Pots
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) Source
Northeastern Europe 2002, Western Subregion
|
提示
题意:
你有两个罐子,它们的容积为A和B,并遵循以下操作:
1.FILL(i) 给罐子i倒满水。
2.DROP(i) 把罐子i的水倒出来。
3.POUR(i,j) 把罐子i的水给罐子j,如果j的容积不够就倒满为止。
给出一个数C,求能不能让其中一个罐子中水的体积为C,能就输出最少步数以及操作过程,不能输出“impossible”。
思路:
在队列里需要增加对上一次状态的储存,要注意判断两个罐子相互倒水会不会溢出。
示例程序
Source Code
Problem: 3414 Code Length: 2873B
Memory: 424K Time: 32MS
Language: GCC Result: Accepted
Source Code
#include <stdio.h>
#include <string.h>
struct
{
int x,y,step,p; //x为第一个罐子的水量,y为第二个,p储存上一次状态的数组下标
char op[10]; //储存操作
}q[8000];
int bfs(int a,int b,int c)
{
int v[101][101],x1,y1,f=0,top=0;
memset(v,0,sizeof(v));
q[top].x=0;
q[top].y=0;
q[top].step=0;
q[top].p=-1;
v[a][b]=1;
top++;
while(f<top)
{
x1=q[f].x;
y1=q[f].y;
if(x1==c||y1==c)
{
return f;
}
if(v[0][y1]==0)
{
q[top].x=0;
q[top].y=y1;
q[top].step=q[f].step+1;
q[top].p=f; //存下上一次的状态的数组下标
strcpy(q[top].op,"DROP(1)");
top++;
v[0][y1]=1;
}
if(v[x1][0]==0)
{
q[top].x=x1;
q[top].y=0;
q[top].step=q[f].step+1;
q[top].p=f;
strcpy(q[top].op,"DROP(2)");
top++;
v[x1][0]=1;
}
if(v[a][y1]==0)
{
q[top].x=a;
q[top].y=y1;
q[top].step=q[f].step+1;
q[top].p=f;
strcpy(q[top].op,"FILL(1)");
v[a][y1]=1;
top++;
}
if(v[x1][b]==0)
{
q[top].x=x1;
q[top].y=b;
q[top].step=q[f].step+1;
q[top].p=f;
strcpy(q[top].op,"FILL(2)");
v[x1][b]=1;
top++;
}
if(x1+y1<=a&&v[x1+y1][0]==0) //需要对是否会溢出做一下判断
{
q[top].x=x1+y1;
q[top].y=0;
q[top].step=q[f].step+1;
q[top].p=f;
strcpy(q[top].op,"POUR(2,1)");
v[x1+y1][0]=1;
top++;
}
else if(x1+y1>a&&v[a][x1+y1-a]==0)
{
q[top].x=a;
q[top].y=x1+y1-a;
q[top].step=q[f].step+1;
q[top].p=f;
strcpy(q[top].op,"POUR(2,1)");
v[a][x1+y1-a]=1;
top++;
}
if(x1+y1<=b&&v[0][x1+y1]==0)
{
q[top].x=0;
q[top].y=x1+y1;
q[top].step=q[f].step+1;
q[top].p=f;
strcpy(q[top].op,"POUR(1,2)");
v[0][x1+y1]=1;
top++;
}
else if(x1+y1>b&&v[x1+y1-b][b]==0)
{
q[top].x=x1+y1-b;
q[top].y=b;
q[top].step=q[f].step+1;
q[top].p=f;
strcpy(q[top].op,"POUR(1,2)");
v[x1+y1-b][b]=1;
top++;
}
f++;
}
return -1;
}
int main()
{
int a,b,c,t,top=0,ans[8000];
scanf("%d %d %d",&a,&b,&c);
t=bfs(a,b,c);
if(t!=-1)
{
printf("%d\n",q[t].step);
while(t>=1)
{
ans[top]=t;
t=q[t].p;
top++;
}
for(t=top-1;t>=0;t--) //操作顺序是反的,我们要把它倒过来
{
printf("%s\n",q[ans[t]].op);
}
}
else
{
printf("impossible");
}
return 0;
}