1. 程式人生 > >bfs+模擬(poj3414 pots倒水問題)

bfs+模擬(poj3414 pots倒水問題)

Pots
Time Limit: 1000MSMemory Limit: 65536K
Total Submissions: 21047Accepted: 8976Special Judge

Description

You are given two pots, having the volume of A and B liters respectively. The following operations can be performed:

  1. FILL(i)        fill the pot i (1 ≤ ≤ 2) from the tap;
  2. DROP(i)      empty the pot i to the drain;
  3. 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 AB, 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)

思路:

總狀態只有那麼多, 每一步後都只有 6 種操作明顯的 BFS 關鍵是每一步路徑的記錄。注意到 A 和 B 的範圍是 1 到 100 的整數,那麼我們可以用vis[i][j]來記錄每一種狀態 0 <= i, j <= 100 ; i 表示目前 A 容器中的水, j 表示目前 B 容器中的水應該很容易就能分析出,對應於每一種狀態的下一步只有六種情況:一:用水池中的水裝滿 A二:用水池中的水裝滿 B三:把 A 中的水全部倒進廢水池四:把 B 中的水全部倒進廢水池五:把 A 中的水倒進 B 【不能溢位】    那麼對應可能會有兩種狀態:用 a 表示 A 中的水, b 表示 B 中的水    如果 a+b <= B 則   B = a+b ; A = 0 【不能夠裝滿容器 B】注意順序    否則 A = a+b-B; B = B 【能夠裝滿容器 B】六:把 B 中的水倒進 A 【不能溢位】    也有兩種情況,分析同上    如果 a+b <= A 則 A = a+b ; B = 0;    否則 B = a+b-A ; A = A
#include<iostream>
#include<queue>
#include<cstring>
using namespace std;
struct pot
{
	int a,b;
	int op[10000],cnt;//op[i]表示此次如何操作 ,cnt表示操作總數 
};
bool flag;
bool vis[105][105];
void bfs(pot start,int a,int b,int c)
{
	queue<pot> q;
	q.push(start);
	while(!q.empty())
	{
		pot cur=q.front();
		q.pop();
		//cout<<cur.a<<cur.b<<endl;
		if(cur.a==c||cur.b==c)
		{
			cout<<cur.cnt<<endl;
			for(int i=0;i<cur.cnt;i++)
			{
				if(cur.op[i]==11) cout<<"FILL(1)"<<endl;
				if(cur.op[i]==12) cout<<"FILL(2)"<<endl;
				if(cur.op[i]==21) cout<<"DROP(1)"<<endl;
				if(cur.op[i]==22) cout<<"DROP(2)"<<endl;
				if(cur.op[i]==312) cout<<"POUR(1,2)"<<endl;
				if(cur.op[i]==321) cout<<"POUR(2,1)"<<endl;
			}
			flag=true;
			return ;
		}
		pot next;
		next=cur;
		if(next.a!=a)
		{
			next.a=a;
			next.op[next.cnt++]=11;
			if(!vis[next.a][next.b])
			{
				vis[next.a][next.b]=true;
				q.push(next);
			}
		}
		next=cur;
		if(next.b!=b)
		{
			next.b=b;
			next.op[next.cnt++]=12;
			if(!vis[next.a][next.b])
			{
				vis[next.a][next.b]=true;
				q.push(next);
			}
		}
		next=cur;
		if(next.a!=0)
		{
			next.a=0;
			next.op[next.cnt++]=21;
			if(!vis[next.a][next.b])
			{
				vis[next.a][next.b]=true;
				q.push(next);
			}
		}
		next=cur;
		if(next.b!=0)
		{
			next.b=0;
			next.op[next.cnt++]=22;
			if(!vis[next.a][next.b])
			{
				vis[next.a][next.b]=true;
				q.push(next);
			}
		}
		next=cur;
		if(next.a+next.b>b)
		{
			next.a=next.a+next.b-b;
			next.b=b;
		}
		else
		{
			next.b=next.b+next.a;
			next.a=0;
		}
		next.op[next.cnt++]=312;
		if(!vis[next.a][next.b])
		{
			vis[next.a][next.b]=true;
			q.push(next);
		}
		next=cur;
		if(next.a+next.b>a)
		{
			next.b=next.a+next.b-a;
			next.a=a;
		}
		else
		{
			next.a=next.a+next.b;
			next.b=0;
		}
		next.op[next.cnt++]=321;
		if(!vis[next.a][next.b])
		{
			vis[next.a][next.b]=true;
			q.push(next);
		}
	}
}
int main()
{
	int a,b,c;
	while(cin>>a>>b>>c)
	{
		flag=false;
		pot start;
		memset(vis,false,sizeof(vis));
		start.a=0;start.b=0;start.cnt=0;
		bfs(start,a,b,c);
		if(!flag) cout<<"impossible"<<endl;
	}
	return 0;
}