码迷,mamicode.com
首页 > 其他好文 > 详细

poj1606 poj3414

时间:2018-04-16 18:21:52      阅读:158      评论:0      收藏:0      [点我收藏+]

标签:enc   模拟   opened   possible   break   cap   sequence   pre   integer   

                    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\n",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\n",ans);
 86         if(ans==0) ;
 87         else{
 88 //            printf("%d\n",ans);
 89             while(--top){
 90                 switch(out[top]){
 91                     case 1:printf("fill A\n");break;
 92                     case 2:printf("fill B\n");break;
 93                     case 3:printf("empty A\n");break;
 94                     case 4:printf("empty B\n");break;
 95                     case 5:printf("pour B A\n");break;
 96                     case 6:printf("pour A B\n");break;
 97                 }
 98             }
 99             printf("success\n");
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\n");
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\n",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\n",ans);
 86         if(ans==0){
 87             printf("impossible\n");
 88         }
 89         else{
 90             printf("%d\n",ans);
 91             while(--top){
 92                 switch(out[top]){
 93                     case 1:printf("FILL(1)\n");break;
 94                     case 2:printf("FILL(2)\n");break;
 95                     case 3:printf("DROP(1)\n");break;
 96                     case 4:printf("DROP(2)\n");break;
 97                     case 5:printf("POUR(2,1)\n");break;
 98                     case 6:printf("POUR(1,2)\n");break;
 99                 }
100             }
101         }
102     }
103     return 0;
104 }
View Code

 

poj1606 poj3414

标签:enc   模拟   opened   possible   break   cap   sequence   pre   integer   

原文地址:https://www.cnblogs.com/ZQUACM-875180305/p/8856389.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!