标签:enc 模拟 opened possible break cap sequence pre integer
Description
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:
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 }
标签:enc 模拟 opened possible break cap sequence pre integer
原文地址:https://www.cnblogs.com/ZQUACM-875180305/p/8856389.html