zoukankan      html  css  js  c++  java
  • HDU 1495 非常可乐

    题目链接http://acm.hdu.edu.cn/showproblem.php?pid=1495

    题目大意:给你三个瓶子,第一个瓶子容量S,装满了S单位的可乐。另外两个瓶子容量等于第一个。三个瓶子都无刻度。给出三个瓶子容量,问能否将第一个瓶子装S/2的可乐,其余两个瓶子无所谓,中途不能喝可乐。

    解题思路:单纯看来像是个数学题(好像确实能用数学做),但是可以认为,三个瓶子初始状态(s,0,0),终止状态(s/2, x, x),那么宽搜即可。

    搜索过程实际就是状态转移的过程。每次可以有S->M, S->N, M->S, M->N, N->S, N->M六个状态,但细节稍微复杂,仔细考虑也不算麻烦。

    代码:

      1 const int maxn = 105;
      2 int s, m, n;
      3 struct node{
      4     int s, n, m;
      5     int t;
      6 };
      7 int vis[maxn][maxn];
      8 queue<node> q; 
      9 
     10 int bfs(){
     11     memset(vis, 0, sizeof(vis));
     12     while(!q.empty()) q.pop();
     13     node u;
     14     u.s = s; u.m = u.n = u.t = 0;
     15     vis[s][0] = 1;
     16     q.push(u);
     17     bool flag = false;
     18     while(!q.empty()){
     19         u = q.front(); q.pop();
     20         if(u.s == s / 2) {
     21             flag = true;
     22             break;
     23         }
     24         u.t++;
     25         if(u.n < n) {
     26             node v = u;
     27             if(v.s <= (n - v.n)){
     28                 v.n += v.s; v.s = 0; 
     29             }
     30             else{    
     31                 v.s -= (n - v.n);
     32                 v.n = n; 
     33             }
     34             if(!vis[v.s][v.n]){    
     35                 q.push(v);
     36                 vis[v.s][v.n] = 1;
     37             }
     38             
     39             v = u;
     40             if(v.m <= (n - v.n)){
     41                 v.n += v.m; v.m = 0; 
     42             }
     43             else{
     44                 v.m -= (n - v.n); v.n = n;
     45             }
     46             if(!vis[s - v.m - v.n][v.n]){ 
     47                 q.push(v);
     48                 vis[s - v.m - v.n][v.n] = 1;
     49             }
     50         }
     51         if(u.m < m){
     52             node v = u;
     53             if(v.s <= (m - v.m)){
     54                 v.m += v.s; v.s = 0; 
     55             }
     56             else{
     57                 v.s -= (m - v.m); v.m = m;
     58             }
     59             if(!vis[v.s][s - v.s - v.m]){
     60                 q.push(v);
     61                 vis[v.s][s - v.s - v.m] = 1;
     62             }
     63             
     64             v = u;
     65             if(v.n <= (m - v.m)){
     66                 v.m += v.n; v.n = 0; 
     67             }
     68             else{
     69                 v.n -= (m - v.m); v.m = m;
     70             }
     71             if(!vis[s - v.n - v.m][v.n]){
     72                 q.push(v);
     73                 vis[s - v.n - v.m][v.n] = 1;
     74             }
     75         }
     76         if(u.s < s){
     77             node v = u;
     78             if(v.m <= s - v.s){
     79                 v.s += v.m; v.m = 0; 
     80             }
     81             else{
     82                 v.m -= (s - v.s); v.s = s;
     83             }
     84             if(!vis[v.s][s - v.m - v.s]){
     85                 q.push(v);
     86                 vis[v.s][s - v.m - v.s] = 1;
     87             }
     88             
     89             v = u;
     90             if(v.n <= s - v.s){
     91                 v.s += v.n; v.n = 0;
     92             }
     93             else{
     94                 v.n -= s - v.s; v.s = s;
     95             }
     96             if(!vis[v.s][v.n]){
     97                 q.push(v);
     98                 vis[v.s][v.n] = 1;
     99             }
    100         }
    101     }
    102     if(!flag) return -1;
    103     return u.t;
    104 }
    105 
    106 int main(){
    107     while(scanf("%d %d %d", &s, &n, &m) != EOF && s != 0){
    108         if(s & 1) {
    109             puts("NO");
    110             continue;
    111         }
    112         else if(n == m){
    113             puts("1");
    114             continue;
    115         }
    116         else{
    117             int ans = bfs();
    118             if(ans == -1) puts("NO");
    119             else printf("%d
    ", ans);
    120         }
    121     }
    122 }

    题目:

    非常可乐

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 16616    Accepted Submission(s): 6709


    Problem Description
    大家一定觉的运动以后喝可乐是一件很惬意的事情,但是seeyou却不这么认为。因为每次当seeyou买了可乐以后,阿牛就要求和seeyou一起分享这一瓶可乐,而且一定要喝的和seeyou一样多。但seeyou的手中只有两个杯子,它们的容量分别是N 毫升和M 毫升 可乐的体积为S (S<101)毫升 (正好装满一瓶) ,它们三个之间可以相互倒可乐 (都是没有刻度的,且 S==N+M,101>S>0,N>0,M>0) 。聪明的ACMER你们说他们能平分吗?如果能请输出倒可乐的最少的次数,如果不能输出"NO"。
     

     

    Input
    三个整数 : S 可乐的体积 , N 和 M是两个杯子的容量,以"0 0 0"结束。
     

     

    Output
    如果能平分的话请输出最少要倒的次数,否则输出"NO"。
     

     

    Sample Input
    7 4 3 4 1 3 0 0 0
     

     

    Sample Output
    NO 3
     

     

    Author
    seeyou
     

     

    Source
     
  • 相关阅读:
    CodeForces Gym 100500A A. Poetry Challenge DFS
    CDOJ 486 Good Morning 傻逼题
    CDOJ 483 Data Structure Problem DFS
    CDOJ 482 Charitable Exchange bfs
    CDOJ 481 Apparent Magnitude 水题
    Codeforces Gym 100637G G. #TheDress 暴力
    Gym 100637F F. The Pool for Lucky Ones 暴力
    Codeforces Gym 100637B B. Lunch 找规律
    Codeforces Gym 100637A A. Nano alarm-clocks 前缀和
    TC SRM 663 div2 B AABB 逆推
  • 原文地址:https://www.cnblogs.com/bolderic/p/7342928.html
Copyright © 2011-2022 走看看