hdu1983 Kaitou Kid - The Phantom Thief (2)

  1 #include<stdio.h>
  2 #include<string.h>
  3 #include<queue>
  4 #include<algorithm>
  5 #define INF 0x7fffffff
  6 using namespace std;
  7 
  8 char maze[11][11],dire[4][2]={-1,0,1,0,0,-1,0,1};
  9 bool hash[11][11][2];
 10 typedef struct
 11 {
 12     int x,y,dist;
 13     bool jewel;
 14 }node;
 15 node sn;
 16 queue<node> Q;
 17 int n,m,t,ans;
 18 
 19 int ok(int x,int y)
 20 {
 21     if( x<1 || x>n || y<1 || y>m || '#'==maze[x][y] || 'S'==maze[x][y] || 'E'==maze[x][y] ) return 0;
 22     return 1;
 23 }
 24 
 25 bool bfs(void)
 26 {
 27     while( !Q.empty() ) Q.pop();
 28     memset(hash,false,sizeof(hash));
 29     sn.jewel=false;
 30     sn.dist=0;
 31     hash[sn.x][sn.y][sn.jewel]=true;
 32     Q.push(sn);
 33     while( !Q.empty() )
 34     {
 35         node cur=Q.front();
 36 
 37         Q.pop();
 38         if( cur.dist>=t )    return false;
 39         for(int i=0;i<4;i++)
 40         {
 41             node next;
 42 
 43             next.x=cur.x+dire[i][0];
 44             next.y=cur.y+dire[i][1];
 45             if( next.x<1 || next.x>n || next.y<1 || next.y>m || '#'==maze[next.x][next.y] )    continue;
 46             next.jewel=cur.jewel;
 47             if( 'J'==maze[next.x][next.y] )    next.jewel=true;
 48             if( hash[next.x][next.y][next.jewel] )        continue;
 49             hash[next.x][next.y][next.jewel]=true;
 50             next.dist=cur.dist+1;
 51             if( 'E'==maze[next.x][next.y] && next.jewel )    return true;
 52             Q.push(next);
 53         }
 54     }
 55     return false;
 56 }
 57 
 58 void dfs(int si,int sj,int step,int Max)
 59 {
 60     if( ans!=INF )    return;
 61     if( step>Max )
 62     {
 63         if( false==bfs() )    ans=step-1;
 64         return;
 65     }
 66 
 67     char tmp;
 68 
 69     for(int j=sj;j<=m;j++)
 70     {
 71         if( '#'==maze[si][j] || 'S'==maze[si][j] || 'E'==maze[si][j] )    continue;
 72         tmp=maze[si][j];
 73         maze[si][j]='#';
 74         dfs(si,j+1,step+1,Max);
 75         maze[si][j]=tmp;
 76     }
 77     for(int i=si+1;i<=n;i++)
 78         for(int j=1;j<=m;j++)
 79         {
 80             if( '#'==maze[i][j] || 'S'==maze[i][j] || 'E'==maze[i][j] )    continue;
 81             tmp=maze[i][j];
 82             maze[i][j]='#';
 83             dfs(i,j+1,step+1,Max);
 84             maze[i][j]=tmp;
 85         }
 86 }
 87 
 88 int main()
 89 {
 90     int T,sMax,eMax;
 91 
 92     scanf("%d",&T);
 93     while( T-- )
 94     {
 95         scanf("%d%d%d",&n,&m,&t);
 96         for(int i=1;i<=n;i++)
 97             scanf("%s",&maze[i][1]);
 98         for(int i=1;i<=n;i++)
 99             for(int j=1;j<=m;j++)
100                 if( 'S'==maze[i][j] )
101                 {
102                     sn.x=i,sn.y=j;
103                     sMax=ok(i-1,j)+ok(i+1,j)+ok(i,j-1)+ok(i,j+1);
104                 }
105                 else if( 'E'==maze[i][j] )
106                 {
107                     eMax=ok(i-1,j)+ok(i+1,j)+ok(i,j-1)+ok(i,j+1);
108                 }
109         if( false==bfs() )    {puts("0");continue;}
110         ans=INF;
111         for(int i=1;i<min(sMax,eMax);i++)
112         {
113             dfs(1,1,1,i);
114             if( ans!=INF )    break;
115         }
116         if( ans!=INF )    printf("%d\n",ans);
117         else printf("%d\n",min(sMax,eMax));
118     }
119     return 0;
120 }
121 /*
122     挺好的题目
123     dfs按个数逐渐增大的顺序枚举封锁情况,最多枚举到 min(sMax,eMax)-1
124     比如说封锁入口需要3(sMax=3),封锁出口需要4(eMax=4),那么做多枚举到2就可以了
125     再用bfs判定该情况是否可行
126     bfs状态:[x][y][2],即在该点是否已经有宝物
127 */
posted @ 2012-11-24 13:59  kiwi_bird  阅读(234)  评论(0编辑  收藏  举报