题目大意:给一个地图,在规定时间内刚好找到出口,不早也不能晚
解决:dfs+剪枝
#include <iostream> #include <cstdio> #include <cmath> using namespace std; #define s scanf #define p printf #define d "%d" char map[8][8]; int n,m,step; bool escape; int sx,sy,ex,ey; int dx[]={1,-1,0,0}; int dy[]={0,0,1,-1}; void dfs(int x,int y,int current_step) { if(escape)return ; int cnt=abs(x-ex)+abs(y-ey); //至少需要的步子数 if(current_step+cnt>step)return; //若到达终点的最小步子数也比要求的步子数大 ,肯定不行了,死定了 if((step-current_step)%2 != cnt%2)return;//奇偶性剪枝 for(int i=0;i<4;i++) { int nxtx=x+dx[i]; int nxty=y+dy[i]; if(nxtx<m && nxtx>=0 && nxty<n && nxty>=0) { if(map[nxtx][nxty]=='D' && current_step+1==step){escape=true;return ;} if(map[nxtx][nxty]=='.') { map[nxtx][nxty]='X'; dfs(nxtx,nxty,current_step+1); map[nxtx][nxty]='.'; } } } } int main() { while(s(d d d,&m,&n,&step),m||n||step) { escape=false; int i,j; //事实证明,先创建好地图,在一个一个找,比输入一个找一个要快一些 for(i=0;i<m;i++) s("%s",map[i]); for(i=0;i<m;i++) for(j=0;j<n;j++) if(map[i][j]=='S'){sx=i; sy=j; } else if(map[i][j]=='D'){ex=i;ey=j;} dfs(sx,sy,0); if(escape)puts("YES"); else puts("NO"); } system("pause"); return 0; }
以上为void 型dfs,一下为有返回值dfs
#include <iostream> #include <cstdio> #include <cmath> using namespace std; #define s scanf #define d "%d" char map[8][8]; int n,m,step; int sx,sy,ex,ey; int dx[]={1,-1,0,0}; int dy[]={0,0,1,-1}; bool dfs(int x,int y,int current_step) { int cnt=abs(x-ex)+abs(y-ey); if(current_step+cnt>step)return false; if(abs(step-current_step)%2 != cnt%2)return false; for(int i=0;i<4;i++) { int nxtx=x+dx[i]; int nxty=y+dy[i]; if(nxtx<m && nxtx>=0 && nxty<n && nxty>=0) { //若从x,y能扩展出新的点,只要这个点在map中,有两种可能 //第一种是为'D',而且满足结束条件,就返回true就行了,第二种是 //有路可走,map[nxtx][nxty]='.',再尝试下一步 if(map[nxtx][nxty]=='D' && current_step+1==step)return true; if(map[nxtx][nxty]=='.') { map[nxtx][nxty]='X'; //一下这个如果不返回的话,就要超时了如果写成 //return dfs(nxtx,nxty,current_steo+1);就错了 //因为这句话是说若下一个为真返回真,下一个为假,返回假,但是实际上 //只能返回真的情况,为假的话,我们还有for循环可以尝试下一个为真不是 if(dfs(nxtx,nxty,current_step+1))return true; map[nxtx][nxty]='.'; } } } return false; } int main() { while(s(d d d,&m,&n,&step),m||n||step) { int i,j; for(i=0;i<m;i++) { //这个地方要用scanf,不能用gets,因为这个gets,错了无数次 s("%s",map[i]); for(j=0;j<n;j++) if(map[i][j]=='S'){sx=i; sy=j; } else if(map[i][j]=='D'){ex=i;ey=j;} } if(dfs(sx,sy,0))puts("YES"); else puts("NO"); } system("pause"); return 0; }