ACM1010一个细节
The doggie found a bone in an ancient maze, which fascinated him a lot. However, when he picked it up, the maze began to shake, and the doggie could feel the ground sinking. He realized that the bone was a trap, and he tried desperately to get out of this maze.
The maze was a rectangle with sizes N by M. There was a door in the maze. At the beginning, the door was closed and it would open at the T-th second for a short period of time (less than 1 second). Therefore the doggie had to arrive at the door on exactly the T-th second. In every second, he could move one block to one of the upper, lower, left and right neighboring blocks. Once he entered a block, the ground of this block would start to sink and disappear in the next second. He could not stay at one block for more than one second, nor could he move into a visited block. Can the poor doggie survive? Please help him.
The maze was a rectangle with sizes N by M. There was a door in the maze. At the beginning, the door was closed and it would open at the T-th second for a short period of time (less than 1 second). Therefore the doggie had to arrive at the door on exactly the T-th second. In every second, he could move one block to one of the upper, lower, left and right neighboring blocks. Once he entered a block, the ground of this block would start to sink and disappear in the next second. He could not stay at one block for more than one second, nor could he move into a visited block. Can the poor doggie survive? Please help him.
Input
The input consists of multiple test cases. The first line of each test case contains three integers N, M, and T (1 < N, M < 7; 0 < T < 50), which denote the sizes of the maze and the time at which the door will open, respectively. The next N lines give the maze layout, with each line containing M characters. A character is one of the following:
'X': a block of wall, which the doggie cannot enter;
'S': the start point of the doggie;
'D': the Door; or
'.': an empty block.
The input is terminated with three 0's. This test case is not to be processed.
'X': a block of wall, which the doggie cannot enter;
'S': the start point of the doggie;
'D': the Door; or
'.': an empty block.
The input is terminated with three 0's. This test case is not to be processed.
Output
For each test case, print in one line "YES" if the doggie can survive, or "NO" otherwise.
Sample Input
4 4 5
S.X.
..X.
..XD
....
3 4 5
S.X.
..X.
...D
0 0 0
Sample Output
NO YES
#include<iostream> using namespace std; int startx,starty,endx,endy,t; int n,m; char net[9][9]; int ok; int direction[4][2]={{1,0},{-1,0},{0,-1},{0,1}}; void dfs(int x,int y,int time) { int i; if(x<1||y<1||x>n||y>m||time>t)return;//越界退出 if(net[x][y]=='X')return; if(x==endx&&y==endy&&time==t)//成功退出 (在这个位置开始我用的是net[x][y]=='X'进行判断,结果总是错误,那是因为在之前他被修改了;所以说用坐标判断最稳 { ok=1; return; } if((x+y+endx+endy+t-time)%2==1)return;//这个地方是利用图内的一个特点,下面有关于它的专门介绍 for(i=0;i<4;i++) { net[x][y]='X'; dfs(x+direction[i][0],y+direction[i][1],time+1); net[x][y]='.'; if(ok==1)return; } } int main() { int block; while(cin>>n>>m>>t&&m&&n&&t) { block=0; ok=0; for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { cin>>net[i][j]; if(net[i][j]=='S'){startx=i;starty=j; } else if(net[i][j]=='X')block++; else if(net[i][j]=='D'){endx=i;endy=j; } } } if((startx+endx+starty+endy+t)%2==1||(n*m-block<t))//和上面一样,利用奇偶性剪枝 { cout<<"NO"<<endl;continue; } dfs(startx,starty,0); if(ok) { cout<<"YES"<<endl; } else cout<<"NO"<<endl; } return 0; }
问题分析:
是否存在从出发点到终点距离为time的路径
若将这个地图看成是一张图,那么在n*m,时间t的情况从s点走到d点,经过t条边的路径数平均有900多条,每条长度为t,那么这个dfs的运行的时间就会达到T(900*t),比较极限的数据会使一个dfs能有几百万的复杂度,那么这个程序肯定是会超时的了.
主要的剪枝条件有:
1、剩余可走区域小于时间
2、奇偶性剪枝
3、越界
4、超时等
下面主要说说奇偶性剪枝
若有一迷宫,将迷宫的每一个位置有0或1表示(x+y为偶数时 为0 否则为1):
0 1 0 1 0
1 0 1 0 1
0 1 0 1 0
1 0 1 0 1
它的规律是:0和1相间排列。仔细观察不难发现,当行号和列号同为奇数,或者同为偶数时,写0;否则,写1。
而且,从0的格子走1步,不管哪个方向,都会走到1的格子上。
于是我们得出这样的结论:
0->1 或 1->0 必定走奇数步,
0->0 或 1->1 必定走偶数步。
所以当我们遇到不满足上述两个结论的,可以推断它不能到达,所以中止搜索。
还有一种特殊情况,就是当地图上能走的点的个数(不包括起点)小于时间t的时候,显然不能到达,这时可以不用搜索,直接输出NO;
这个题目就是利用DFS进行做,可以作为一个练习去体会深搜的威力吧,作为初学者的,记录下来,以后容易回来复习,从这道题目里我还了解了奇偶剪枝呢,收获不菲啊。谁让我不喜欢做笔记呢,就借助这个平台记录吧。
What I don't dare to say is I can't!