poj 1606 BFS 经典问题

题意:倒水问题,现在有两个容积为a和b的水壶,对每个水壶可以进行4种操作,两个水壶之间相互倒水(一个水壶倒空或者一个水壶倒满为止),从水农头那里灌水(将水壶灌满为止),向外倒水(将水壶倒空为止),问对这两个水壶进行这样的一系列操作是否可以量出容积为c的水(两个杯子中有一个水壶中的水的容积恰好为c)     由于题目是"Special Judge",即答案不是唯一的,题目给出了三项假设:       1> 只有两个水壶       2> 对于每个输入,都有一个确定的输出       3> 0<c[a]<=c[b]和N<=c[b]<=1000     也就是水壶A肯定比水壶B小,水壶B肯定能装下目标水量N.     算法:仅仅是将水壶A灌满水,也只从水壶A向水壶B倒水,当水壶B灌满水时就倒空,最后的答案就是水壶B中的水量.

这是摘录的

这是我做的第一个BFS题,感觉其中主要是有个while循环,加上一个结构体或者一个数组当做队列,进行队列操作;

问题的实质是(0,0)如何在指定的操作范围内到(i,n)或(n,i)


技巧性 缩小支路 确定只要对的就行 没有要求最优解
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;

int main()
{
int a,b,t,n;
while(scanf("%d%d%d",&a,&b,&n)!=EOF)
{
if(a==1)

//如果水壶A的容量只有1加仑,那么直接倒水n次就可以了
{
for(t=1;t<=n;t++)
{
printf("fill A\n");
printf("pour A B\n");
}
printf("success\n");
continue;
}
t=0; //

水壶B的当前水量
while(t!=n)
{
printf("fill A\n");
printf("pour A B\n"); //

向水壶B倒水
t+=a;
if(t>=b) //

如果水壶B要溢出,则倒掉一个水壶B的容量
{
t-=b;
printf("empty B\n");
printf("pour A B\n");
}
}
printf("success\n");
}
system("pause");
return 0;
}




#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std;
#include <fstream>
#define MAXN 105

int a,b,n,vis[MAXN][MAXN],str[MAXN*MAXN],r,l;

char ss[7][10]={" ","fill A","fill B","empty A","empty B","pour B A","pour A B"};

struct action
{
int va;
int vb;
int step;
int opr;
int pre;
}ac[MAXN*MAXN];

void make(int va,int vb,int opr)
{
if(vis[va][vb])
return ;
vis[va][vb]=1;
ac[r].va=va;
ac[r].vb=vb;
ac[r].step=ac[l].step+1;
ac[r].opr=opr;
ac[r].pre=l;
r++;
}

int min(int o,int m)
{
return o>m?m:o;
}

void ouput()
{
int top,i;
top=0;
while(l!=0)
{
str[top++]=ac[l].opr;
l=ac[l].pre;
}

for(i=top-1;i>=0;i--)
{
printf("%s\n",ss[str[i]]);
}
printf("success\n");
}

void bfs()
{
ac[0].va=0;
ac[0].vb=0;
ac[0].step=0;
vis[0][0]=1;

l=0;
r=1;

while(l!=r)
{
if(ac[l].vb==n)
{
ouput();
return ;
}

int xa,xb,x;

xa=a;
xb=ac[l].vb;
make(xa,xb,1);

xa=ac[l].va;
xb=b;
make(xa,xb,2);

xa=0;
xb=ac[l].vb;
make(xa,xb,3);

xa=ac[l].va;
xb=0;
make(xa,xb,4);

x=min(a-ac[l].va,ac[l].vb);
xa=ac[l].va+x;
xb=ac[l].vb-x;
make(xa,xb,5);

x=min(b-ac[l].vb,ac[l].va);
xa=ac[l].va-x;
xb=ac[l].vb+x;
make(xa,xb,6);

l++;
}
}

int main()
{
//ifstream cin("input.txt");

while(cin>>a>>b>>n)
{
memset(vis,0,sizeof(vis));
bfs();
}

return 0;
}

 

posted @ 2012-03-31 20:13  shijiwomen  阅读(754)  评论(0编辑  收藏  举报