深度优先搜索+回朔+奇偶剪枝
- 题目描述
http://acm.hdu.edu.cn/showproblem.php?pid=1010 - 题解
基本算法思路就是深搜,不过会超时,因此得奇数偶数剪枝,就可以ac了。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
using namespace std;
int N,M,T;
char ch[10];
int maze[10][10];
int sx=0,sy=0,ex=0,ey=0;
int ok=false;
int da[4]={1,0,-1,0};
int db[4]={0,1,0,-1};
bool visit[10][10];
int count_=0;
void dfs(int a,int b){
if(count_==T&&maze[a][b]==2){
ok=true;
return;
}
if(count_>T||ok) return;
if((T-count_-abs(a-ex)-abs(b-ey))%2==1) return;
for(int i=0;i<4;i++){
int x=a+da[i];
int y=b+db[i];
if(maze[x][y]!=-1&&visit[x][y]==0){
visit[x][y]=1;
count_++;
dfs(x,y);
visit[x][y]=0;
count_--;
if(ok) return;
}
}
}
int main(){
while(cin>>N>>M>>T){
if(N==0&&M==0&&T==0) break;
memset(maze,-1,sizeof(maze));
memset(visit,0,sizeof(visit));
int w=0;
for(int i=1;i<=N;i++){
scanf("%s",ch);
for(int j=1;j<=M;j++){
switch (ch[j-1]){
case 'S': maze[i][j]=1;sx=i,sy=j; break;
case '.': maze[i][j]=0;break;
case 'D': maze[i][j]=2;ex=i,ey=j;break;
case 'X':maze[i][j]=-1;w++;break;
default: maze[i][j]=-1; break;
}
}
}
ok= false;
if(N*M-w<T&&abs(sx-ex)+abs(sy-ey)>T||(T-abs(sx-ex)-abs(sy-ey))%2==1){
printf("NO\n");
continue;
}
count_=0;
visit[sx][sy]=1;
dfs(sx,sy);
if(ok) printf("YES\n");
else printf("NO\n");
}
return 0;
}