1. 程式人生 > >hdu1010---Tempter of the Bone解題報告(DFS + 剪枝)

hdu1010---Tempter of the Bone解題報告(DFS + 剪枝)

                                     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;
}