POJ3414 Pots【BFS】
Pots
Time Limit: 1000MS | Memory Limit: 65536K | |||
Total Submissions: 23177 | Accepted: 9827 | 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
Northeastern Europe 2002, Western Subregion
題目連結:POJ3414 Pots
問題描述:給你兩個空壺,容量分別為A,B。定義3中操作,FILL(i)表示把壺i裝滿,DROP(i)表示把壺清空,POUR(i,j)表示把壺i中的水倒入j中,直到i變空,或者j變滿。問經過若干步操作後,是否能使得其中一個壺的容量為C,如果可以則列印步數和相應步驟,否則輸出“impossible”
題解:初始狀態為把壺a裝滿或者把壺b裝滿,然後對每個狀態進行6中操作:裝滿壺a,轉滿壺b,清空壺a,清空壺b,壺a倒入壺b,壺b倒入壺a,詳情如下
AC的C++程式:
#include<iostream>
#include<queue>
#include<string>
#include<cstring>
#define MIN(x,y) x<y?x:y
using namespace std;
const int N=500;
struct Node{
int a,b,pre,id;
string s;
}st[2*N];
int A,B,C;
bool vis[N][N];
int bfs()
{
memset(vis,false,sizeof(vis));
queue<Node>q;
//初始有兩個狀態,要麼把a裝滿,要麼把b裝滿
st[0].a=A,st[0].b=0,st[0].pre=-1,st[0].id=0,st[0].s="FILL(1)";
st[1].a=0,st[1].b=B,st[1].pre=-1,st[1].id=1,st[1].s="FILL(2)";
q.push(st[0]);
q.push(st[1]);
vis[A][0]=vis[0][B]=true;
int k=2;
while(!q.empty()){
Node f=q.front();
q.pop();
if(f.a==C||f.b==C)//如果轉換成功,返回此狀態的編號
return f.id;
//FILL操作
Node e=f;
if(e.a!=A&&!vis[A][e.b]){
e.a=A,e.id=k,e.pre=f.id,e.s="FILL(1)";
st[k++]=e;
vis[A][e.b]=true;
q.push(e);
}
e=f;
if(e.b!=B&&!vis[e.a][B]){
e.b=B,e.id=k,e.pre=f.id,e.s="FILL(2)";
st[k++]=e;
vis[e.a][B]=true;
q.push(e);
}
//DROP操作
e=f;
if(e.a!=0&&!vis[0][e.b]){
e.a=0,e.id=k,e.pre=f.id,e.s="DROP(1)";
st[k++]=e;
vis[0][e.b]=true;
q.push(e);
}
e=f;
if(e.b!=0&&!vis[e.a][0]){
e.b=0,e.id=k,e.pre=f.id,e.s="DROP(2)";
st[k++]=e;
vis[e.a][0]=true;
q.push(e);
}
//POUR操作
e=f;
if(e.a!=0){
int d=MIN(e.a,B-e.b);//a向b中倒水的最大量
if(!vis[e.a-d][e.b+d]){
vis[e.a-d][e.b+d]=true;
e.a-=d,e.b+=d,e.pre=f.id,e.id=k,e.s="POUR(1,2)";
st[k++]=e;
q.push(e);
}
}
e=f;
if(e.b!=0){
int d=MIN(A-e.a,e.b);//b向a中倒水的最大量
if(!vis[e.a+d][e.b-d]){
vis[e.a+d][e.b-d]=true;
e.a+=d,e.b-=d,e.pre=f.id,e.id=k,e.s="POUR(2,1)";
st[k++]=e;
q.push(e);
}
}
}
return -1; //表示不能成功
}
void print(int i)
{
if(st[i].pre!=-1)
print(st[i].pre);
cout<<st[i].s<<endl;
}
int main()
{
scanf("%d%d%d",&A,&B,&C);
if(C==0){
printf("0\n");
return 0;
}
int id=bfs();//終止狀態id
if(id==-1){
printf("impossible\n");
return 0;
}
int cnt=1,i=id;
while(st[i].pre!=-1){
i=st[i].pre;
cnt++;
}
printf("%d\n",cnt);
print(id);
return 0;
}
相關文章
- 【BFS】poj 3414 Pots
- Pots(POJ - 3414)【BFS 尋找最短路+路徑輸出】
- POJ 3414 Pots
- POJ3414-Pots
- bfs
- BFS(模板)
- Pots POJ – 3414 (搜尋+記錄路徑)
- 01BFS
- Count BFS Graph
- poj 3278 BFS
- DAG bfs + dfs 126,
- BFS入門筆記筆記
- BFS和Dijkstra結合
- 找朋友(bfs常錯!!)
- 【BFS】腐爛的橘子
- BFS/acm習題集ACM
- UVA11624 Fire!【BFS】
- BFS演算法原理演算法
- 藍橋杯-長草(BFS)
- C++演算法——BFSC++演算法
- HDU2612 Find a way【BFS】
- 藍橋杯-走迷宮(BFS)
- [LeetCode] 最短的橋 雙BFS JavaLeetCodeJava
- 聊聊演算法——BFS和DFS演算法
- Gym - 101875L PC is for kicking【bfs】
- bfs廣度優先搜尋
- cf1072D. Minimum path(BFS)
- HDU1495 非常可樂【BFS】
- 求樹的直徑(BFS/DFS)
- P1032 字串變換(bfs)字串
- 藍橋杯-迷宮(BFS+DFS)
- 【ybtoj】【BFS】【例題1】走迷宮
- FZU2150 Fire Game【BFS+暴力】GAM
- POJ3984 迷宮問題【BFS】
- cf1064D. Labyrinth(01BFS)
- nyoj - 1154. 找食物(簡單BFS)
- Cow Marathon(BFS求數的直徑)
- L2-006 樹的遍歷(BFS)