标签:
4 4 5 S.X. ..X. ..XD .... 3 4 5 S.X. ..X. ...D 0 0 0
NO YES
题意:
”S“为起点,”D“为终点,”X“为塌陷的地板。
每走一步为1秒,只要走到下一块地板,原来的地板便立即塌陷,判断从起点到终点是否可以刚好t秒。
思路分析:
直接用深搜会超时,所以要进行简单的剪枝,这里就需要了解奇偶剪枝。
奇偶剪枝
s | ||||
| | ||||
| | ||||
| | ||||
+ | — | — | — | e |
设所在位置s (sx,sy) 与 目标位置 e(ex,ey)
易知最短步数step=abs(ex-sx)+abs(ey-sy)
故 abs(ex-sx)+abs(ey-sy)的奇偶性就确定了最短步数step的奇偶性
绕过一个有障碍的格子,需要多走两步,如果经过t步刚好到终点,则必定有t-step=偶数;
因此 只有t-abs(ex-sx)-abs(ey-sy)=偶数(也可以写成t+ex+sx+ey+sy=偶数), 才能从起点刚好经过t步到达终点。
源代码:
1 #include <cstdio> 2 #include<iostream> 3 using namespace std; 4 const int MAX=10; 5 int n,m,t; 6 char a[MAX][MAX]; 7 int d[4][2]={{1,0},{0,1},{-1,0},{0,-1}}; 8 int startx,starty,endx,endy,flag; 9 void dfs(int dx,int dy,int k) 10 { 11 int i; 12 if(flag)return; 13 if(a[dx][dy]==‘X‘) return; 14 if(dx==endx&&dy==endy&&k==t) 15 { 16 flag=1; 17 return; 18 } 19 if(dx<1||dx>n||dy<1||dy>m||k>t) return; 20 for(i=0;i<4;i++) 21 { 22 a[dx][dy]=‘X‘; 23 dfs(dx+d[i][0],dy+d[i][1],k+1); //这个地方必须用k+1,不然当前一个不达到条件而返回时,k却已经加1 24 a[dx][dy]=‘.‘; 25 if(flag)return; 26 } 27 } 28 int main() 29 { 30 31 while(scanf("%d%d%d",&n,&m,&t)&&n&&m&&t) 32 { 33 flag=0; 34 int s=0; 35 for(int i=1;i<=n;i++) 36 for(int j=1;j<=m;j++) 37 { 38 cin>>a[i][j]; //如果这里用scanf的话,会吃掉每一行的换行符, 39 if(a[i][j]==‘S‘) 40 { 41 startx=i; 42 starty=j; 43 continue; 44 } 45 if(a[i][j]==‘D‘) 46 { 47 endx=i; 48 endy=j; 49 continue; 50 } 51 if(a[i][j]==‘X‘) 52 s++; 53 } 54 if((t+startx+starty+endx+endy)%2==1) //奇偶剪枝 55 { cout<<"NO"<<endl; continue;} 56 if((m*n-s)<t) 57 { cout<<"NO"<<endl; continue;} 58 dfs(startx,starty,0); 59 if(flag) 60 cout<<"YES"<<endl; 61 else 62 cout<<"NO"<<endl; 63 } 64 return 0; 65 }
标签:
原文地址:http://www.cnblogs.com/q-c-y/p/5410193.html