题目大意:给一个地图,在规定时间内刚好找到出口,不早也不能晚
解决: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;
}
浙公网安备 33010602011771号