Time Limit: 1000MS | Memory Limit: 65536K | |||
Total Submissions: 8253 | Accepted: 3499 | Special Judge |
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)
Source
算法:數組模擬bfs
題意:
思路:
code:
#include<stdio.h>
#include<string.h>
const int maxn = 110;
int vis[maxn][maxn]; //標記狀態是否入隊過
int a,b,c; //容器大小
int step; //最終的步數
int flag; //紀錄是否能夠成功
/* 狀態紀錄 */
struct Status{
int k1,k2; //當前水的狀態
int op; //當前操作
int step; //紀錄步數
int pre; //紀錄前一步的下標
}q[maxn*maxn];
int id[maxn*maxn]; //紀錄最終操作在隊列中的編號
int lastIndex; //最後一個的編號
void bfs()
{
Status now, next;
int head, tail;
head = tail = 0;
q[tail].k1 = 0; q[tail].k2 = 0;
q[tail].op = 0; q[tail].step = 0; q[tail].pre = 0;
tail++;
memset(vis,0,sizeof(vis));
vis[0][0] = 1; //標記初始狀態已入隊
while(head < tail) //當隊列非空
{
now = q[head]; //取出隊首
head++; //彈出隊首
if(now.k1 == c || now.k2 == c) //應該不會存在這樣的情況, c=0
{
flag = 1;
step = now.step;
lastIndex = head-1; //紀錄最後一步的編號
}
for(int i = 1; i <= 6; i++) //分別遍歷 6 種情況
{
if(i == 1) //fill(1)
{
next.k1 = a;
next.k2 = now.k2;
}
else if(i == 2) //fill(2)
{
next.k1 = now.k1;
next.k2 = b;
}
else if(i == 3) //drop(1)
{
next.k1 = 0;
next.k2 = now.k2;
}
else if(i == 4) // drop(2);
{
next.k1 = now.k1;
next.k2 = 0;
}
else if(i == 5) //pour(1,2)
{
if(now.k1+now.k2 <= b) //如果不能夠裝滿 b
{
next.k1 = 0;
next.k2 = now.k1+now.k2;
}
else //如果能夠裝滿 b
{
next.k1 = now.k1+now.k2-b;
next.k2 = b;
}
}
else if(i == 6) // pour(2,1)
{
if(now.k1+now.k2 <= a) //如果不能夠裝滿 a
{
next.k1 = now.k1+now.k2;
next.k2 = 0;
}
else //如果能夠裝滿 b
{
next.k1 = a;
next.k2 = now.k1+now.k2-a;
}
}
next.op = i; //紀錄操作
if(!vis[next.k1][next.k2]) //如果當前狀態沒有入隊過
{
vis[next.k1][next.k2] = 1; //標記當前狀態入隊
next.step = now.step+1; //步數 +1
next.pre = head-1; //紀錄前一步的編號
//q.push(next);
//q[tail] = next; 加入隊尾
q[tail].k1 = next.k1; q[tail].k2 = next.k2;
q[tail].op = next.op; q[tail].step = next.step; q[tail].pre = next.pre;
tail++; //隊尾延長
if(next.k1 == c || next.k2 == c) //如果達到目標狀態
{
flag = 1; //標記成功
step = next.step; //紀錄總步驟數
lastIndex = tail-1; //紀錄最後一步在模擬數組中的編號
return;
}
}
}
}
}
int main()
{
while(scanf("%d%d%d", &a,&b,&c) != EOF)
{
flag = 0; //初始化不能成功
step = 0;
bfs();
if(flag)
{
printf("%d\n", step);
id[step] = lastIndex; //最後一步在模擬數組中的編號
for(int i = step-1; i >= 1; i--)
{
id[i] = q[id[i+1]].pre; //向前找前一步驟在模擬數組中的編號
}
for(int i = 1; i <= step; i++)
{
if(q[id[i]].op == 1)
printf("FILL(1)\n");
else if(q[id[i]].op == 2)
printf("FILL(2)\n");
else if(q[id[i]].op == 3)
printf("DROP(1)\n");
else if(q[id[i]].op == 4)
printf("DROP(2)\n");
else if(q[id[i]].op == 5)
printf("POUR(1,2)\n");
else if(q[id[i]].op == 6)
printf("POUR(2,1)\n");
}
}
else printf("impossible\n");
}
return 0;
}