Pots POJ

来源:互联网 发布:思维导图软件 编辑:程序博客网 时间:2024/06/01 19:03






 Pots POJ - 3414

You are given two pots, having the volume of A and B liters respectively. The following operations can be performed:

  1. FILL(i)        fill the pot i (1 ≤i ≤ 2) from the tap;
  2. DROP(i)      empty the pot i to the drain;
  3. POUR(i,j)    pour from pot i to potj; after this operation either the pot j is full (and there may be some water left in the poti), or the pot i is empty (and all its contents have been moved to the potj).

Write a program to find the shortest possible sequence of these operations that will yield exactlyC liters of water in one of the pots.

Input

On the first and only line are the numbers A, B, and C. These are all integers in the range from 1 to 100 andC≤max(A,B).

Output

The first line of the output must contain the length of the sequence of operationsK. The following K lines must each describe one operation. If there are several sequences of minimal length, output any one of them. If the desired result can’t be achieved, the first and only line of the file must contain the word ‘impossible’.

Sample Input
3 5 4
Sample Output
6FILL(2)POUR(2,1)DROP(1)POUR(2,1)FILL(2)POUR(2,1)
思路:Bfs的思路很容易想到,就是路径还原的时候,用数组模拟队列比较方便,因为这样每个结构体都对应一个确定的下标,这样每个节点的标号就知道了,就可以用标号来
存父亲,最后回溯打印即可
代码:
#include <iostream>#include <cstdio>#include <cstring>using namespace std;int A,B,C;//输入数据,A,B为罐子容量,C为所要达到的值struct pot{//罐子结构体    int a,b;//当前ab罐子中的量    int step;//次数    int pre;//它的父亲节点编号    int op;//变到当前状态的操作}p,nextp,path[10000];int vis[105][105];void printPath(int x){    if(x==-1)return;//这就是为什么将第一个结构体的前驱设为-1,作为返回条件    printPath(path[x].pre);//回溯打印    switch(path[x].op){       case 0:           printf("FILL(1)\n");           break;       case 1:           printf("FILL(2)\n");           break;       case 2:           printf("DROP(1)\n");           break;       case 3:           printf("DROP(2)\n");           break;       case 4:           printf("POUR(1,2)\n");           break;       case 5:           printf("POUR(2,1)\n");           break;    }    return;}void Bfs(){    pot q[10000];//结构体数组模拟队列    int head = 0,tail = 0;    int i;    p.a = 0;    p.b = 0;    p.step = 0;    p.pre = -1;    p.op = -1;//初始化第一个点入队    vis[p.a][p.b] = 1;    q[tail++] = p;    path[head] = p;//路径保存下第零个顶点    while(head<tail){//六种操作 fill a,fill b,drop a,drop b,a->b,b->a        p = q[head];        if(p.a==C||p.b==C){            printf("%d\n",p.step);            printPath(head);//从当前这个标号开始向前寻找            return;        }        for(i = 0; i < 6; i++){            if(i==0){//fill a                nextp.a = A;                nextp.b = p.b;                nextp.step = p.step+1;                nextp.op = 0;//记录操作的编号                nextp.pre = head;//记录他的父亲状态节点编号            }            else if(i==1){//fill b                nextp.a = p.a;                nextp.b = B;                nextp.step = p.step+1;                nextp.op = 1;                nextp.pre = head;            }            else if(i==2){//drop a                nextp.a = 0;                nextp.b = p.b;                nextp.step = p.step+1;                nextp.op = 2;                nextp.pre = head;            }            else if(i==3){//drop b                nextp.a = p.a;                nextp.b = 0;                nextp.step = p.step+1;                nextp.op = 3;                nextp.pre = head;            }            else if(i==4){//a->b                if((B-p.b)>=p.a){//如果b中剩余空间大于a的量,a倒空                    nextp.a = 0;                    nextp.b = p.a+p.b;                }                else{//否则,b满,a剩余                    nextp.a = p.a-(B-p.b);                    nextp.b = B;                }                nextp.step = p.step+1;                nextp.op = 4;                nextp.pre = head;            }            else{//b->a                if((A-p.a)>=p.b){//如果a剩余空间大于b的量,b倒空                    nextp.a = p.a+p.b;                    nextp.b = 0;                }                else{//否则,a满b剩余                    nextp.a = A;                    nextp.b = p.b-(A-p.a);                }                nextp.step = p.step+1;                nextp.op = 5;                nextp.pre = head;            }            if(!vis[nextp.a][nextp.b]){                q[tail++] = nextp;                vis[nextp.a][nextp.b] = 1;                path[tail-1] = nextp;//每一个结构体在数组中的对应下标是固定了,所以可以利用这一性质记录父亲和儿子的下标关系就可以了            }        }        head++;    }    printf("impossible\n");    return;}int main(){    scanf("%d%d%d",&A,&B,&C);    memset(vis,0,sizeof(vis));    Bfs();    return 0;}


原创粉丝点击