poj3414

来源:互联网 发布:阿里小号 知乎 编辑:程序博客网 时间:2024/06/10 06:54

题目名称: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;}


0 0
原创粉丝点击