啦啦啦,这个太刷成就感了!!!!115行代码哦
poj 3414原题戳这
大致题意:
给你容器a,容器b,还有容量c;
问你是否能够通过有限的步骤达到c的目标状态呢?
嗯,关于path数组其实又参看大神的,不得不说太腻害了
操作6种:
1.装满a FILL(1)
2.装满b FILL(2)
3.清空a DROP(1)
4.清空b DROP(2)
5.把A倒入B POUR(1,2) (注意不能溢出o
就有2种情况,装得满和装不满;
6.把b装进a同上
算法:bfs,加数组??
ps and耐心,也就是你要有写完题的耐心和改错的耐心【哭
下面是codes
poj 3414
228k 0ms
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
int m,n,k;
int vis[105][105];
char opr[20][20]= {"FILL(1)" , "FILL(2)" , "DROP(1)" , "DROP(2)" , "POUR(1,2)" , "POUR(2,1)" }; //共6种操作
struct node
{
int x,y,step;// 当前水量和步数
int path[200]; //用来记录路径的数组 //!!
};
void bfs( )
{
int i,j;
int kx,ky;
memset(vis,0,sizeof(vis));
queue<node>q;
node now,next;//当前操作和下步操作
now.x=0;
now.y=0;
now.step=0;
q.push(now);
vis[0][0]=1;
while(!q.empty())
{
now=q.front();
q.pop();
if(now.x==k||now.y==k)//达到目标状态
{
printf("%d\n",now.step);
for( i=1; i<=now.step; i++)
{
printf("%s\n",opr[now.path[i]]);
}
return;
}
for(i=1; i<=6; i++) // 共六种操作
{
if(i == 1 ) //第一种操作,装满1;
{
next.y=now.y;
next.x=m;
now.path[now.step+1]=0;
}
else if(i == 2)//sec,fill 2
{
next.x=now.x;
next.y=n;
now.path[now.step+1]=1;
}
else if(i == 3)//third,drop 1;
{
next.y=now.y;
next.x=0;
now.path[now.step+1]=2;
}
else if(i == 4)// fourth,drop 2
{
next.x=now.x;
next.y=0;
now.path[now.step+1]=3;
}
else if(i == 5)
{
if(n-now.y>now.x) //每种pour 应有两种情况
{
next.x=0;
next.y=now.x+now.y;
}
else
{
next.y=n;
next.x=now.x-n+now.y;
}
now.path[now.step+1]=4;
}
else if(i == 6)
{
if(m-now.x>now.y)//装不满
{
next.y=0;
next.x=now.x+now.y;
}
else//装得满
{
next.x=m;//最多m
next.y=now.y-m+now.x;
}
now.path[now.step+1]=5;
}
if(vis[next.x][next.y] == 1)
continue;
vis[next.x][next.y]=1;
next.step=now.step+1;
for(j=1; j<=next.step; j++) //!!!!!!记录之前的operation,在这傻了很久
{
next.path[j]=now.path[j];
}
q.push(next);
}
}
printf("impossible\n");
return;
}
int main()
{
int i;
scanf("%d%d%d",&m,&n,&k);
bfs();
return 0;
}
本文介绍了一道经典的水壶问题(POJ3414),利用广度优先搜索(BFS)算法解决该问题,并详细展示了如何通过不同操作步骤从初始状态到达目标状态的过程。
548

被折叠的 条评论
为什么被折叠?



