zoukankan      html  css  js  c++  java
  • poj1606 poj3414

                        Jugs

    Description

    In the movie "Die Hard 3", Bruce Willis and Samuel L. Jackson were confronted with the following puzzle. They were given a 3-gallon jug and a 5-gallon jug and were asked to fill the 5-gallon jug with exactly 4 gallons. This problem generalizes that puzzle. 

    You have two jugs, A and B, and an infinite supply of water. There are three types of actions that you can use: (1) you can fill a jug, (2) you can empty a jug, and (3) you can pour from one jug to the other. Pouring from one jug to the other stops when the first jug is empty or the second jug is full, whichever comes first. For example, if A has 5 gallons and B has 6 gallons and a capacity of 8, then pouring from A to B leaves B full and 3 gallons in A. 

    A problem is given by a triple (Ca,Cb,N), where Ca and Cb are the capacities of the jugs A and B, respectively, and N is the goal. A solution is a sequence of steps that leaves exactly N gallons in jug B. The possible steps are 

    fill A 
    fill B 
    empty A 
    empty B 
    pour A B 
    pour B A 
    success 

    where "pour A B" means "pour the contents of jug A into jug B", and "success" means that the goal has been accomplished. 

    You may assume that the input you are given does have a solution.

    Input

    Input to your program consists of a series of input lines each defining one puzzle. Input for each puzzle is a single line of three positive integers: Ca, Cb, and N. Ca and Cb are the capacities of jugs A and B, and N is the goal. You can assume 0 < Ca <= Cb and N <= Cb <=1000 and that A and B are relatively prime to one another.

    Output

    Output from your program will consist of a series of instructions from the list of the potential output lines which will result in either of the jugs containing exactly N gallons of water. The last line of output for each puzzle should be the line "success". Output lines start in column 1 and there should be no empty lines nor any trailing spaces.

    Sample Input

    3 5 4 
    5 7 3 

    Sample Output

    fill B 
    pour B A 
    empty A 
    pour B A 
    fill B 
    pour B A 
    success 
    fill A 
    pour A B 
    fill A 
    pour A B 
    empty B 
    pour A B 
    success 

    题意:输入A、B、D三个数。表示有A、B两个这么大的桶,要求通过加满水,倒水,清空水桶的操作,在B桶中有D这么多的水。
    fill A/B 把桶A/B加满水
    pour B A 把A桶的水倒去桶B
    pour A B 把B桶的水倒去桶A
    empty A/B 把桶A/B的水清空
    最后的水一定要在桶B处。
    思路:运用bfs将各种状态入队,用数组flag查找该状态是否经历过。巧妙的利用链表寻找路径输出。
      1 #include<cstdio>
      2 #include<cstring>
      3 #include<string>
      4 #include<queue>
      5 #define MAX 106
      6 using namespace std;
      7 struct C{
      8     int x,y,setp,ou;
      9     C *pre;
     10 };
     11 int A,B,D;
     12 int flag[MAX][MAX];
     13 int ans,top;
     14 int out[MAX*2];
     15 
     16 void bfs()
     17 {
     18     C fin;
     19     C cow[MAX*2];
     20     int num=0;
     21 
     22     queue<C> op;
     23     fin.pre=NULL;///fin只是中间变量,把中间的pre都加入到队列中进行转换
     24     fin.x=fin.y=fin.setp=fin.ou=0;
     25     op.push(fin);
     26 
     27     while(!op.empty()){
     28         num++;
     29         cow[num]=op.front();
     30         op.pop();
     31 //        printf("%d
    ",cow[num].x);
     32         for(int i=1;i<=6;i++){///经历6项操作,一一模拟
     33             switch(i){
     34                 case 1:fin.x=A,fin.y=cow[num].y,fin.ou=1; break;
     35                 case 2:fin.x=cow[num].x,fin.y=B,fin.ou=2; break;
     36                 case 3:fin.x=0,fin.y=cow[num].y,fin.ou=3; break;
     37                 case 4:fin.x=cow[num].x, fin.y=0,fin.ou=4; break;
     38                 case 5:
     39                     if(cow[num].x+cow[num].y<=A){
     40                         fin.x=cow[num].x+cow[num].y;
     41                         fin.y=0; fin.ou=5;
     42                     }
     43                     else{
     44                         fin.x=A;
     45                         fin.y=cow[num].x+cow[num].y-A; fin.ou=5;
     46                     }
     47                     break;
     48                 case 6:
     49                     if(cow[num].x+cow[num].y<=B){
     50                         fin.y=cow[num].x+cow[num].y;
     51                         fin.x=0; fin.ou=6;
     52                     }
     53                     else{
     54                         fin.y=B;
     55                         fin.x=cow[num].x+cow[num].y-B; fin.ou=6;
     56                     }
     57                     break;
     58             }
     59             if(!flag[fin.x][fin.y]){
     60                 flag[fin.x][fin.y]=1;
     61                 fin.setp=cow[num].setp+1;
     62                 fin.pre=&cow[num];  ///指向该出的链
     63 
     64                 if(fin.y==D){
     65                     top=1;
     66                     ans=fin.setp;
     67                     while(fin.pre){
     68                         out[top++]=fin.ou;
     69                         fin=*fin.pre;
     70                     }
     71                     return ;
     72                 }
     73                 op.push(fin);
     74             }
     75         }
     76     }
     77 }
     78 
     79 int main()
     80 {
     81     while( ~scanf("%d%d%d",&A,&B,&D)){ 
     82         memset( flag, 0, sizeof flag);
     83         ans=0;
     84         bfs();
     85 //        printf("%d
    ",ans);
     86         if(ans==0) ;
     87         else{
     88 //            printf("%d
    ",ans);
     89             while(--top){
     90                 switch(out[top]){
     91                     case 1:printf("fill A
    ");break;
     92                     case 2:printf("fill B
    ");break;
     93                     case 3:printf("empty A
    ");break;
     94                     case 4:printf("empty B
    ");break;
     95                     case 5:printf("pour B A
    ");break;
     96                     case 6:printf("pour A B
    ");break;
     97                 }
     98             }
     99             printf("success
    ");
    100         }
    101     }
    102     return 0;
    103 }

    刚开始不清楚怎么判断,用了set把结构体放进了set里面。而且重载还有问题,于是在这里记录一下set的结构体重载。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 struct W{
     4     int a,b;
     5     bool operator < (const W &rhs) const{
     6         if(this->a==rhs.a) return this->b < rhs.b;
     7         return this->a < rhs.a; 
     8     };  ///排列a
     9 };
    10 
    11 set<W> seek;
    12 int main()
    13 {
    14     W cow;
    15     cow.a=3; cow.b=0;
    16     seek.insert(cow);///(3,0)
    17 
    18     cow.a=0; cow.b=5;
    19     seek.insert(cow);///(0,5)
    20 
    21     cow.a=3;cow.b=5;
    22     if(!seek.count(cow)){///查(3,5)
    23         printf("yes
    ");
    24     }
    25 
    26     return 0;
    27 }

    好不容易把set的结构体重载捣鼓好,发现不会找路径。qwq

    由于死活想不明白,然后去网上找到题解,发现了运用链表回溯的操作,感觉十分好理解。于是就参考运用了链表运用了。

    参考:https://blog.csdn.net/u012860063/article/details/37772275



                Pots

    Description

    You are given two pots, having the volume of A and B liters respectively. The following operations can be performed:

    1. FILL(i)        fill the pot i (1 ≤ ≤ 2) from the tap;
    2. DROP(i)      empty the pot i to the drain;
    3. POUR(i,j)    pour from pot i to pot j; after this operation either the pot j is full (and there may be some water left in the pot i), or the pot i is empty (and all its contents have been moved to the pot j).

    Write a program to find the shortest possible sequence of these operations that will yield exactly C liters of water in one of the pots.

    Input

    On the first and only line are the numbers AB, and C. These are all integers in the range from 1 to 100 and C≤max(A,B).

    Output

    The first line of the output must contain the length of the sequence of operations K. The following K lines must each describe one operation. If there are several sequences of minimal length, output any one of them. If the desired result can’t be achieved, the first and only line of the file must contain the word ‘impossible’.

    Sample Input

    3 5 4

    Sample Output

    6
    FILL(2)
    POUR(2,1)
    DROP(1)
    POUR(2,1)
    FILL(2)
    POUR(2,1)

    与上面一题相同,就顺便记录下来。

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<string>
      4 #include<queue>
      5 #define MAX 106
      6 using namespace std;
      7 struct C{
      8     int x,y,setp,ou;
      9     C *pre;
     10 };
     11 int A,B,D;
     12 int flag[MAX][MAX];
     13 int ans,top;
     14 int out[MAX*2];
     15 
     16 void bfs()
     17 {
     18     C fin;
     19     C cow[MAX*2];
     20     int num=0;
     21 
     22     queue<C> op;
     23     fin.pre=NULL;
     24     fin.x=fin.y=fin.setp=fin.ou=0;
     25     op.push(fin);
     26 
     27     while(!op.empty()){
     28         num++;
     29         cow[num]=op.front();
     30         op.pop();
     31 //        printf("%d
    ",cow[num].x);
     32         for(int i=1;i<=6;i++){
     33             switch(i){
     34                 case 1:fin.x=A,fin.y=cow[num].y,fin.ou=1; break;
     35                 case 2:fin.x=cow[num].x,fin.y=B,fin.ou=2; break;
     36                 case 3:fin.x=0,fin.y=cow[num].y,fin.ou=3; break;
     37                 case 4:fin.x=cow[num].x, fin.y=0,fin.ou=4; break;
     38                 case 5:
     39                     if(cow[num].x+cow[num].y<=A){
     40                         fin.x=cow[num].x+cow[num].y;
     41                         fin.y=0; fin.ou=5;
     42                     }
     43                     else{
     44                         fin.x=A;
     45                         fin.y=cow[num].x+cow[num].y-A; fin.ou=5;
     46                     }
     47                     break;
     48                 case 6:
     49                     if(cow[num].x+cow[num].y<=B){
     50                         fin.y=cow[num].x+cow[num].y;
     51                         fin.x=0; fin.ou=6;
     52                     }
     53                     else{
     54                         fin.y=B;
     55                         fin.x=cow[num].x+cow[num].y-B; fin.ou=6;
     56                     }
     57                     break;
     58             }
     59             if(!flag[fin.x][fin.y]){
     60                 flag[fin.x][fin.y]=1;
     61                 fin.setp=cow[num].setp+1;
     62                 fin.pre=&cow[num];
     63 
     64                 if(fin.x==D||fin.y==D){
     65                     top=1;
     66                     ans=fin.setp;
     67                     while(fin.pre){
     68                         out[top++]=fin.ou;
     69                         fin=*fin.pre;
     70                     }
     71                     return ;
     72                 }
     73                 op.push(fin);
     74             }
     75         }
     76     }
     77 }
     78 
     79 int main()
     80 {
     81     while( ~scanf("%d%d%d",&A,&B,&D)){
     82         memset( flag, 0, sizeof flag);
     83         ans=0;
     84         bfs();
     85 //        printf("%d
    ",ans);
     86         if(ans==0){
     87             printf("impossible
    ");
     88         }
     89         else{
     90             printf("%d
    ",ans);
     91             while(--top){
     92                 switch(out[top]){
     93                     case 1:printf("FILL(1)
    ");break;
     94                     case 2:printf("FILL(2)
    ");break;
     95                     case 3:printf("DROP(1)
    ");break;
     96                     case 4:printf("DROP(2)
    ");break;
     97                     case 5:printf("POUR(2,1)
    ");break;
     98                     case 6:printf("POUR(1,2)
    ");break;
     99                 }
    100             }
    101         }
    102     }
    103     return 0;
    104 }
    View Code
  • 相关阅读:
    Java中的异常处理
    Java源码阅读Vector
    Java源码中遇到的一些问题(更新中)
    Java迭代器原理
    有趣的位运算-与或非
    有趣的位运算-移位运算
    为何要使用原码, 反码和补码?
    有趣的位运算-异或
    为什么实现Serializbale接口就能够进行序列化?
    死锁,活锁,饥饿
  • 原文地址:https://www.cnblogs.com/ZQUACM-875180305/p/8856389.html
Copyright © 2011-2022 走看看