hdu1010---Tempter of the Bone解題報告(DFS + 剪枝)
阿新 • • 發佈:2018-11-05
Tempter of the Bone題目連結
'X': a block of wall, which the doggie cannot enter;
'S': the start point of the doggie;
'D': the Door; or
'.': an empty block.
輸入n,m,t
n * m的地圖
題意:從s出發,初始時間為0, 只有在第t秒,D會開門,判斷能否走出迷宮。
思路:暴搜,沒有剪枝預判的話會超時。
剪枝:
假設sx,sy為起點,則ex,ey為終點,任意點
如果
1.abs(sx - ex) + abs(sy - ey) > t
2.abs(sx - ex) + abs(sy - ey) % 2 != t % 2(即到達D的時候時間不同步)
以上任意情況則一定不能走出去了
每次在迷宮移動的時候,同理,對此剪枝。
#include<iostream> #include<sstream> #include<cstdlib> #include<cmath> #include<algorithm> #include<cstring> #include<cstdio> #include<map> #include<vector> #include<stack> #include<queue> #include<set> #include<list> #define mod 998244353 #define INF 0x3f3f3f3f #define Min 0xc0c0c0c0 #define mst(a) memset(a,0,sizeof(a)) #define f(i,a,b) for(int i = a; i < b; i++) using namespace std; typedef long long ll; const int MAX_N = 1e6 + 5; int n, m, t; int sx, sy, ex, ey; char maps[10][10]; bool vis[10][10]; bool flag; const int fx[4] = {1, 0, -1, 0}; const int fy[4] = {0, 1, 0, -1}; void dfs(int x, int y, int sum){ if(maps[x][y] == 'D' && sum == t){ flag = true; return ; } if(flag){ return ; } for(int i = 0; i < 4; i++){ int nx = x + fx[i], ny = y + fy[i]; int tmp = abs(nx - ex) + abs(ny - ey); //剪枝 if(nx >= 1 && nx <= n && ny >= 1 && ny <= m && maps[nx][ny] != 'X' && (sum + tmp + 1 <= t) && (sum + tmp + 1) % 2 == (t % 2) && !vis[nx][ny]){ vis[nx][ny] = 1; dfs(nx, ny, sum + 1); vis[nx][ny] = 0; } } } int main(){ ios::sync_with_stdio(false); //freopen("c1.txt", "w", stdin); //freopen("c2.txt", "r", stdout); int cas = 1; while(cin>>n>>m>>t){ if(n == 0 && m == 0 && t == 0){ break; } 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(maps[i][j] == 'D'){ ex = i, ey = j; } } } mst(vis); flag = false; int tmp = abs(ex - sx) + abs(ey - sy); if(tmp > t || tmp % 2 != t % 2){ //預判 cout<<"NO"<<endl; continue; } vis[sx][sy] = 1; dfs(sx, sy, 0); if(flag){ cout<<"YES"<<endl; } else { cout<<"NO"<<endl; } } //fclose(stdin); //fclose(stdout); return 0; }