Tempter of the Bone HDU - 1010

原题链接

考察:dfs+剪枝

错误思路:

        用bfs解此题,会WA,因为我们要时间为T时刚刚好到达,bfs是最短时间.这道题需要我们在D周围绕圈子

思路:

        直接暴力TLE了.所以需要一些剪枝.

  1. 当时间==T时回溯
  2. 这个剪枝比较关键,奇偶剪枝,如果S坐标之和的奇偶与D奇偶相同,说明我们到达D需要偶数步,奇偶不同需要奇数步.不管怎么绕圈子都是一样.

这位大佬的证明比较详细 GO

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio> 
 4 using namespace std;
 5 const int N = 8;
 6 int n,m,T;
 7 int xx[4] ={-1,1,0,0},yy[4] = {0,0,-1,1};
 8 char mp[N][N];
 9 bool st[N][N];
10 bool dfs(int x,int y,int t)
11 {
12     if(t==T)
13     {
14         if(mp[x][y]=='D') return 1;
15         return 0;
16     }
17     for(int i=0;i<4;i++)
18     {
19         int dx = x+xx[i],dy = y+yy[i];
20         if(dx>0&&dx<=n&&dy>0&dy<=m&&mp[dx][dy]!='X'&&!st[dx][dy])
21         {
22             st[dx][dy] = 1;
23             if(dfs(dx,dy,t+1)) return 1;
24             st[dx][dy] = 0;
25         }
26     }
27     st[x][y] = 1;
28     return 0;
29 }
30 int main()
31 {
32     while(scanf("%d%d%d",&n,&m,&T)!=EOF&&n)
33     {
34         int x,y,ex,ey;
35         for(int i=1;i<=n;i++)
36           scanf("%s",mp[i]+1);
37         for(int i=1;i<=n;i++)
38           for(int j=1;j<=m;j++)
39           {
40               st[i][j] = 0;
41               if(mp[i][j]=='S') x = i,y = j;
42               else if(mp[i][j]=='D') ex = i,ey = j;
43           }
44         int t = (x+y)&1,k = (ex+ey)&1;
45         if(t!=k&&!(T&1)) {puts("NO");continue;}
46         if(t==k&&(T&1)) {puts("NO");continue;}
47         st[x][y] = 1;
48         if(dfs(x,y,0)) puts("YES");
49         else puts("NO");
50     }
51     return 0;
52 }

 

posted @ 2021-03-09 23:11  acmloser  阅读(49)  评论(0编辑  收藏  举报