int tt = t - tx - (abs(x-ex)+abs(y-ey));
其中t - tx味剩余的步数或者说时间,另其为T
(abs(x-ex)+abs(y-ey))为剩余步数,另其为S如果走偶数步要求的时间是奇数,或者走奇数步要求的时间是偶数,都明显不可行
而轻易得出奇数-偶数 = 奇数,反之亦然
而奇数-奇数= 偶数,偶数-偶数=偶数
所以tt必须为偶
#include <bits/stdc++.h>
using namespace std;
int n,m,t;
int ex,ey;
bool flag;
char a[10][10];
bool vis[10][10];
int dir[4][2]= {0,1,0,-1,1,0,-1,0};
bool OK(int x,int y) {
if(x < 0||x >= n||y < 0||y >= m)
return false;
return true;
}
int abs(int x) {
return x<0?-x:x;
}
void DFS(int x,int y,int tx) {//tx:当前时间
if(x == ex && y == ey && tx == t) {
flag = true;
return;
}
if(flag)
return ;
int tt = t - tx - (abs(x-ex)+abs(y-ey));
if(tt < 0 || tt&1)//important,看剩下的时间能能否到达终点,tem&1则是判断其是否偶数,根据奇偶性剪枝可得tem必须是偶数,是奇数则不行,此处不剪枝,超时
return;
for(int i = 0; i < 4; i++) {//
int xx = x + dir[i][0];
int yy = y + dir[i][1];
if(OK(xx,yy) && !vis[xx][yy] &&a[xx][yy] != 'X') {
vis[xx][yy] = true;
DFS(xx, yy, tx+1);
vis[xx][yy] = false;
}
}
}
int main() {
//freopen("data.in", "r", stdin);
while(cin>>n>>m>>t,n,m,t) {
for(int i = 0; i < n; i++)
cin>>a[i];
int x = 0;
int sx,sy;
for(int i=0; i<n; i++) {
for(int j = 0; j < m; j++) {
if(a[i][j] == 'S')
sx=i,sy=j;//起点
else if(a[i][j] == 'X')
x++;//墙
else if(a[i][j] == 'D')
ex=i,ey=j;//终点
}
}
if(m*n-x <= t) {//t是代表要走的步数,步数加墙数必须小于总格子数的,因为所有格子中还包括了S和D,这是剪枝
cout<<"NO"<<endl;
continue;
}
memset(vis,false,sizeof(vis));
vis[sx][sy] = true;
flag = false;
DFS(sx,sy,0);
if(flag)
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
}
return 0;
}