您的位置:首页 > 其它

ACM pku 3414 Pots 关于bfs的一个好题

2008-11-04 11:45 363 查看
题目给出了两个水桶A,B,以及一个数C,其中A和B分别代表它们的容量,对
它们可以有如下操作:
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).
问桶里的水经过哪几个操作后能够达到C的容量。
这个题目可以用bfs把它做出来,对于两个桶的每一种状态,我们都可对它进行
六种操作,即FILL(1),FILL(2),DROP(1),DROP(2),POUR(1,2),POUR(2,1),
我们可以把它的每一种状态记录下来,一层一层的往下扩展,直到找到我们要
找的容量为止。不过这里有一个麻烦,就是要你输出得到容量C的过程。所以
对于每一个结点,我们都得对它设置一个pre指针,使它指向其父结点,等到
我们找到正确的结果之后,再沿着其父结点返回来找那条正确的路径。
具体代码如下:
#include <iostream>
#include <stack>
#define Len 10000
//#include <queue>

using namespace std;

struct Pot
{
int x,y,step;
int flag;
};
struct Node
{
Pot data;
struct Node *pre;
};
int A,B,C;
Node *an[Len];
Node nd[Len];
int num;
bool visit[110][110];
int head,tail;
stack<int> T;

int bfs(int x,int y)
{
Node *s,*t,*cur;
head = tail = 0;
num = 0;
cur = new Node;
cur->data.x = x;
cur->data.y = y;
cur->data.flag = 0;
cur->data.step = 0;
cur->pre = NULL;
an[head] = cur;
tail++;
visit[x][y] = true;
while(head != tail)
{
s = an[head++];
bool f;
for(int i=1;i<=6;++i)
{
f = false;
switch(i)
{
case 1:
nd[num].data.x = A;
nd[num].data.y = s->data.y;
nd[num].data.flag = 1;

break;
case 2:
nd[num].data.y = B;
nd[num].data.x = s->data.x;
nd[num].data.flag = 2;
break;
case 3:nd[num].data.x = 0;
nd[num].data.y = s->data.y;
nd[num].data.flag = 3;
break;
case 4:
nd[num].data.x = s->data.x;
nd[num].data.y = 0;
nd[num].data.flag = 4;
break;
case 5:
if(s->data.x + s->data.y > B)
{
nd[num].data.x = s->data.x+s->data.y-B;
nd[num].data.y = B;
nd[num].data.flag = 5;
}
else{
nd[num].data.x = 0;
nd[num].data.y = s->data.x+s->data.y;
nd[num].data.flag = 5;
}
break;
case 6:
if(s->data.x+s->data.y > A)
{
nd[num].data.x = A;
nd[num].data.y = s->data.x+s->data.y-A;
nd[num].data.flag = 6;
}
else{
nd[num].data.x = s->data.x+s->data.y;
nd[num].data.y = 0;
nd[num].data.flag = 6;
}
break;
}
nd[num].data.step = s->data.step+1;
if(!visit[nd[num].data.x][nd[num].data.y])
{
visit[nd[num].data.x][nd[num].data.y] = true;
nd[num].pre = s;
if(nd[num].data.x == C || nd[num].data.y == C)
{
Node *p = &nd[num];
while(p)
{
T.push(p->data.flag);
p = p->pre;
}
return nd[num].data.step;
}
else an[tail++] = &nd[num++];
}
}
}
printf("impossible/n");
}
void input()
{
cin>>A>>B>>C;
for(int i=0;i<=A;++i)
for(int j=0;j<=B;++j)
visit[i][j] = false;
if(C == 0) cout<<"0"<<endl;
else
cout<<bfs(0,0)<<endl;
int tag;
while(!T.empty())
{
tag = T.top();
T.pop();
switch(tag)
{
case 0:break;
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;
}
}
}
int main()
{
input();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: