http://acm.hdu.edu.cn/showproblem.php?pid=1983

首先,题目要求出口和入口不能封闭,那么,只要把出口或入口的周围全给封闭了那盗贼肯定无法成功偷盗,出口或入口周围最多

会有四个点,所以初始答案ans=4(没必要计算出出口或入口可以封闭的最小值,就初始为4就好),然后从一到四枚举看有没有

最小的符合条件的值,

所以先用BFS查找出至少偷到一个宝石的最小时间的路径,记录下来,然后枚举封闭路径上的点递归回去,再BFS判断是否能偷盗

成功---DFS中插入BFS

 

code

 

 1 #include<cstdio>
 2 #include<queue>
 3 #include<cstring>
 4 using namespace std;
 5 struct point{
 6      int x,y;
 7      int time,flag;//记录时间和是否至少偷到一个宝石
 8      int rx[65],ry[65];//记录路径
 9 };
10 char map[10][10];
11 int visit[10][10][2];//开三维的数组时因为有偷到了和还没有偷到两种情况,作用相当于是当偷到第一个宝石后,再议这个宝石的地方为起点寻找到终点的时间最短路径,确保了是最短的
12 int n,m,sx,sy,tt,ans;
13 int dx[]={1,-1,0,0};
14 int dy[]={0,0,1,-1};
15 void DFS(int deep)
16 {
17     int i,k;
18     if (deep>ans) return ;
19     memset(visit,0,sizeof(visit));
20     queue<point>Q;
21     point now,next;
22     now.x=sx,now.y=sy;
23     now.time=now.flag=0;
24     visit[now.x][now.y][now.flag]=1;
25     Q.push(now);
26     int minn=-1;
27     while (!Q.empty())
28     {
29         now=Q.front();
30         Q.pop();
31         if (map[now.x][now.y]=='E'&&now.flag==1)
32         {
33             minn=now.time;
34             break;
35         }
36         for (i=0;i<4;i++)
37         {
38             next.x=now.x+dx[i];
39             next.y=now.y+dy[i];
40             if (next.x<1||next.x>n||next.y<1||next.y>m)continue;
41             if (map[next.x][next.y]=='#')continue;
42             if (now.time>=tt)continue;
43             if (map[next.x][next.y]=='J')  next.flag=1;
44             else next.flag=now.flag;
45             if (visit[next.x][next.y][next.flag]==1)continue;
46             for (k=1;k<=now.time;k++) //记录路径
47             {
48                 next.rx[k]=now.rx[k];
49                 next.ry[k]=now.ry[k];
50             }
51             next.time=now.time+1;
52             visit[next.x][next.y][next.flag]=1;
53             next.rx[next.time]=next.x;
54             next.ry[next.time]=next.y;
55             Q.push(next);
56         }
57     }
58     if (minn==-1)
59     {
60         if (deep<ans)
61             ans=deep;
62         return ;
63     }
64     for (i=1;i<=now.time;i++)
65     {
66         char op=map[now.rx[i]][now.ry[i]];
67         if (op=='E'||op=='S') continue;
68         map[now.rx[i]][now.ry[i]]='#';
69         DFS(deep+1);
70         map[now.rx[i]][now.ry[i]]=op;//回溯
71     }
72 }
73 int main()
74 {
75     int t,i,j;
76     while (~scanf("%d",&t))
77     {
78         while (t--)
79         {
80             getchar();
81             scanf("%d %d %d",&n,&m,&tt);
82             for (i=1;i<=n;i++)
83             {
84                 for (j=1;j<=m;j++)
85                 {
86                     scanf(" %c",&map[i][j]);
87                     if (map[i][j]=='S')
88                         sx=i,sy=j;
89                 }
90             }
91             ans=4;
92             DFS(0);
93             printf("%d\n",ans);
94         }
95     }
96     return 0;
97 }

 

posted on 2015-08-08 09:54  蜘蛛侦探  阅读(351)  评论(0编辑  收藏  举报