您的位置:首页 > 其它

zoj(2110)Tempter of the Bone(DFS+奇偶剪枝)

2014-03-14 17:21 405 查看
剪枝很重要,可走的格数小于时间则减去,然后就是奇偶性剪枝

可以把map看成这样:

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 的格子

即:

 0 ->1或1->0 必然是奇数步

 0->0 走1->1 必然是偶数步

所以当遇到从 0 走向 0 但是要求时间是奇数的,或者, 从 1 走向 0 但是要求时间是偶数的 都可以直接判断不可达!

#include <iostream>
#include <stdio.h>
#include <string>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <fstream>
#include <vector>
#include <map>
#include <queue>
#include <stack>
#include <math.h>
#include <stdlib.h>
using namespace std ;
const int maxn = 55;
char grid[maxn][maxn];
int vis[maxn][maxn];
int n,m,s,flag;
int sx,sy,dx,dy;
int dir[4][2] = {1,0,0,1,-1,0,0,-1};
int cango(int x,int y){
return x>=1&&x<=n&&y>=1&&y<=m;
}
void dfs(int x,int y,int step){
if(flag)return ;//也是一种剪枝吧,不加上这句险些TLE
if(step == s){
if(x == dx && y == dy)
flag = 1;
return;
}
int temp = s - step - abs(dy - y)-abs(dx - x);
if(temp<0||temp&1)//奇偶剪枝
return;
for(int i = 0;i < 4;i++){
int xx = x + dir[i][0];
int yy = y + dir[i][1];
if(cango(xx,yy)&&!vis[xx][yy]&&grid[xx][yy] != 'X'){
vis[xx][yy] = 1;
dfs(xx,yy,step+1);
vis[xx][yy] = 0;
}
}
}
int main(){
while(scanf("%d%d%d",&n,&m,&s)&&(n+m+s)){
int wall = 0;
for(int i = 1;i <= n;i++)
scanf("%s",grid[i]+1);
for(int i = 1;i <= n;i++)
for(int j = 1;j <= m;j++){
if(grid[i][j] == 'S'){
sx = i;
sy = j;
}
if(grid[i][j] == 'D'){
dx = i;
dy = j;
}
if(grid[i][j] == 'X') wall++;
}
if(n*m - wall <= s){//可能性剪枝
printf("NO\n");
continue;
}
flag = 0;
memset(vis,0,sizeof(vis));
vis[sx][sy] = 1;
dfs(sx,sy,0);
if(flag)
printf("YES\n");
else
printf("NO\n");
//for(int i = 1;i <= n;i++)
//  printf("%s\n",grid[i]+1);
}
return 0 ;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: