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
     
  • 相关阅读:
    对json的爱恨情仇
    Linux操作系统改动PATH的方法
    不好意思啊,我上周到今天不到10天时间,用纯C语言写了一个小站!想拍砖的就赶紧拿出来拍啊
    cmd启动Oracle服务和监听服务
    8.4.1 跨越整个分区的聚合函数
    nginx 代理tcp长连接短连接配置
    Nginx Upstream Keepalive 分析 保持长连接
    Xargs用法详解
    删除除了指定扩展名文件其他全部删除
    LINUX的文件按时间排序
  • 原文地址:https://www.cnblogs.com/bolderic/p/7342928.html
Copyright © 2011-2022 走看看