hdu 1010 dfs+奇偶性剪枝

来源:互联网 发布:猪八戒软件 编辑:程序博客网 时间:2024/05/18 02:17

点击打开链接

奇偶剪枝:
把矩阵标记成如下形式:
0,1,0,1,0
1,0,1,0,1
0,1,0,1,0
1,0,1,0,1
很明显,如果起点在0 而终点在1 那显然 要经过奇数步才能从起点走到终点,依次类推,奇偶相同的偶数步,奇偶不同的奇数步

奇偶剪枝:读入的时候起点记为(Si,Sj) 终点记为(Di,Dj) 判断(Si+Sj) 和 (Di+Dj) 的奇偶性 如果与要求步数奇偶性不同就cut

#include <iostream>#include <algorithm>#include <queue>#include <cstring>#include <cmath>using namespace std;const int M = 11;int n,m,T,ex,ey,vis[M][M],flag;char g[M][M];typedef struct{int x2;int y2;}MOVE;MOVE Move[4]={{-1,0},{1,0},{0,-1},{0,1}};struct Node{int x;int y;int dist;Node(int x1,int y1,int d):x(x1),y(y1),dist(d){}};bool check(int a,int b){if(a>=0&&a<n&&b>=0&&b<m&&g[a][b]!='X'&&!vis[a][b])return true;elsereturn false;}void dfs(int x,int y,int cur){if(cur>T||flag) return; //cutif(cur==T&&x==ex&&y==ey){flag=1;return;} int a,b;for(int i=0;i<4;i++){a=x+Move[i].x2;b=y+Move[i].y2;if(check(a,b)){vis[a][b]=1;dfs(a,b,cur+1);vis[a][b]=0; //回溯 }}}int main(){int i,j,sx,sy,k1,k2;while(cin>>n>>m>>T&&(n+m+T)){flag=0;memset(vis,0,sizeof(vis));for(i=0;i<n;i++){for(j=0;j<m;j++){cin>>g[i][j];if(g[i][j]=='S'){ sx=i; sy=j;}if(g[i][j]=='D'){ex=i;ey=j;}}}k1=(sx+sy)%2; //算出起始点的 奇偶性 k2=(ex+ey)%2; //0->1 奇数步   0->0偶数步   证明 0->0 移动相邻的0:2步 0反复移动到相邻的0 2n步 if(((k1+k2)%2==0&&T%2)||((k1+k2)%2&&T%2==0))//0->1   移动到相邻的1 1步  1反复移动到相邻的1 2n步 所以2n+1步 { flag=0;}else{vis[sx][sy]=1;dfs(sx,sy,0);}if(flag){cout<<"YES"<<endl;}else{cout<<"NO"<<endl;}}return 0;}


 


 

0 0
原创粉丝点击