小记:最开始以为是T时间内,用bfs WA了,后来知道是刚好T时间,然后就用dfs, 相当于暴力了,然后简单的dfs提交TLE, 必须剪枝。
首先判最少需要的时间是否有,没有就不用继续了,而如果有,那么因为我们是要花掉T时间刚好到达,那么我们先保证能走到终点的时间,然后在路上花掉多余的时间
此时,我们必须保证我们多出来的时间必须是偶数,这样我们才能回来,否则就回不来了,回不来就意味着到达不了终点,一来一回两倍距离,所以必须是偶数。
就加上这个剪枝就A了
代码:
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <map>
#include <set>
#include <vector>
#include <stack>
#include <queue>
#include <algorithm>
using namespace std;
#define mst(a,b) memset(a,b,sizeof(a))
#define eps 10e-10
#define PI acos(-1.0)//3.14159265
const int MAX_ = 1010;
const int N = 100010;
const int INF = 0x7fffffff;
int mp[MAX_][MAX_];
int dir[4][2] = {{0,-1},{-1,0},{0,1},{1,0}};
int n,m, T, ex, ey;
int dfs(int x,int y,int step){
if(mp[y][x] == -1 && step == T){return 1;}
if(step >= T){return 0;}
int tmp = abs(x-ey) + abs(y-ex);
if((tmp > T-step )|| ((T-step-tmp)%2))return 0;
for(int i = 0; i < 4; ++i){
int nextx, nexty;
nextx = x + dir[i][0];
nexty = y + dir[i][1];
if((nextx > 0 && nextx <= m) && (nexty > 0 && nexty <= n) && mp[nexty][nextx] != 1){
int tmp = mp[y][x];
mp[y][x] = 1;
int flag = dfs(nextx,nexty,step+1);
if(flag)return 1;
mp[y][x] = tmp;
}
}
return 0;
}
/*
7 7 48
S......
.......
.......
.......
.......
.......
......D
*/
int main(){
int ans, sx,sy, cnt;
char c;
//freopen("E://1.txt","w",stdout);
while(scanf("%d%d%d",&n,&m,&T), n||m||T){
getchar();
cnt = 1;
for(int i = 1; i <= n; ++i){
for(int j = 1; j <= m; ++j){
scanf("%c",&c);
if(c == 'S'){
sx = i, sy = j;
mp[i][j] = 1;
}
else if(c == '.'){
mp[i][j] = 0;
}
else if(c == 'X'){
cnt++;
mp[i][j] = 1;
}
else if(c == 'D'){
ex = i, ey = j;
mp[i][j] = -1;
}
}
getchar();
}
if((abs(ex-sx) + abs(ey-sy) > T) || (n*m - cnt < T)){
ans = 0;
}
else ans = dfs(sy,sx,0);
if(ans)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}