hdu-1010

来源:互联网 发布:linux 编译安装 lnmp 编辑:程序博客网 时间:2024/05/17 22:53

奇偶剪枝

假设在某一时刻t,狗狗走到P(xi, yi),又记终点为D(x0, y0)。由P到D的路径可以分解为水平方向和竖直方向(类似于高中物理的位移的正交分解),就是说将P到D的每一条可行路径分解为从直线x = xi到达x = x0,和由直线y = yi到直线y = y0的两个分路径。现在考虑由x = xi到x = x0,当x0 - xi为偶数时,说明x0和xi的奇偶性相同,那么无论通过怎么样的路径由x = xi到x = x0,路径的步数总和必定为偶数(因为每走一步所处方位的x坐标奇偶性就变一次),不然不可能到达x0,,同理,当x0 - xi为奇数时,无论走什么路径,步数总和必为奇数。考查由xi到x0之后,yi到y0的情况不言而知。设由xi到x0的步数为tx,由yi到y0的步数为ty,则tx和ty的奇偶性分别与abs(xi - x0)和abs(yi - y0)的相同,所以总步数tx + ty的奇偶性和abs(xi - x0) + abs(yi - y0)的奇偶性相同。注意,总步数tx + ty实际上就是在P点时剩余的时间t。由此可知,由P到D的总步数,也就是剩余的时间t的奇偶性必定与abs(xi - x0) + abs(yi - y0)的奇偶性相同。不然就无法从P到达D。

#include<stdio.h>#include<math.h>int n,m,time,flag;int from_x,from_y,to_x,to_y;int change[4][2]={-1,0,1,0,0,-1,0,1};char map[10][10];void dfs(int x,int y,int t){int i;if(flag)return ;if(x==to_x && y==to_y && t==time){flag=1;return ;}if((time-t)%2 != (abs(x-to_x)+abs(y-to_y))%2) return ;if(abs(x-to_x)+abs(y-to_y) > time-t)  return;for(i=0;i<4;i++){int xx=x+change[i][0];int yy=y+change[i][1];if(xx<n && xx>=0 && yy<m && yy>=0 && map[xx][yy]!='X'){map[xx][yy]='X';t++;dfs(xx,yy,t);t--;map[xx][yy]='.';}}}int main(){    //freopen("d:\\test.txt","r",stdin);int i,j;while(scanf("%d%d%d",&n,&m,&time)){if(n==0 && n==0 && time==0)break;flag=0;int cnt=0;getchar();for(i=0;i<n;++i)scanf("%s",map[i]);for(i=0;i<n;++i){for(j=0;j<m;++j){if(map[i][j]=='S'){from_x=i;from_y=j;map[i][j]='X';  }else if(map[i][j]=='.')cnt++;else if(map[i][j]=='D'){to_x=i;to_y=j;}}}if(cnt+1<time)  {printf("NO\n");continue;}dfs(from_x,from_y,0);if(flag)printf("YES\n");elseprintf("NO\n");}    return 0;}

  

原创粉丝点击