题目:http://poj.org/problem?id=3414
题意:给你a,b,c三个容积的杯子,问通过a,b(不使用c)什么操作能够得到c升的水。包括6中操作。
想法:bfs,六个状态。关键是要回溯步骤,用栈来保存,正好倒序输出。
代码
#include<iostream>
#include<queue>
#include<stack>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
struct Node{
int x,y;
int meth;
int step;
};
Node node[105][105];
queue<int>t,s;
stack <int> pre;
bool vis[105][105];
int a,b,c;
int main(){
while(~scanf("%d%d%d",&a,&b,&c)){
memset(node,-1,sizeof(node));
while(!t.empty()) t.pop();
while(!s.empty()) s.pop();
t.push(0),s.push(0);
node[0][0].step=0;
while(!t.empty()){
int ex=s.front();
int ey=t.front();
if(ex==c||ey==c) break;
s.pop(),t.pop();
int num=node[ex][ey].step;
if(node[a][ey].step==-1){
node[a][ey].meth=1;
node[a][ey].x=ex;
node[a][ey].y=ey;
node[a][ey].step=num+1;
s.push(a),t.push(ey);
}
if(node[ex][b].step==-1){
node[ex][b].meth=2;
node[ex][b].x=ex;
node[ex][b].y=ey;
node[ex][b].step=num+1;
s.push(ex),t.push(b);
}
if(node[0][ey].step==-1){
node[0][ey].meth=3;
node[0][ey].x=ex;
node[0][ey].y=ey;
node[0][ey].step=num+1;
s.push(0),t.push(ey);
}
if(node[ex][0].step==-1){
node[ex][0].meth=4;
node[ex][0].x=ex;
node[ex][0].y=ey;
node[ex][0].step=num+1;
s.push(ex),t.push(0);
}
int tx=max(ex+ey-b,0);
int ty=min(b,ex+ey);
if(node[tx][ty].step==-1){
node[tx][ty].meth=5;
node[tx][ty].x=ex;
node[tx][ty].y=ey;
node[tx][ty].step=num+1;
s.push(tx),t.push(ty);
}
tx=min(a,ex+ey);
ty=max(0,ex+ey-a);
if(node[tx][ty].step==-1){
node[tx][ty].meth=6;
node[tx][ty].x=ex;
node[tx][ty].y=ey;
node[tx][ty].step=num+1;
s.push(tx),t.push(ty);
}
}
if(s.empty())
cout<<"impossible"<<endl;
else{
while(!pre.empty()) pre.pop();
int px=s.front();
int py=t.front();
cout<<node[px][py].step<<endl;
while(node[px][py].meth!=-1){
pre.push(node[px][py].meth);
int bx=node[px][py].x;
int by=node[px][py].y;
px=bx,py=by;
}
while(!pre.empty()){
int m=pre.top();
pre.pop();
switch(m){
case 1:cout<<"FILL(1)"<<endl;break;
case 2:cout<<"FILL(2)"<<endl;break;
case 3:cout<<"DROP(1)"<<endl;break;
case 4:cout<<"DROP(2)"<<endl;break;
case 5:cout<<"POUR(1,2)"<<endl;break;
case 6:cout<<"POUR(2,1)"<<endl;break;
}
}
}
}
return 0;
}