题意:给出一张图,判断在给定的时间(正好,不是时间内)走到另一个点
分析: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;
}
}