题目在这
逃跑的拉尔夫
题意:跟据每一步指定的方向,可移动到方向上的第一个障碍物之前的任意点上(但至少要移动一格,不能静止),求完成所有步骤后,其可能达到的位置。
题析:一道比较普通的搜索题,题被定义在二维的地图上,求进行过指定操作后其可能所在的位置。很明显,这些位置都是需要我们一步步枚举出来的。所以我们可用DFS来结局这道问题,对每一个可能状态的予以拓展,当然网上还有用BFS做的,但我估计二者的原理都大同小异,但既然是一步步枚举,或许DFS更好直接理解。
细节:当然,这道题还不只那么简单,这里有一个必须要明白的地方:当使用搜索时,对于同一步的同种状态,我们可能会多次拓
展,而且拓展后又会形成连锁反应,导致后一步的状态被多次拓展,一步步的,最终你的DFS就会以TLE告终(这就是我血的教训啊)。
但想要解决这个问题,也很简单,我们只需要定一个bool数组,用来判断这个状态是否出现过即可,而且,我们会发现,假如该数组被
定义为vis[50][50][1000],那我们最大访问的状态也就只可能有50*50*1000=2500000个罢了,搜索足以解决问题(从这里看,这道题的DFS与BFS的做法极其相识)。
代码:用DFS做的,代码超具个人风格,凑活凑活看吧...
#include<cstdio>
#include<cstring>
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