1018 Tempter of the Bone
题意:一个n*m的矩阵中,“S”代表人,“X”为墙,“.”为路,“D”为门,在第T秒时门打开,那么“S”是否能够在第T秒到达门中。
思路:深搜,对于满足要求的点,进一步搜索,直到满足题意。
感想:看到题目第一眼,想法有些过于简单了,网上搜了一下,找到了奇偶剪枝,其中t-cnt为剩余的步数或者说时间,令其为T,s1+s2为剩余步数,令其为S,如果走偶数步要求的时间是奇数,或者走奇数步要求的时间是偶数,都明显不可行,而轻易得出奇数-偶数 = 奇数,反之亦然,而奇数-奇数= 偶数,偶数-偶数=偶数,所以tem必须为偶数。
#include<iostream>
#include<string.h>
#include<math.h>
#include<stdio.h>
using namespace std;
char map[10][10];
int n,m,t,di,dj,wall,flag;
int dir[4][2]={{-1,0},{0,1},{1,0},{0,-1}};
void dfs(int si,int sj,int cnt){
int i,tmp;
if(si<1||si>n||sj<1||sj>m)
return ;
if(cnt==t&&si==di&&sj==dj)
flag=1;
if(flag)
return ;
int s1=si-di;
int s2=sj-dj;
if(s1<0) s1=-s1;
if(s2<0) s2=-s2;
tmp=t-cnt-s1-s2;
if(tmp<0||tmp&1)
return ;
for(i=0;i<4;i++){
if(map[si+dir[i][0]][sj+dir[i][1]]!='X'){
map[si+dir[i][0]][sj+dir[i][1]]='X';
dfs(si+dir[i][0],sj+dir[i][1],cnt+1);
map[si+dir[i][0]][sj+dir[i][1]]='.';
}
}
return ;
}
int main(){
int i,j,sum,si,sj;
while(cin>>n>>m>>t){
wall=0;
if(!n&&!m&&!t) break;
for(i=1;i<=n;i++){
for(j=1;j<=m;j++){
cin>>map[i][j];
if(map[i][j]=='S'){
si=i;
sj=j;
}
else if(map[i][j]=='D'){
di=i;
dj=j;
}
else if(map[i][j]=='X')
wall++;
}
getchar();
}
if(n*m-wall<=t){
printf("NO\n");
continue;
}
flag=0;
map[si][sj]='X';
dfs(si,sj,0);
if(flag)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}