ZOJ2081坑爹的题啊!由于少加了一个换行符,WA了很久纠结啊!泪奔啊!

  1 我的做法是先用BFS求的到达T最短的步数,再用DFS
2 做判断这样的路总共有几条和踩到地雷的路有几条,
3 DFS中用到了剪支,最后求比值即可
4 #include<cstdio>
5 #include<cstdlib>
6 #include<iostream>
7 #include<cstring>
8 #include<queue>
9
10 using namespace std;
11
12 int dx[4] = {1,-1,0, 0};
13 int dy[4] = {0, 0,1,-1};
14 char map[11][11];
15 int ncases, visit[11][11], n, m;
16 int si, sj, di, dj, minstep, sum, num_m;
17
18 typedef struct
19 {
20 int x, y;
21 int step;
22 }Point;
23 Point Start, Target;
24
25 int Reach(Point V, int step)//重要剪支,这要感谢好朋友阿焦提醒我,如果垂直距离相加大于最小步数就不必在判断了节省了时间
26 {
27 if( abs(Target.x-V.x) + abs(Target.y-V.y) + step > minstep)
28 return 0;
29 return 1;
30 }
31
32 void dfs(Point P, int step, bool mines)
33 {
34 if(P.x<0 || P.x>n || P.y<0 || P.y>m)
35 {
36 return;
37
38 }
39 if(Target.x==P.x&&Target.y==P.y&&step==minstep)
40 {
41 if(mines==true)//踩到地雷加一
42 num_m++;
43 sum++;总数乌鲁怎样都加1
44 }
45 if(map[P.x][P.y] == '#')
46 return ;
47 if( !Reach(P,step) )
48 return ;
49 if(map[P.x][P.y] == 'M')
50 mines = true;
51 for(int i=0; i<4; i++)//四个方向的DFS查找
52 {
53 Point V;
54 V.x = P.x + dx[i];
55 V.y = P.y + dy[i];
56 dfs(V, step+1, mines);
57 }
58 }
59
60 queue<Point>q;
61 int main()
62 {
63 int i, j, k, flag;
64
65 scanf("%d", &ncases);
66 getchar();//消除输入的回车键的影响
67 for(k=1; k<=ncases; k++)
68 {
69 scanf("%d%d",&n, &m);
70 getchar();
71 for(i=0; i<n; i++)
72 {
73 for(j=0; j<m; j++)
74 {
75 scanf("%c", &map[i][j]);
76 if(map[i][j] == 'S')
77 {
78 si = i;
79 sj = j;
80 }
81 if(map[i][j] == 'T')
82 {
83 di = i;
84 dj = j;
85 }
86 }
87 getchar();
88 }
89 memset(visit, 0, sizeof(visit));
90 visit[si][sj] = 1;
91 Start.step = 0;
92 Start.x = si;
93 Start.y = sj;
94 Target.x = di;
95 Target.y = dj;
96 q.push(Start);
97 sum = num_m = 0;
98 flag = 0;
99 while( !q.empty() )
100 {
101 Point u = q.front();
102 q.pop();
103 if(map[u.x][u.y]=='T')//找到了就退出得到最小步数
104 {
105 minstep = u.step;
106 flag = 1;
107 break;
108 }
109 for(i=0; i<4; i++)
110 {
111 Point v;
112 v.x = u.x + dx[i];
113 v.y = u.y + dy[i];
114 v.step = u.step + 1;
115 if(!visit[v.x][v.y]&&map[v.x][v.y]!='#'&&v.x>=0&&v.x<n&&v.y>=0&&v.y<m)
116 {
117 q.push(v);
118 visit[v.x][v.y] = 1;
119 }
120 }
121 }
122 dfs(Start, 0, false);//开始深搜寻找路径的数目
123 printf("Mission #%d:\n",k);
124 if(flag==0 || sum==num_m)
125 printf("Mission Impossible.\n\n");
126 else
127 {
128 printf("The probability for the spy to get to the telegraph transmitter is");
129 printf(" %.2lf%%.\n\n",((sum-num_m+0.0)*100.0)/sum);
130 }
131 while( !q.empty() )
132 {
133 q.pop();
134 } //清空当前队列
135 }
136 return 0;
137 }
138

转载于:https://www.cnblogs.com/cn19901203/archive/2012/03/03/2378459.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值