poj1606 poj3414
Posted flyer_duck
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了poj1606 poj3414相关的知识,希望对你有一定的参考价值。
Description
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
Output
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
Description
You are given two pots, having the volume of A and B liters respectively. The following operations can be performed:
- FILL(i) fill the pot i (1 ≤ i ≤ 2) from the tap;
- DROP(i) empty the pot i to the drain;
- 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 A, B, 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 }
以上是关于poj1606 poj3414的主要内容,如果未能解决你的问题,请参考以下文章