HDU 1495 非常可乐

题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=103921#problem/M

开始数组是三维210的,MLE,然后超时,stl-queue 改成了数组模拟队列。水题。

  1 /*
  2   想了想。好像和POJ 3414 差不多。
  3   看成是三个容器。初始容量分别是满着,0, 0, 然后问是否有可能两个杯子的水分别是第一个杯子的一半。如果有。输出最短步数。
  4   S == N + M.那就是至少两个杯子的容量>= s/2.
  5   如果有可能。首先s是偶数。然后,判断的话。好像就只能初始状态往下搜,然后遇到搜完所有的可能还没有就是不可能吧。状态不重复、就没法扩展还是会停止的。
  6  */
  7 
  8 #include <stdio.h>
  9 #include <string.h>
 10 #include <iostream>
 11 #include <queue>
 12 #define maxn 1000000
 13 using namespace std;
 14 
 15 int s, n, m;
 16 
 17 struct Node {
 18     int s, n, m;
 19 }que[10000], now, temp;
 20 
 21 int ans;
 22 int step[110][110][110];
 23 int vis[110][110][110];
 24 
 25 bool divide(Node a) {
 26     if (a.s == s/2 && a.n == s/2)
 27         return true;
 28     if (a.s == s/2 && a.m == s/2)
 29         return true;
 30     if (a.n == s/2 && a.m == s/2)
 31         return true;
 32     return false;
 33 }
 34 
 35 int head, tail;
 36 
 37 void bfs() {
 38     while(head < tail) {
 39         now = que[head++];
 40         if (divide(now)) {
 41             ans = step[now.s][now.n][now.m];
 42             return;
 43         }
 44         int pour;
 45         // 操作数 1.s->n 2.s->m 3.n->m 4.n->s 5.m->n 6.m->s
 46         if (now.s > 0 && now.n < n) {
 47             pour = min(now.s, n-now.n);
 48             temp.s = now.s - pour;
 49             temp.n = now.n + pour;
 50             temp.m = now.m;
 51 
 52             if (!vis[temp.s][temp.n][temp.m] && temp.s >= 0 && temp.n >= 0 && temp.m >= 0) {
 53                 que[tail++] = temp;
 54                 vis[temp.s][temp.n][temp.m] = 1;
 55                 step [temp.s][temp.n][temp.m] = step[now.s][now.n][now.m] + 1;
 56             }
 57 
 58         }
 59 
 60         if (now.s > 0 && now.m < m) {
 61             pour = min(now.s, m-now.m);
 62             temp.s = now.s - pour;
 63             temp.m = now.m + pour;
 64             temp.n = now.n;
 65             if (!vis[temp.s][temp.n][temp.m] && temp.s >= 0 && temp.n >= 0 && temp.m >= 0) {
 66                 que[tail++] = temp;
 67                 vis[temp.s][temp.n][temp.m] = 1;
 68                 step[temp.s][temp.n][temp.m] = step[now.s][now.n][now.m] + 1;
 69             }
 70         }
 71 
 72         if (now.n > 0 && now.s < s) {
 73             pour = min(now.n, s-now.s);
 74             temp.s = now.s + pour;
 75             temp.n = now.n - pour;
 76             temp.m = now.m;
 77             if (!vis[temp.s][temp.n][temp.m] && temp.s >= 0 && temp.n >= 0 && temp.m >= 0) {
 78                 que[tail++] = temp;
 79                 vis[temp.s][temp.n][temp.m] = 1;
 80                 step[temp.s][temp.n][temp.m] = step[now.s][now.n][now.m] + 1;
 81             }
 82         }
 83 
 84         if (now.n > 0 && now.m < m) {
 85             pour = min(now.n, m-now.m);
 86             temp.n = now.n - pour;
 87             temp.m = now.m + pour;
 88             temp.s = now.s;
 89             if (!vis[temp.s][temp.n][temp.m] && temp.s >= 0 && temp.n >= 0 && temp.m >= 0) {
 90                 que[tail++] = temp;
 91                 vis[temp.s][temp.n][temp.m] = 1;
 92                 step [temp.s][temp.n][temp.m] = step[now.s][now.n][now.m] + 1;
 93             }
 94         }
 95 
 96         if (now.m > 0 && now.s < s) {
 97             pour = min(now.m, s-now.s);
 98             temp.s = now.s + pour;
 99             temp.m = now.m - pour;
100             temp.n = now.n;
101             if (!vis[temp.s][temp.n][temp.m] && temp.s >= 0 && temp.n >= 0 && temp.m >= 0) {
102                 que[tail++] = temp;
103                 vis[temp.s][temp.n][temp.m] = 1;
104                 step [temp.s][temp.n][temp.m] = step[now.s][now.n][now.m] + 1;
105             }
106         }
107 
108          if (now.m > 0 && now.n < n) {
109             pour = min(now.m, n-now.n);
110             temp.n = now.n + pour;
111             temp.m = now.m - pour;
112             temp.s = now.s;
113             if (!vis[temp.s][temp.n][temp.m] && temp.s >= 0 && temp.n >= 0 && temp.m >= 0) {
114                 que[tail++] = temp;
115                 vis[temp.s][temp.n][temp.m] = 1;
116                 step [temp.s][temp.n][temp.m] = step[now.s][now.n][now.m] + 1;
117             }
118         }
119     }
120 }
121 
122 int main() {
123     while(~scanf("%d%d%d", &s, &n, &m)) {
124         now.s = s, now.n = 0, now.m = 0;
125         if (s % 2) {
126             printf("NO\n");
127             continue;
128         }
129         head = 0, tail = 0;
130         memset(step, 0, sizeof(step));
131         memset(vis, 0, sizeof(vis));
132         if (s == 0 && n == 0 && m == 0)
133             break;
134         ans = maxn;
135         que[tail++] = now;
136         vis[now.s][now.n][now.m] = 1;
137         step[now.s][now.n][now.m] = 0;
138 
139         bfs();
140         if (ans == maxn) {
141             printf("NO\n");
142         }
143         else printf("%d\n", ans);
144     }
145     return 0;
146 }
View Code

 

转载于:https://www.cnblogs.com/icode-girl/p/5169972.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值