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

    大家一定觉的运动以后喝可乐是一件很惬意的事情,但是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

    题意:
    三个杯子已知容量,只有一杯可乐,来回倒,问多少次能把可乐均分成两份
    题意很简单的,关键是思路

    思路:
    倒的过程只有六种,即6个方向,要求的操作数类似于其他bfs要求的步数
    把题中的s n m用数组存,来回倒的过程就能用里外两个循环写,方便一点

    代码:

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 #include <string.h>
     4 
     5 int b[5];
     6 struct node
     7 {
     8     int a[5];
     9     int step;
    10 } str[1005], x, y;
    11 int vis[105][105][105];
    12 
    13 void bfs(int s)
    14 {
    15     if(s%2!=0) printf("NO
    ");
    16     else if(b[1]==s/2) printf("1
    ");
    17     else
    18     {
    19         int i, j, in, out;
    20         in = 0;
    21         out = 0;
    22         x.a[0] = s;
    23         x.a[1] = 0;
    24         x.a[2] = 0;
    25         x.step = 0;
    26         str[in++] = x;
    27         while(in>out)
    28         {
    29             x = str[out++];  //得到最末尾的一个状态
    30             for(i=0; i<3; i++)    //x.a[i]往外倒
    31             {
    32                 if(x.a[i]==0) continue;  //有的倒
    33                 for(j=0; j<3; j++)    //x.a[j]往里接
    34                 {
    35                     if(i==j) continue;    //不能一个杯子操作!(一开始这里也没写,样例能过,但是代码不对)
    36                     y = x;
    37                     if(x.a[i]+x.a[j] >= b[j])  //能倒满
    38                     {                          //注意里面式子都是不能倒过来的
    39                         y.a[i] = x.a[i] + x.a[j] - b[j];
    40                         y.a[j] = b[j];
    41                     }
    42                     else  //不能倒满
    43                     {
    44                         y.a[j] = x.a[i] + x.a[j];
    45                         y.a[i] = 0;
    46                     }
    47                     if(vis[y.a[0]][y.a[1]][y.a[2]]==0)   //如果这个状态是新的,判断+进队列
    48                     {
    49                         y.step++;
    50                         if((y.a[0]==b[0]/2&&y.a[1]==b[0]/2)  //一开始把判断写在判断上面的x了,
    51                                   //每次判断最后一个,超时了。应该是得到一个状态就判断
    52                                   //避免后知后觉做了一些无谓的动作
    53                                 ||(y.a[0]==b[0]/2&&y.a[2]==b[0]/2)
    54                                 ||(y.a[1]==b[0]/2&&y.a[2]==b[0]/2)
    55                           )
    56                         {
    57                             printf("%d
    ", y.step);
    58                             return;
    59                         }
    60                         str[in++] = y;
    61                         vis[y.a[0]][y.a[1]][y.a[2]] = 1;
    62                     }
    63                 }
    64             }
    65         }
    66         printf("NO
    ");
    67     }
    68 }
    69 
    70 int main()
    71 {
    72     while(~scanf("%d %d %d", &b[0], &b[1], &b[2]))
    73     {
    74         if(!b[0]&&!b[1]&&!b[2]) break;
    75         memset(vis, 0, sizeof(vis));
    76         vis[b[0]][0][0] = 1;
    77         bfs(b[0]);
    78     }
    79     return 0;
    80 }
  • 相关阅读:
    net.sf.fmj.media.cdp.civil.CaptureDevicePlugger addCaptureDevices解决方法
    SVN快速入门教程
    Struts 2详细工作流程
    未能加载.NET基类问题
    图片上传的例子
    一个.NET发邮件的简单例子
    一种巧妙的删除程序自己的方法
    oracle的问题
    javascript 中对Trim()的实现
    SQL Server 不存在或访问被拒绝的问题
  • 原文地址:https://www.cnblogs.com/0xiaoyu/p/11356310.html
Copyright © 2011-2022 走看看