HDOJ 1010

 

深度搜索,注意要剪枝

1.奇偶剪枝

  可以把map看成这样:
  0 1 0 1 0 1
  1 0 1 0 1 0
  0 1 0 1 0 1
  1 0 1 0 1 0
  0 1 0 1 0 1
  从为 0 的格子走一步,必然走向为 1 的格子
  从为 1 的格子走一步,必然走向为 0 的格子
  即:
  0 ->1或1->0 必然是奇数步
  0->0 走1->1 必然是偶数步
 
则如果((di-si+dj-sj)&1)!=(t&1) 就可以直接输出“NO”了
 
2.判断可走的block是否小于时间总数
  n*m-wall<=t  就输出“NO”

 

 1 #include <iostream>
 2 #include <stdio.h>
 3 using namespace std;
 4 
 5 char map[10][10];
 6 int desc[4][2]={{-1,0},{1,0},{0,1},{0,-1}};
 7 int si,sj,di,dj;
 8 int n,m,t;
 9 int escape;
10 
11 void dfs(int ni,int nj,int nt)
12 {
13     if(escape) return;
14     if(nt>t) return;
15     else if(nt==t)
16     {
17         if(ni==di && nj==dj)
18         {
19             printf("YES\n");
20             escape=1;
21         }
22         return;
23     }
24     else
25     {
26         for(int k=0;k<4;++k)
27         {
28             if(ni+desc[k][0]>-1&&ni+desc[k][0]<n && nj+desc[k][1]>-1&&nj+desc[k][1]<m)
29             {
30                 if(map[ni+desc[k][0]][nj+desc[k][1]]!='X')
31                 {
32                     map[ni][nj]='X';
33                     //printf("goto (%d,%d) %d\n",ni+desc[k][0],nj+desc[k][1],nt+1);
34                     dfs(ni+desc[k][0],nj+desc[k][1],nt+1);
35                     map[ni][nj]='.';
36                 }
37             }
38         }
39     }
40 }
41 
42 int main()
43 {
44     int i,j,wall;
45 
46     while(scanf("%d %d %d",&n,&m,&t),n||m||t)
47     {
48         escape=0;
49         di=10;
50         dj=10;
51         wall=0;
52         getchar();
53         for(i=0;i<n;++i)
54         {
55             for(j=0;j<m;++j)
56             {
57                 //scanf("%c",&map[i][j]);
58                 cin>>map[i][j];
59                 if(map[i][j]=='S')
60                 {
61                     si=i;
62                     sj=j;
63                 }
64                 else if(map[i][j]=='D')
65                 {
66                     di=i;
67                     dj=j;
68                 }
69                 else if(map[i][j]=='X') ++wall;
70             }
71             //getchar();
72         }
73 
74         //前半句是判断可以走的block数是否小于等于时间;
75         //后半句是奇偶剪枝
76         if(n*m-wall<=t || ((di-si+dj-sj)&1)!=(t&1))
77         {
78             printf("NO\n");
79             continue;
80         }
81         dfs(si,sj,0);
82         if(escape==0) printf("NO\n");
83     }
84 }

 

posted @ 2013-12-16 13:21  forkbomb  阅读(218)  评论(0)    收藏  举报