[hdu1010]Tempter of the Bone 题解

mac2026-10-05  0

题目大意:

给定一幅地图,“.”是可以走的空格子,“S”是起点,“D”是终点,“X”是不可以走的墙。问有无这样的一条路,使得从S出发到D恰好在第t秒。并且,不能停留在任何位置。

分析:

因为数据范围很小,所以我使用了爆搜,但是虽然没有TLE,但是却WA了。样例过了,调试感觉也没问题,所以为什么???

#pragma GCC optimize(2) #include<cstdio> #include<cstring> #include<algorithm> using namespace std; int n,m,t,sx,sy,ex,ey; char c[10][10]; bool f[10][10],flag; inline void dfs(int x,int y,int tm){ if(x<1||x>n||y<1||y>m||!f[x][y])return; if(tm>t)return; if(x==ex&&y==ey){ if(tm==t)flag=true; return; }else{ f[x][y]=false; dfs(x-1,y,tm+1); dfs(x,y-1,tm+1); dfs(x+1,y,tm+1); dfs(x,y+1,tm+1); }return; } int main(){ while(scanf("%d%d%d",&n,&m,&t)){ flag=false; memset(f,false,sizeof(f)); if(n==0&&m==0&&t==0)break; for(int i=1;i<=n;++i){ scanf("%s",c[i]+1); for(int j=1;j<=m;++j){ if(c[i][j]=='.')f[i][j]=true; else if(c[i][j]=='S')sx=i,sy=j,f[i][j]=true; else if(c[i][j]=='D')ex=i,ey=j,f[i][j]=true; else f[i][j]=false; } } for(int i=1;i<=n;++i){ for(int j=1;j<=m;++j)printf("%c",c[i][j]); printf("\n"); } dfs(sx,sy,0); if(flag)printf("YES\n"); else printf("NO\n"); } return 0; }

感谢 某巨佬 \color{red}\text{某巨佬} 某巨佬帮忙调试,对搜索稍微改了改就切了这题。虽然跑了374ms,但是问题不大~

#pragma GCC optimize(2) #include<cstdio> #include<cstring> #include<algorithm> using namespace std; int n,m,t,sx,sy,ex,ey; char c[10][10]; bool f[10][10],flag; inline void dfs(int x,int y,int tm){//爆搜 if(flag)return;//找到了就return可以快不少 if(x==ex&&y==ey){ if(tm==t)flag=true; return; }f[x][y]=0; if(x-1>=1&&f[x-1][y]){ f[x-1][y]=0; dfs(x-1,y,tm+1); f[x-1][y]=1; } if(y-1>=1&&f[x][y-1]){ f[x][y-1]=0; dfs(x,y-1,tm+1); f[x][y-1]=1; } if(x+1<=n&&f[x+1][y]){ f[x+1][y]=0; dfs(x+1,y,tm+1); f[x+1][y]=1; } if(y+1<=m&&f[x][y+1]){ f[x][y+1]=0; dfs(x,y+1,tm+1); f[x][y+1]=1; } return; } int main(){ while(scanf("%d%d%d",&n,&m,&t)){ if(n==0&&m==0&&t==0)break; flag=false; memset(f,false,sizeof(f)); for(int i=1;i<=n;++i){ scanf("%s",c[i]+1); for(int j=1;j<=m;++j){ if(c[i][j]=='.')f[i][j]=true; if(c[i][j]=='S')sx=i,sy=j,f[i][j]=true; if(c[i][j]=='D')ex=i,ey=j,f[i][j]=true; } } f[sx][sy]=0;//标记起点 dfs(sx,sy,0); if(flag)printf("YES\n"); else printf("NO\n"); } return 0; }

关于奇偶剪枝:

在爆搜的“if(flag)return;”下一行加上:

if((t-tm)<mhd||((t-tm-mhd)&1))return;

其中——

#define mhd abs(ex-x)+abs(ey-y)

加上曼哈顿距离的奇偶剪枝之后又快了100ms左右,挺好的。 因为比较简单我就不废话了。


不知道之前为什么WA了,也许是没标记初始位置和搜索时没回溯吧。 网上还有不少高级的剪枝操作,不过我觉得水过这题就行了,想进一步提升自己的读者请自行查找吧~

F I N FIN FIN

最新回复(0)