您的位置:首页 > 其它

poj 3414 倒水问题 bfs

2015-04-29 20:34 274 查看
链接:http://poj.org/problem?id=3414

思路:就是bfs,有六种操作,FILL 1或2,DROP 1或2 ,将1倒到2,将2倒到1。要注意的是要使用标记数组vis[i][j] 表示左边的杯子为i升,右边的杯子为j升,如果已被标记说明之前已经出现这种情况,就不要入队。从(0,0)开始bfs。

因为题目中需要输出如何倒,那么就需要保存路径。。以前似乎自己还没有写过,只是知道这种思想,用一个数组记录下当前位置的前一个位置的坐标。最后通过终点找回去,找出整条路径,将路上的每个点都保存到答案数组中,(这里我是逆着保存的,也就是终点保存在最后面),最后输出的时候顺着遍历一遍答案数组,比较前后两个的情况,输出操作。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <stack>
using namespace std;
#define M 109
#define INF 0x3f3f3f3f
int vis[M][M];
int n,m,k;
int ans;
struct state
{
    int x,y;
    int step;
}cur,next1;
struct
{
    int lx,ly;
}s[M][M]; //记录路径 保存上一个点坐标
struct
{
    int a,b;
}ss[100009]; //保存答案的数组
void bfs(state temp)
{
    queue<state> q;
    temp.step = 0;
    s[temp.x][temp.y].lx = 0;
    s[temp.x][temp.y].ly = 0;
    vis[temp.x][temp.y] = 0;
    q.push(temp);
    while(!q.empty())
    {
        cur = q.front();
        vis[cur.x][cur.y] = 1;
        q.pop();
        if(cur.x==k || cur.y==k)
        {
            ans = cur.step;
            printf("%d\n",ans);
            int i = ans;
            ss[i].a = cur.x;
            ss[i--].b = cur.y;
            int xx = s[cur.x][cur.y].lx;
            int yy = s[cur.x][cur.y].ly;
            while(i!=-1)
            {
                ss[i].a = xx; //从后往前保存答案。
                ss[i--].b = yy;
                int temp1 = xx;
                int temp2 = yy;
                xx = s[temp1][temp2].lx;
                yy = s[temp1][temp2].ly;
            }
            return ;
        }
        next1.step = cur.step+1;
        if(cur.y < m) //倒满y
        {
            next1.x = cur.x;
            next1.y = m;
            if(!vis[next1.x][next1.y])
            { //要有括号。。。不然没有加入队列也保存了路径。。。
                q.push(next1);
                s[next1.x][next1.y].lx = cur.x; //只有加入队列才保存路径
                s[next1.x][next1.y].ly = cur.y;
            }
        }
        if(cur.x < n) //倒满x
        {
            next1.x = n;
            next1.y = cur.y;
            if(!vis[next1.x][next1.y])
            {
                q.push(next1);
                s[next1.x][next1.y].lx = cur.x;
                s[next1.x][next1.y].ly = cur.y;
            }
        }
        if(cur.x > 0)
        {
            next1.x = 0; //倒空x
            next1.y = cur.y;
            if(!vis[next1.x][next1.y])
            {
                q.push(next1);
                s[next1.x][next1.y].lx = cur.x;
                s[next1.x][next1.y].ly = cur.y;
            }
            if(cur.y < m) //x倒到y
            {
                if(cur.x > m-cur.y)
                {
                    next1.x = cur.x-(m-cur.y);
                    next1.y = m;
                }
                else
                {
                    next1.x = 0;
                    next1.y = cur.y+cur.x;
                }
                if(!vis[next1.x][next1.y])
                {
                    q.push(next1);
                    s[next1.x][next1.y].lx = cur.x;
                    s[next1.x][next1.y].ly = cur.y;
                }
            }
        }
        if(cur.y > 0)
        {
            next1.x = cur.x; //倒空y
            next1.y = 0;
            if(!vis[next1.x][next1.y])
            {
                q.push(next1);
                s[next1.x][next1.y].lx = cur.x;
                s[next1.x][next1.y].ly = cur.y;
            }
            if(cur.x < n)//y倒到x
            {
                if(cur.y > n-cur.x)
                {
                    next1.x = n;
                    next1.y = cur.y-(n-cur.x);
                }
                else
                {
                    next1.x = cur.x+cur.y;
                    next1.y = 0;
                }
                if(!vis[next1.x][next1.y])
                {
                    q.push(next1);
                    s[next1.x][next1.y].lx = cur.x;
                    s[next1.x][next1.y].ly = cur.y;
                }
            }
        }
    }
}
int main()
{
    while(scanf("%d %d %d",&n,&m,&k)==3)
    {
        memset(vis,0,sizeof(vis));
        memset(ss,0,sizeof(ss));
        memset(s,0,sizeof(s));
        ans = INF;
        cur.x = 0;
        cur.y = 0;
        bfs(cur);
        if(ans==INF)
            printf("impossible\n");
        else
        {
            //ss[0].a = 0;
            //ss[0].b = 0;
            for(int i = 0;i < ans;i++)
            {
                int x1 = ss[i].a;
                int y1 = ss[i].b;
                int x2 = ss[i+1].a;
                int y2 = ss[i+1].b;
                if(x1==0 && x2==n && y1==y2) printf("FILL(1)\n");  //要写清楚情况 fill的时候必须y是不变的。。
                if(y1==0 && y2==m && x1==x2) printf("FILL(2)\n");
                if(x1>0 && x2==0 && y1==y2) printf("DROP(1)\n");
                if(x2>0 && y2==0 && x1==x2) printf("DROP(2)\n");
                if(y2>y1 && x2<x1) printf("POUR(1,2)\n");
                if(x2>x1 && y2<y1) printf("POUR(2,1)\n");
            }
        }
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: