码迷,mamicode.com
首页 > 其他好文 > 详细

HDU-1459.非常可乐(BFS )

时间:2019-03-08 09:29:01      阅读:170      评论:0      收藏:0      [点我收藏+]

标签:open   break   clu   next   alt   原来   ring   namespace   print   

  这道题TLE了很多次,原来一直以为将数字化为最简可以让运算更快,但是去了简化之后才发现,真正耗时的就是化简....还和队友学到了用状态少直接数组模拟刚就能过...

  本题大意:给出可乐的体积v1,给出两个杯子v2和v3,要求v2 + v3 == v1,每次只能从一个杯子倒到另一个杯子,问最少倒多少次可以将可乐平分。

  思路:最后可乐肯定在可乐瓶和大杯子里面,直接DFS搜就行了。

  参考代码:

技术图片
 1 #include <cstdio>
 2 #include <queue>
 3 #include <cstring>
 4 using namespace std;
 5 
 6 struct node {
 7     int cur[3], step;
 8 } now, Next;
 9 
10 const int maxn = 100 + 5;
11 int v[3];
12 int  ans, t;
13 bool flag;
14 bool vis[maxn][maxn][maxn];
15 
16 void bfs() {
17     if(v[0] & 1) {
18         flag = false;
19         return;
20     } 
21     queue <node> Q;
22     now.cur[0] = v[0], now.cur[1] = 0, now.cur[2] = 0, now.step = 0;
23     vis[v[0]][0][0] = true;
24     Q.push(now);
25     while(!Q.empty()) {
26         now = Q.front();
27         Q.pop();
28         if(now.cur[0] == now.cur[1] && now.cur[2] == 0) {
29             ans = now.step;
30             return;
31         }
32         for(int i = 0; i < 3; i ++) {//i -> j
33             for(int j = 0; j < 3; j ++) {
34                 if(i != j) {
35                     Next = now;
36                     t = now.cur[i] + now.cur[j];
37                     if(t > v[j])  Next.cur[j] = v[j];
38                     else Next.cur[j] = t;
39                     Next.cur[i] = t - Next.cur[j];
40                     if(!vis[Next.cur[0]][Next.cur[1]][Next.cur[2]]) {
41                         Next.step = now.step + 1;
42                         Q.push(Next);
43                         vis[Next.cur[0]][Next.cur[1]][Next.cur[2]] = true;
44                     }
45                 }
46             }
47         }
48     }
49     flag = false;
50 }
51 
52 int main () {
53     while(~scanf("%d %d %d", &v[0], &v[1], &v[2])) {
54         memset(vis, false, sizeof(vis));
55         if(v[0] == 0 && v[1] == 0 && now.cur[2] == 0)  break;
56         flag = true, ans = 0;
57         if(v[1] < v[2]) {
58             t = v[1];
59             v[1] = v[2];
60             v[2] = t;
61         }
62         bfs();
63         if(flag) printf("%d\n", ans);
64         else    printf("NO\n");        
65     }
66     return 0;
67 }
View Code

   下面这个代码的效率要高一点,区别在于倒水方式不同。

技术图片
 1 #include <cstdio>
 2 #include <queue>
 3 #include <cstring>
 4 using namespace std;
 5 
 6 struct node {
 7     int cur[3], step;
 8 } now, Next;
 9 
10 const int maxn = 100 + 5;
11 int v[3];
12 int  ans, t;
13 bool flag;
14 bool vis[maxn][maxn][maxn];
15 
16 void bfs() {
17     if(v[0] & 1) {
18         flag = false;
19         return;
20     } 
21     queue <node> Q;
22     now.cur[0] = v[0], now.cur[1] = 0, now.cur[2] = 0, now.step = 0;
23     vis[v[0]][0][0] = true;
24     Q.push(now);
25     while(!Q.empty()) {
26         now = Q.front();
27         Q.pop();
28         if(now.cur[0] == now.cur[1] && now.cur[2] == 0) {
29             ans = now.step;
30             return;
31         }
32         for(int i = 0; i < 3; i ++) {//i -> j
33             for(int j = 0; j < 3; j ++) {
34                 if(i != j) {
35                     Next = now;
36                     if(j == 0) {
37                         Next.cur[j] = now.cur[j] + now.cur[i];
38                         Next.cur[i] = 0;
39                     } else if(j == 1) {
40                         t = v[1] - now.cur[j];
41                         Next.cur[i] = now.cur[i] - t;
42                         Next.cur[i] = Next.cur[i] > 0 ? Next.cur[i] : 0;
43                         Next.cur[j] = now.cur[j] + now.cur[i];
44                         Next.cur[j] = Next.cur[j] < v[1] ? Next.cur[j] : v[1];
45                     } else {
46                         t = v[2] - now.cur[j];
47                         Next.cur[i] = now.cur[i] - t;
48                         Next.cur[i] = Next.cur[i] > 0 ? Next.cur[i] : 0;
49                         Next.cur[j] = now.cur[j] + now.cur[i];
50                         Next.cur[j] = Next.cur[j] < v[2] ? Next.cur[j] : v[2];
51                     }
52                     if(!vis[Next.cur[0]][Next.cur[1]][Next.cur[2]]) {
53                         Next.step = now.step + 1;
54                         Q.push(Next);
55                         vis[Next.cur[0]][Next.cur[1]][Next.cur[2]] = true;
56                     }
57                 }
58             }
59         }
60     }
61     flag = false;
62 }
63 
64 int main () {
65     while(~scanf("%d %d %d", &v[0], &v[1], &v[2])) {
66         memset(vis, false, sizeof(vis));
67         if(v[0] == 0 && v[1] == 0 && now.cur[2] == 0)  break;
68         flag = true, ans = 0;
69         if(v[1] < v[2]) {
70             t = v[1];
71             v[1] = v[2];
72             v[2] = t;
73         }
74         bfs();
75         if(flag) printf("%d\n", ans);
76         else    printf("NO\n");        
77     }
78     return 0;
79 }
View Code

 

HDU-1459.非常可乐(BFS )

标签:open   break   clu   next   alt   原来   ring   namespace   print   

原文地址:https://www.cnblogs.com/bianjunting/p/10493581.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!