HDU 1010 Tempter of the Bone (DFS+剪枝)

题意:给出一张图,判断在给定的时间(正好,不是时间内)走到另一个点

分析:dfs,两个点之间最小的距离为麦哈顿距离(详见百度百科)我们可以发现,我们的步数不是等于最短距离就是比最短距离多一个偶数,所以可以利用这点进行剪枝

代码:

#include <map>
#include <set>
#include <cmath>
#include <queue>
#include <deque>
#include <stack>
#include <cstdio>
#include <vector>
#include <iomanip>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <iostream>
#include <algorithm>
#define ll long long
#define mod 10000000007
#define mem(a) memset(a,0,sizeof(a))

using namespace std;

typedef pair <int,int> pii;
const int maxn = 10+5 , inf = 0x3f3f3f3f;

char G[maxn][maxn];
bool vis[maxn][maxn];
int n,m,t,sx,sy,ex,ey;

const int dx[] = {1,-1,0,0};
const int dy[] = {0,0,-1,1};

bool can(int x,int y){
    if(1<=x&&x<=n&&1<=y&&y<=m&&G[x][y]!='X'&&!vis[x][y])
        return true;
    return false;
}

bool dfs(int x,int y,int d){
    //cout<<"x = "<<x<<" y = "<<y<<endl;
    if(G[x][y]=='D'&&d==t) return true;
    int dis = t-d-abs(x-ex)-abs(y-ey);
    if(dis<0||dis&1) return false;
    if(d>=t) return false;
    for(int i=0;i<4;i++){
        int nx = x+dx[i];
        int ny = y+dy[i];
        if(can(nx,ny)){
            vis[nx][ny] = 1;
            if(dfs(nx,ny,d+1)) return true;
            vis[nx][ny] = 0;
        }
    }
    return false;
}

int main(){
    //freopen("in.txt","r",stdin);
   // freopen("out.txt","w",stdout);
    while(scanf("%d%d%d",&n,&m,&t)!=EOF&&n&&m){
        mem(vis);
        mem(G);
        for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++){
            scanf(" %c",&G[i][j]);
            if(G[i][j]=='S'){
                sx = i;
                sy = j;
            }
            if(G[i][j]=='D'){
                ex = i;
                ey = j;
            }
        }
        vis[sx][sy] = true;
        if(dfs(sx,sy,0)) cout<<"YES"<<endl;
        else cout<<"NO"<<endl;
    }
}

猜你喜欢

转载自blog.csdn.net/Insist_77/article/details/81481357
今日推荐