一:题意描述
本题大致意思是讲给定一个迷宫(N*M),起点(s)和终点(D),现在要求在给定的步数(T)下从起点走到终点。要求是每一个点只能走一次。
二:题目分析
考虑到数据比较小,我们完全可以利用dfs去暴力出来,但是对于本题我想说一个很特别的技巧就是奇偶剪枝:对于任何一个可能的路径,我们都可以看做是S与D的最短距离
MIN=abs(sx-dx)+abs(dx-dy)+一个偶数。对于我们为何加一个偶数?我们可以这样想:我们既然是加了最短距离,那么当我们从某一个点偏离最短路长的时候必定重新回到偏离的那个点,那么走过的路长一定是偶数。
根据数据的加减性质:偶数+奇数=奇数;偶数+偶数=偶数
所以我们只要判断T和MIN是否同时奇数或者偶数即可,那么这样可以节省很多时间。如果是相同的话,才进行下一步的DFS,在用DFS时同样可以剪枝。
三:AC代码
#include<iostream> #include<cmath> #include<string.h> using namespace std; #define maxn 8 char maps[maxn][maxn]; int T; int dfs(int x,int y,int len) { if(maps[x][y]==‘D‘) { if(len==T) return 1; else if(len!=T) return 0; } else { if(len>=T) return 0; else { if(maps[x][y-1]!=‘X‘) { maps[x][y]=‘X‘; if(dfs(x,y-1,len+1)) return 1; maps[x][y]=‘.‘; } if(maps[x][y+1]!=‘X‘) { maps[x][y]=‘X‘; if(dfs(x,y+1,len+1)) return 1; maps[x][y]=‘.‘; } if(maps[x+1][y]!=‘X‘) { maps[x][y]=‘X‘; if(dfs(x+1,y,len+1)) return 1; maps[x][y]=‘.‘; } if(maps[x-1][y]!=‘X‘) { maps[x][y]=‘X‘; if(dfs(x-1,y,len+1)) return 1; maps[x][y]=‘.‘; } } return 0; } } int main() { int m,n; while(cin>>n>>m>>T) { if(!n&&!m&&!T) break; int step=0; int sx,sy; memset(maps,‘X‘,sizeof(maps)); for(int i=1;i<=n;i++)//初始化矩阵 for(int j=1;j<=m;j++) { cin>>maps[i][j]; if(maps[i][j]==‘S‘) { sx=i;sy=j; } } if((abs(ex - sx) + abs(ey - sy) - T)&1) { cout<<"NO"<<endl; continue; } else { if(dfs(sx,sy,step)) cout<<"YES"<<endl; else cout<<"NO"<<endl; } } return 0; }
四:总结
在以后的题目中一定要注意学会仔细分析问题抓住本质,进而简化分析。
时间: 2024-11-03 01:32:46