poj3414

题目名称:Pots

题目链接:http://poj.org/problem?id=3414


题意:

给出了两个瓶子的容量A,B, 以及一个目标水量C,

对A、B可以有如下操作:

FILL(i)        将瓶 i 倒满水;

DROP(i)     将瓶 i 倒空;

POUR(i,j)   将瓶 i 的水倒到瓶 j 中,如果瓶 j 满了(或许有些水留在瓶 i ),或者瓶 i 空了,说明都倒到 j 中.

问经过哪几个操作后能使得任意一个瓶子的残余水量为C。若不可能得到则输出impossible


代码如下(直接用stl的queue):

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<string>
#include<queue>
using namespace std;
const int INF=0x3ffffff;
int A,B,C;
int ans;
bool ok,vis[105][105];
struct Last
{
    int x,y;
    int lo;
}last[105][105];   //保存上一步骤两杯的水量和操作的编号
char dir[6][10]={"FILL(1)","FILL(2)","DROP(1)","DROP(2)","POUR(1,2)","POUR(2,1)"};
struct Node
{
    int a,b;
    int sum;
};
queue<Node> q;
void print(int a,int b)
{
    if(a!=0||b!=0)
    {
        print(last[a][b].x,last[a][b].y);
        printf("%s\n",dir[last[a][b].lo]);
    }
}
void bfs(Node ss)
{
    while(!q.empty())
        q.pop();
    q.push(ss);
    while(!q.empty())
    {
        Node now=q.front();
        q.pop();
        if(now.a==C||now.b==C)
        {
            printf("%d\n",now.sum);
            print(now.a,now.b);
            return ;
        }
        Node tmp;
        //FILL(1);
        if(!vis[A][now.b])
        {
            vis[A][now.b]=true;
            tmp.a=A;
            tmp.b=now.b;
            tmp.sum=now.sum+1;
            last[A][now.b].x=now.a;
            last[A][now.b].y=now.b;
            last[A][now.b].lo=0;
            q.push(tmp);
        }
        //FILL(2)
        if(!vis[now.a][B])
        {
            vis[now.a][B]=true;
            tmp.a=now.a;
            tmp.b=B;
            tmp.sum=now.sum+1;
            last[now.a][B].x=now.a;
            last[now.a][B].y=now.b;
            last[now.a][B].lo=1;
            q.push(tmp);
        }
        //DROP(1);
        if(!vis[0][now.b])
        {
            vis[0][now.b]=true;
            tmp.a=0;
            tmp.b=now.b;
            tmp.sum=now.sum+1;
            last[0][now.b].x=now.a;
            last[0][now.b].y=now.b;
            last[0][now.b].lo=2;
            q.push(tmp);
        }
        //DROP(2)
        if(!vis[now.a][0])
        {
            vis[now.a][0]=true;
            tmp.a=now.a;
            tmp.b=0;
            tmp.sum=now.sum+1;
            last[now.a][0].x=now.a;
            last[now.a][0].y=now.b;
            last[now.a][0].lo=3;
            q.push(tmp);
        }
        //POUR(1,2)
        int w1=min(now.a,B-now.b);
        if(!vis[now.a-w1][now.b+w1])
        {
            tmp.a=now.a-w1;
            tmp.b=now.b+w1;
            tmp.sum=now.sum+1;
            last[now.a-w1][now.b+w1].x=now.a;
            last[now.a-w1][now.b+w1].y=now.b;
            last[now.a-w1][now.b+w1].lo=4;
            vis[now.a-w1][now.b+w1]=true;
            q.push(tmp);
        }
        //POUR(2,1)
        int w2=min(A-now.a,now.b);
        if(!vis[now.a+w2][now.b-w2])
        {
            tmp.a=now.a+w2;
            tmp.b=now.b-w2;
            tmp.sum=now.sum+1;
            last[now.a+w2][now.b-w2].x=now.a;
            last[now.a+w2][now.b-w2].y=now.b;
            last[now.a+w2][now.b-w2].lo=5;
            vis[now.a+w2][now.b-w2]=true;
            q.push(tmp);
        }
    }
    printf("impossible\n");
}
int main()
{
    while(scanf("%d%d%d",&A,&B,&C)!=EOF)
    {
        memset(vis,false,sizeof(vis));
        vis[0][0]=true;
        Node que;
        que.a=que.b=0;
        que.sum=0;
        bfs(que);
    }
    return 0;
}

手写queue(时间会快很多):

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int Max = 101;
struct node
{
    int ope;
    int a;
    int b;
    node* pre;
}que[Max*Max];     //队列结点,ope记录第几种操作,a,b记录此结点两个pot的水数。
bool vis[Max][Max];
char str[6][10] = {"FILL(1)", "FILL(2)", "DROP(1)", "DROP(2)", "POUR(1,2)", "POUR(2,1)"};
void print(node now)
{
    if(now.pre!=NULL)
    {
        print(*now.pre);
        cout<<str[now.ope]<<endl;
    }
}
void bfs(int a,int b,int c)   //手写queue
{
    int steps=0;
    int head=0,tail=1;      //队列的开始和结尾
    que[0].a=que[0].b=0;
    que[0].pre=NULL;
    while(tail-head>0)
    {
        int count=tail-head;
        while(count--)
        {
            node now=que[head];
            if(now.a==c||now.b==c)
            {
                cout<<steps<<endl;
                print(now);
                return;
            }
            //FILL(1);
            if(!vis[a][now.b])
            {
                que[tail].ope = 0;
                que[tail].a = a;
                que[tail].b = now.b;
                que[tail].pre = &que[head];
                vis[a][now.b] = true;
                tail ++;
            }
            //FILL(2)
            if(!vis[now.a][b])
            {
                que[tail].ope = 1;
                que[tail].a = now.a;
                que[tail].b = b;
                que[tail].pre = &que[head];
                vis[now.a][b] = true;
                tail ++;
            }
            //DROP(1);
            if(!vis[0][now.b])
            {
                que[tail].ope = 2;
                que[tail].a = 0;
                que[tail].b = now.b;
                que[tail].pre = &que[head];
                vis[0][now.b] = true;
                tail ++;
            }
            //DROP(2)
           if(!vis[now.a][0])
           {
                que[tail].ope = 3;
                que[tail].a = now.a;
                que[tail].b = 0;
                que[tail].pre = &que[head];
                vis[now.a][0] = true;
                tail ++;
            }
            //POUR(1,2)
            int wat1 = min(now.a, b - now.b);
            if(!vis[now.a - wat1][now.b + wat1])
            {
                que[tail].ope = 4;
                que[tail].a = now.a - wat1;
                que[tail].b = now.b + wat1;
                que[tail].pre = &que[head];
                vis[now.a - wat1][now.b + wat1] = true;
                tail ++;
            }
            //POUR(2,1)
            int wat2 = min(a - now.a, now.b);
            if(!vis[now.a + wat2][now.b - wat2])
            {
                que[tail].ope = 5;
                que[tail].a = now.a + wat2;
                que[tail].b = now.b - wat2;
                que[tail].pre = &que[head];
                vis[now.a + wat2][now.b - wat2] = true;
                tail ++;
            }
            head++;
        }
        steps++;
    }
    cout<<"impossible"<<endl;
}
int main()
{
    int a,b,c;
    cin>>a>>b>>c;
    memset(vis,false,sizeof(vis));
    vis[0][0]=true;
    bfs(a,b,c);
    return 0;
}


posted @ 2015-07-22 16:37  maplefighting  阅读(151)  评论(0编辑  收藏  举报