POJ 3414 Pots 記錄路徑的搜尋
阿新 • • 發佈:2019-02-19
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
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
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)
題目大意:兩個水壺,給出各自容量,開始都沒有水,問經過如上幾種操作後,如何能在最少操作下到達其中一個水壺中的水為c升。並輸出該操作過程。
題目難點在於如何儲存路徑,這裡的路徑不單單是常數,而是一個操作。
這裡採用map<data,data> 把後一個點指向前一個點,類似一棵樹的多個分支,最後可以通過不斷往回找 可以到達最初的點
即 初始狀態。
注意:map 用到結構體時候 需要自定義 比較 bool operator < (DataType data) const
#include<iostream>
#include<stdio.h>
#include<vector>
#include<map>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<set>
#include<cmath>
#include<queue>
using namespace std;
int a,b,c;
struct Pot{
int a,b;
string s;
//必須 指定 結構體的 大小比較 map 需要
bool operator < (Pot o)const {
if(a != o.a)
return a < o.a;
else
return b < o.b;
}
};
map<Pot,Pot> mp;
void bfs(int s_a, int s_b){
Pot pot,tmp;
queue<Pot> q;
tmp.b = tmp.a = -1;
pot.a = s_a; pot.b = s_b;
mp[pot] = tmp;
q.push(pot);
while(!q.empty()){
pot = q.front();
q.pop();
if(pot.a == c || pot.b == c){
break;
}
// fill a
tmp.a = a; tmp.b = pot.b;tmp.s = "FILL(1)";
if(mp.find(tmp) == mp.end())
mp[tmp] = pot,q.push(tmp);
//fill b
tmp.a = pot.a; tmp.b = b; tmp.s = "FILL(2)";
if(mp.find(tmp) == mp.end())
mp[tmp] = pot,q.push(tmp);
// drop a
tmp.a = 0; tmp.b = pot.b; tmp.s ="DROP(1)";
if(mp.find(tmp) == mp.end())
mp[tmp] = pot,q.push(tmp);
// drop b
tmp.a = pot.a; tmp.b = 0; tmp.s = "DROP(2)";
if(mp.find(tmp) == mp.end())
mp[tmp] = pot,q.push(tmp);
//pour a to b
tmp.a = max(0,pot.a+pot.b-b);
tmp.b = min(pot.a+pot.b,b);
tmp.s = "POUR(1,2)";
if(mp.find(tmp) == mp.end())
mp[tmp] = pot,q.push(tmp);
// pour b to a
tmp.a = min(a,pot.a+pot.b);
tmp.b = max(0,pot.a+pot.b-a);
tmp.s = "POUR(2,1)";
if(mp.find(tmp) == mp.end())
mp[tmp] = pot,q.push(tmp);
}
if(pot.a == c || pot.b == c){
int step = 0;
string ans = "";
// p.a == 0 && p.b == 0 時候則為初始狀態 結束
for(Pot p = pot; p.a || p.b; p = mp[p]){
++step;
ans = p.s + "\n" + ans;
}
cout << step << endl;
cout << ans <<endl;
return ;
}
cout << "impossible" << endl;
return;
}
int main()
{
ios::sync_with_stdio(false);
cin >> a >> b >> c;
bfs(0,0);
return 0;
}