题目链接:http://poj.org/problem?id=3414
题目大意:有A,B容量的两个杯子,然后有六种操作,分别是:
"FILL(1)";//将杯子1装满
"FILL(2)";//将杯子2装满
"DROP(1)";//将杯子1中的水全部倒掉
"DROP(2)";//将杯子2中的水全部倒掉
"POUR(1,2)";//将杯子1中的水倒入2中
"POUR(2,1)";//将杯子2中的水倒入1中
(倾倒水的时候如果能倒完就倒完,如果倒不完,就剩在原来杯子里)
问:是否有一系列操作使得任意一个杯子中出现水量为C的水。
题解:
首先想到用BFS嘛,每种状态可向下继续走的有六种操作。如果没有操作的记录的话就没那么麻烦,就直接常规的做就好了。但是有了要记录操作的记录,所以我们要处理一下这个嘛。
主要就是将所有放入队列的结构体编号,然后记录下当前编号和上一步操作的编号以便于我们最后的输出。然后就做就好了。
还有一个就是map输出要用cout,第一次用map,其实也不必要用map的,但是因为刚接触了然后就想试试,然后就用了。
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <queue>
#include <math.h>
#include <string.h>
#include <string>
#include <vector>
#include <set>
#include <stack>
#include <map>
#define INF 0x3f3f3f3f
const int MAX=0x3f3f3f3f;
using namespace std;
typedef long long ll;
map<int,string> path;
int A,B,C;
struct node{
int x,y;//当前水量;
int op;//具体的操作
int s;//路径长度
int now;//当前的编号
int pre;//前一个步骤的编号
}tt[1000];//用来存所有放入过队列的结构体编号
int flag=0;
int id[1000];//用来存最优系列操作的编号
int endid;//用来记录最后一个操作的编号
int mp[1000][1000];//看这个状态是否走过
int bfs(int ex,int ey)
{
memset(mp,false,sizeof(mp));
tt[0].x=ex;
tt[0].y=ey;
tt[0].s=0;
tt[0].now=0;
tt[0].pre=0;
queue<node>q;
q.push(tt[0]);
mp[q.front().x][q.front().y]=1;
flag++;
while(!q.empty())
{
node temp;
for(int i=1;i<=6;i++)
{
switch (i) {
case 1://将第一个杯子装满
{
temp.x = A;
temp.y = q.front().y;
goto loop;
}
case 2://将第二个杯子装满
{
temp.y = B;
temp.x = q.front().x;
goto loop;
}
case 3://将第一个杯子清空
{
temp.x = 0;
temp.y = q.front().y;
goto loop;
}
case 4://将第二个杯子清空
{
temp.y = 0;
temp.x = q.front().x;
goto loop;
}
case 5://将第一个杯子的水倒入第二个杯子
{
//如果可以把第二个杯子倒满
if (q.front().x >= (B - q.front().y)) {
temp.x = q.front().x - (B - q.front().y);
temp.y = B;
}
//如果不能把第二个杯子倒满
if (q.front().x < (B - q.front().y)) {
temp.y = q.front().y + q.front().x;
temp.x = 0;
}
goto loop;
}
case 6://将第二个杯子的水倒入第一个杯子
{
//如果可以把第一个杯子倒满
if (q.front().y >= (A - q.front().x)) {
temp.y = q.front().y - (A - q.front().x);
temp.x = A;
}
//如果不能把第二个杯子倒满
if (q.front().y < (A - q.front().x)) {
temp.x = q.front().y + q.front().x;
temp.y = 0;
}
goto loop;
}
}
loop:
if(mp[temp.x][temp.y]==1)
continue;
temp.op=i;
temp.s=q.front().s+1;
temp.now=flag;
temp.pre=q.front().now;
q.push(temp);
tt[flag]=temp;
flag++;
mp[temp.x][temp.y]=1;
if(temp.x==C||temp.y==C)
{
endid=temp.now;
return temp.s;
}
}
q.pop();
}
return 0;
}
int main()
{
path[1]="FILL(1)";
path[2]="FILL(2)";
path[3]="DROP(1)";
path[4]="DROP(2)";
path[5]="POUR(1,2)";
path[6]="POUR(2,1)";
while(~scanf("%d%d%d",&A,&B,&C))
{
int ans=bfs(0,0);
if(ans==0)
printf("impossible\n");
else
{
printf("%d\n",ans);
id[ans]=endid;
for(int i=ans-1;i>=1;i--)
{
id[i]=tt[id[i+1]].pre;
}
for(int i=1;i<=ans;i++)
{
cout<<path[tt[id[i]].op]<<endl;
}
}
}
return 0;
}
(一个月了,首发题,寒假懒死了……想哭)