描述
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.
输入
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).
输出
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’.
样例输入
3 5 4
样例输出
6 FILL(2) POUR(2,1) DROP(1) POUR(2,1) FILL(2) POUR(2,1)
两口锅A B,通过一系列操作,能得到C升吗?
操作有三个:注入,倒出,从一个倒入另一个,2个锅就有六种操作:注入A,注入B,倒出A,倒出B,从A倒入B,从B倒入A
开一个结构体数组,保存节点,用指针操作等等。
与迷宫问题相似。
#include<bits/stdc++.h>
using namespace std;
//开始想不出用广搜,直至突然想到用下标来表示水量
//A.B锅,以二维数组下标来表示每锅的现在容量
//状态已被存过用visited数组 用1-6表示不同的操作
//结构体数组:x,y,为每锅的现时容量;steps为步数,*p为上个节点
//操作分6种:注A满,注B满,倒出A,倒出B,从A倒入B,从B倒入A;
//我放在一个main中了,有点长。Writed by Wangzhimin Date:2023/12/24
struct pots{
int x,y;
int steps;
pots *p;
int state;//操作的6种之一
} table[100010];//存搜出的结构体
pots *head,*tail;//头和尾的指针
int shuchu[1001];//操作项1-6的保存输出
int cc=0,A,B,C;
int visited[105][105];//标志
int main()
{
scanf("%d%d%d",&A,&B,&C);
head=table;
tail=table+10;//随便指定个尾了啊
head->p=&table[0];
head->state=10;//其它头指针项为0,我就没赋值
while(head!=tail){
pots s=*head;//s好用
if(s.x==C||s.y==C)//当一个的值和C相等时,输出
{
printf("%d\n",s.steps);//步数
for(int i=s.steps;i>0;i--)//反向把状态1-6,存入shuchu中
{
//cout<<head->x<<" "<<head->y<<" "<<head->steps<<" "<<head->state<<endl;
shuchu[i]=head->state;
head=head->p;
}
for(int i=1;i<=s.steps;i++)//输出了
{
switch(shuchu[i])//每种状态输出不一样
{
case 1:{
printf("FILL(1)\n");
break;
}
case 2:{printf("FILL(2)\n");
break;
}
case 3:{printf("DROP(1)\n");
break;
}
case 4:{printf("DROP(2)\n");
break;
}
case 5:{printf("POUR(1,2)\n");
break;
}
case 6:{printf("POUR(2,1)\n");
break;
}
}
//cout<<shuchu[i]<<endl;
}
return 0;
}
else
{
if(s.x<A&&!visited[A][s.y])//先注入A A满,B不动
{
cc++;
tail=table+cc+1;
table[cc].x=A;
table[cc].y=s.y;
table[cc].steps=s.steps+1;
table[cc].p=head;
table[cc].state=1;//表示状态数
visited[A][s.y]=1;//这个!0就行,原先想用它做状态用,也作标志
}
if(s.y<B&&!visited[s.x][B])//注入B
{
cc++;
tail=table+cc+1;
table[cc].x=s.x;
table[cc].y=B;
table[cc].steps=s.steps+1;
table[cc].p=head;
table[cc].state=2;
visited[s.x][B]=2;
}
if(s.x>0&&!visited[0][s.y])//A放水
{
cc++;
tail=table+cc+1;
table[cc].x=0;
table[cc].y=s.y;
table[cc].steps=s.steps+1;
table[cc].p=head;
table[cc].state=3;
visited[0][s.y]=3;
}
if(s.y>0&&!visited[s.x][0])//B放水
{
cc++;
tail=table+cc+1;
table[cc].x=s.x;
table[cc].y=0;
table[cc].steps=s.steps+1;
table[cc].p=head;
table[cc].state=4;
visited[s.x][0]=4;
}
if(s.x<=B-s.y&&!visited[0][s.y+s.x])//从A->B ,A中没有剩余
{
cc++;
tail=table+cc+1;
table[cc].x=0;
table[cc].y=s.y+s.x;
table[cc].steps=s.steps+1;
table[cc].p=head;
table[cc].state=5;
visited[0][s.y+s.x]=5;
}
else if(s.x>B-s.y&&!visited[s.y+s.x-B][B])//从A->B ,A中有剩余
{
cc++;
tail=table+cc+1;
table[cc].x=s.y+s.x-B;
table[cc].y=B;
table[cc].steps=s.steps+1;
table[cc].p=head;
table[cc].state=5;
visited[s.y+s.x-B][B]=5;
}
if(s.y<=A-s.x&&!visited[s.x+s.y][0])//从B->A ,B中没有剩余
{
cc++;
tail=table+cc+1;
table[cc].x=s.x+s.y;
table[cc].y=0;
table[cc].steps=s.steps+1;
table[cc].p=head;
table[cc].state=6;
visited[s.x+s.y][0]=6;
}
else if(s.y>A-s.x&&!visited[A][s.x+s.y-A])//从B->A ,B中有剩余
{
cc++;
tail=table+cc+1;
table[cc].x=A;
table[cc].y=s.x+s.y-A;
table[cc].steps=s.steps+1;
table[cc].p=head;
table[cc].state=6;
visited[A][s.x+s.y-A]=6;
}
head++;//go ahead to tail
}
}
cout<<"impossible";
}
模块化概念就是不行,不愿深究。