Codevs 1026 逃跑的拉尔夫 解题报告

题目在这

逃跑的拉尔夫


题意跟据每一步指定的方向,可移动到方向上的第一个障碍物之前的任意点上(但至少要移动一格,不能静止)求完成所有步骤后,其可能达到的位置。


题析:一道比较普通的搜索题,题被定义在二维的地图上,求进行过指定操作后其可能所在的位置。很明显,这些位置都是需要我们一步步枚举出来的。所以我们可用DFS来结局这道问题,对每一个可能状态的予以拓展,当然网上还有用BFS做的,但我估计二者的原理都大同小异,但既然是一步步枚举,或许DFS更好直接理解。


细节当然,这道题还不只那么简单,这里有一个必须要明白的地方:当使用搜索时,对于同一步的同种状态,我们可能会多次拓

,而且拓展后又会形成连锁反应,导致后一步的状态被多次拓展,一步步的,最终你的DFS就会以TLE告终(这就是我血的教训啊)

但想要解决这个问题,也很简单,我们只需要定一个bool数组,用来判断这个状态是否出现过即可,而且,我们会发现,假如该数组被

定义为vis[50][50][1000],那我们最大访问的状态也就只可能有50*50*1000=2500000个罢了,搜索足以解决问题(从这里看,这道题的DFS与BFS的做法极其相识)


代码:用DFS做的,代码超具个人风格,凑活凑活看吧...


#include
#include
using namespace std;

const int SIZE=50+5;
const int N=1000+5;

bool mp[SIZE][SIZE];
bool ed[SIZE][SIZE];
bool vis[SIZE][SIZE][N];
char face[N][10];

int r,c;
int n;
int sh,sl;

void Dfs(int h,int l,int arg){
    
    if ( arg>n ) ed[h][l]=true;
    
    if ( vis[h][l][arg] ) return;
    
    vis[h][l][arg]=true;
    
    if ( face[arg][0]=='N' ){
    
        for(int i=h-1;i>=0;i--)
          if ( mp[i][l]==false ) break;
            else Dfs(i,l,arg+1);
    
    }        
    
    if ( face[arg][0]=='S' ){
    
        for(int i=h+1;i<=r;i++)
          if ( mp[i][l]==false ) break;
            else Dfs(i,l,arg+1);
    
    }        
    
    if ( face[arg][0]=='W' ){
    
        for(int i=l-1;i>=0;i--)
          if ( mp[h][i]==false ) break;
            else Dfs(h,i,arg+1);
    
    }      

    if ( face[arg][0]=='E' ){
    
        for(int i=l+1;i<=c;i++)
          if ( mp[h][i]==false ) break;
            else Dfs(h,i,arg+1);
    
    }  

  return;

}

int main(){

    scanf("%d %d",&r,&c);
    
    for(int i=1;i<=r;i++){
      
          char in[SIZE];
          
          scanf("%s",in);
          
          for(int j=1;j<=c;j++)
            if ( in[j-1]=='.' ) mp[i][j]=true;
              else if ( in[j-1]=='X' ) mp[i][j]=false;
                else if ( in[j-1]=='*' ) mp[i][j]=true,sh=i,sl=j;
         
               
    }      
    
    scanf("%d",&n);
    
    for(int i=1;i<=n;i++) scanf("%s",&face[i][0]);
    
    Dfs(sh,sl,1); 
    
    for(int i=1;i<=r;i++){
      
      for(int j=1;j<=c;j++)
        if ( mp[i][j]==false ) printf("X");
          else if ( mp[i][j] && ed[i][j] ) printf("*");     
            else printf(".");
      
      printf("\n");
                      
    } 
  
//  while(1);
  
  return 0;    
    
}

我就是那个搭上一天还是只能做3道题的人!

orz


2017.1.31


你可能感兴趣的:(Codevs)