题意:一只狗(柴犬,看到一块骨头,迷失在了maze里,S是起点,D是终点,问你能不能在时间T时从起点到达终点.
这题有个小trick: 奇偶剪枝+普通剪枝
解释一下:
普通剪枝:从S到D要走的步数是k=abs(x1-x2)+abs(y1-y2);那么如果k>=T,永远不可能到达;
奇偶剪枝:
首先,分析一下两个坐标的奇偶性与K的关系
当坐标是奇数的时候: x,y一定是一奇一偶的关系(妈哒输入法好难用
当坐标是偶数的时候:x,y一定全为奇数或者全为偶数.
当两个坐标奇偶性一样的时候:
1.全为奇数,那么K=(奇数-奇数)+(偶数-偶数)或者K=(奇数-偶数)+(偶数-奇数);
众所周知:
奇数+/-奇数=偶数;
偶数+/-偶数=偶数;
奇数+/-偶数=奇数;
妈哒这些数数好复杂!
所以当两个坐标全为奇数时K=(奇数-奇数)+(偶数-偶数)或者K=(奇数-偶数)+(偶数-奇数)=偶数+偶数或者K=奇数+奇数;
总而言之的言之:当两个坐标都是奇时,K=偶数;
2.全为偶数是
K=(奇数-奇数)+(奇数-奇数)=偶数;
或者K=(偶数-偶数)+(偶数-偶数)=偶数;
或者K=(奇数-偶数)+(奇数-偶数)=偶数;
卧槽怎么写出原理这么多,快出来个人告诉我简便证法!!!
反正总而言之!!!
上面的都是草泥马写的!!不用看了!!
当两个坐标奇偶性相同时,需要走的步数一定绝壁是:偶数!
当两个坐标的奇偶性不一样的时候:
这就简单了:其中一个一定是一奇一偶;另一个要么全是奇,要么全是偶;
所以K=(奇数-奇数)+(奇数-偶数)或者K=(奇数-偶数)+(偶数-偶数)
当两个坐标奇偶性不相等时,需要走的步数K都等于奇数!
好了好了,累死我了;
说了这么多,其实就是一个奇偶剪枝的结论:
当两个坐标奇偶性相等时,需要走偶数步!
当两个坐标奇偶性不相等时,需要走奇数步!
翻译成C语言就是:
if((x1+y1+x2+y2)%2==0)
{
两个坐标奇偶性相等;
}
if((x1+y1+x2+y2)%2==1)
{
两个坐标奇偶性不相等;
}
要想奇偶性相等的时候T是偶数;
奇偶性不想等的时候T是奇数;
只需要把上面这么一大坨的东西变成一句话(哭
if((x1+y1+x2+y2+T)%2==0)
AC代码:
#include <stdio.h> #include <string.h> #include <math.h> #include <iostream> #include <algorithm> using namespace std; const int dx[4]= {1,0,-1,0}; const int dy[4]= {0,1,0,-1}; char s[56][56]; int n,m,t,xxx,yyy; int vis[105][56]; int dfs(int x,int y,int cnt) { int k; for(int i=0; i<4; i++) { int x1=x+dx[i]; int y1=y+dy[i]; if(x1>=0&&x1<n&&y1>=0&&y1<m&&vis[x1][y1]==0) { if(s[x1][y1]=='.')//如果遇到"."继续往下搜 { vis[x1][y1]=1; k=dfs(x1,y1,cnt+1); if(k==1) { return 1; } vis[x1][y1]=0; } else if(s[x1][y1]=='D') { if(cnt+1==t) { return 1; } else if(cnt+1>t) { return 0; } } } } return 0; } int main() { int xx,yy; while(~scanf("%d%d%d",&n,&m,&t)) { memset(vis,0,sizeof(vis)); if(n==0&&m==0&&t==0) { break; } for(int i=0; i<n; i++) { scanf("%s",s[i]); } int ans=0; for(int i=0; i<n; i++) { for(int j=0; j<m; j++) { if(s[i][j]=='S') { xx=i; yy=j; } else if(s[i][j]=='D') { xxx=i; yyy=j; } } } if(abs(xx-xxx)+abs(yy-yyy)>t||(xx+yy+xxx+yyy+t)%2==1)//普通剪枝+奇偶剪枝 { printf("NO "); continue; } ans=dfs(xx,yy,0); if(ans) { printf("YES "); } else { printf("NO "); } } return 0; }
第二次做,再来一份代码:
#include <stdio.h> #include <string.h> #include <math.h> int sx[4]= {1,-1,0,0}; int sy[4]= {0,0,-1,1}; int n,t,step[15][15],m,vis[15][15]; char s[15][15]; int dfs(int x,int y) { if(s[x][y]=='D'&&step[x][y]==t) { return 1; } if(s[x][y]=='.'||s[x][y]=='S') { for(int i=0; i<4; i++) { int kk1=x+sx[i]; int kk2=y+sy[i]; if(kk1>=0&&kk1<n&&kk2>=0&&kk2<m&&vis[kk1][kk2]==0) { vis[kk1][kk2]=1; step[kk1][kk2]=step[x][y]+1; int kk=dfs(kk1,kk2); if(kk==1) { return 1; } vis[kk1][kk2]=0; } } } return 0; } int main() { int x1,x2,k1,k2; while(~scanf("%d%d%d",&n,&m,&t)) { if(n==0&&m==0&&t==0) { break; } for(int i=0; i<n; i++) { scanf("%s",s[i]); for(int j=0; j<m; j++) { if(s[i][j]=='S') { x1=i; x2=j; } else if(s[i][j]=='D') { k1=i; k2=j; } } } if((x1+x2+k1+k2+t)%2!=0||fabs(x1-x2)+fabs(k1-k2)>t) { printf("NO "); } else { memset(vis,0,sizeof(vis)); step[x1][x2]=0; vis[x1][x2]=1; int ans=dfs(x1,x2); if(ans==1) { printf("YES "); } else { printf("NO "); } } } return 0; }