- 0 1 0 1 0 1
- 1 0 1 0 1 0
- 0 1 0 1 0 1
- 1 0 1 0 1 0
- 0 1 0 1 0 1
- 从 0->1 需要奇数步
- 从 1->0 需要偶数步
- 那么设所在位置 (si,sj) 与 目标位置 (di,dj)
- 如果abs(si-sj)+abs(di-dj)为偶数,则说明 abs(si-sj) 和 abs(di-dj)的奇偶性相同,需要走偶数步
- 如果abs(si-sj)+abs(di-d
- 奇偶剪枝:把map看作
- j)为奇数,那么说明 abs(si-sj) 和 abs(di-dj)的奇偶性不同,需要走奇数步
- 理解为 abs(si-sj)+abs(di-dj) 的奇偶性就确定了所需要的步数的奇偶性!!
- 因此 temp=t-cnt-abs(sj-dj)-abs(si-di) 必然为偶数!
- 而 (t-cnt)表示剩下还需要走的步数,由于题目要求要在 t时 恰好到达,那么 (t-cnt) 与 abs(si-sj)+abs(di-dj) 的奇偶性必须相同
题意为:http://acm.hdu.edu.cn/showproblem.php?pid=1010
解题注意
1:用 dfs 不断的搜索 看是否存在路径 刚好为长度为 t 有输出yes 没有输出 No
2:主要考察点事 dnf 的剪枝
3:注意最大优化的剪枝
刚开始只有一个地方没优化就 LimitedTime 了
代码如下:
#include<iostream>
#include<math.h>
#include<queue>
#define Max 8
using namespace std;
char map[Max][Max];
int visit[Max][Max];
int n,m,t,ex,ey;
int temp;
int d[4][2]={{-1,0},{0,1},{1,0},{0,-1}};// 方向
bool flage = false;
bool f = false;
void dfs(int n,int m,int sx,int sy ,int k){
f= false;
int temp = t-k-abs(sx-ex)-abs(sy-ey);
if( k>t && temp%2!=0 || temp<0 ){// 奇偶剪枝
return;
}
if( sx ==ex && sy == ey){// 找到D
if(k==t){
flage = true;
return;
}
}
if(flage){
return;
}
int i=0;
for(i=0;i<4;i++){
int nx,ny;
nx=sx+d[i][0];ny=sy+d[i][1];
if( nx<1 || nx>n || ny<1 || ny>m || map[nx][ny] =='X' || visit[nx][ny]==1){
continue;
}
visit[nx][ny]=1;
dfs(n,m,nx,ny ,k+1);
visit[nx][ny]=0;
}
}
void main(){
int n,m,i=0,j=0,sx=0,sy=0,wall=0;
while(cin>>n>>m>>t){
wall = 0;
if( n==0 && m==0 && t==0){
break;
}
flage = false;
for( i=1;i<=n;i++){
for(j=1;j<=m;j++){
cin>>map[i][j];
if( map[i][j]=='D'){
ex = i; ey = j;
}
if( map[i][j] =='S'){
sx = i;sy=j;
}
if( map[i][j]=='X'){
wall++;
}
}
}
memset(visit,0,sizeof(visit));
visit[sx][sy]=1;
if( n*m - wall < t){
cout<<"NO"<<endl;
continue;
}
if((t-abs(sx-ex)-abs(sy-ey))%2==0){
dfs(n,m,sx,sy,0);
}
if( flage){
cout<<"YES"<<endl;
}else{
cout<<"NO"<<endl;
}
}
}
做题一定要考虑细节啊……哎。我真失败,总是在细小的地方卡壳好久好久。