Pots-BFS

Pots
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 14034 Accepted: 5909 Special Judge

Description

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 ≤ ≤ 2) from the tap;
  2. DROP(i)      empty the pot i to the drain;
  3. POUR(i,j)    pour from pot i to pot j; after this operation either the pot j is full (and there may be some water left in the pot i), or the pot i is empty (and all its contents have been moved to the pot j).

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

Input

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

Output

The first line of the output must contain the length of the sequence of operations K. 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

6
FILL(2)
POUR(2,1)
DROP(1)
POUR(2,1)
FILL(2)
POUR(2,1)

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

整整研究了我一上午,昨天看到这个题,第一反应,我见过,再一反应,扩欧!简单啊,直接就上了数论,然后。。。就没有然后了,一个小时后,终于忍不住再去看了看我当初看的这个数论,结果上面清楚的印着几个大写的汉字,“有一种解法为”,我!@#¥%……&好吧,我承认错了,乖乖的去搜索,然后,就发现了一件事,搜索,这个题,我好像不会啊TAT,然后就比较尴尬了,哎,代码写到一半写不下去了,去网上看了一下大牛们的博客,好吧,我还是渣。。。


看了博客后,豁然开朗,思路很简单,就是运用BFS的思想,没有必要那么刻板的去用BFS,只是运用思想就可以,这个题的数据范围不大,用数组模拟队列,使当前状态的下一状态(全部情况)放入队列,记得注意标记好状态,避免重复,在结构体中记录操作编号和上一步的下标,然后就可以愉快的敲代码了-_-|

代码如下:
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
//这里char没有string好用
string op[7]={"","FILL(1)","FILL(2)","DROP(1)","DROP(2)","POUR(2,1)","POUR(1,2)"};
int l,r;//队列的头尾
int a,b,c;
int vis[200][200],step[50000];//标记数组,操作数组
struct node
{
    int x;//第一个杯子里的水量
    int y;//第二个杯子里的水量
    int opter;//操作编号
    int pre;//上一步的下标
}xin[100000];
void solve(int x,int y,int opter)
{
    if(vis[x][y])
        return ;
    vis[x][y]=1;//改变此种情况时的状态
    xin[r].x=x;
    xin[r].y=y;
    xin[r].opter=opter;//记录操作编号
    xin[r].pre=l;//记录上一步的下标
    r++;//进队列
}
int print()
{
    int ans=0;
    while(l!=0)
    {
        step[ans++]=xin[l].opter;//记录操作编号
        l=xin[l].pre;//递归思想
    }
    printf("%d\n",ans);//操作数
    for(int i=ans-1;i>=0;i--)
    {
        cout<<op[step[i]]<<endl;//操作
    }
    return 0;
}
int bfs()
{
    memset(vis,0,sizeof(vis));
    xin[0].x=0;//初始化两个杯子都是空的状态
    xin[0].y=0;
    vis[0][0]=1;
    l=0;
    r=1;//进队列
    int tx;//临时水量
    int ty;
    while(l!=r)
    {
        if(xin[l].x==c||xin[l].y==c)//结束的条件,恰好量出需要的水量
        {
            print();
            break;
        }
        tx=a;
        ty=xin[l].y;
        solve(tx,ty,1);//第一种情况,倒满第一杯

        tx=xin[l].x;
        ty=b;
        solve(tx,ty,2);//第二种情况,倒满第二杯

        tx=0;
        ty=xin[l].y;
        solve(tx,ty,3);//第三种情况,清空第一杯

        tx=xin[l].x;
        ty=0;
        solve(tx,ty,4);//第四种情况,清空第二杯

        tx=xin[l].x+min(a-xin[l].x,xin[l].y);
        ty=xin[l].y-min(a-xin[l].x,xin[l].y);
        solve(tx,ty,5);//第五种情况,把第二杯倒入第一杯

        tx=xin[l].x-min(b-xin[l].y,xin[l].x);
        ty=xin[l].y+min(b-xin[l].y,xin[l].x);
        solve(tx,ty,6);//第六种情况,把第一杯倒入第二杯

        l++;
    }
    if(l>=r)//不能恰好量出需要的水量
        printf("impossible\n");
    return 0;
}
int main()
{
    while(~scanf("%d",&a))
    {
        scanf("%d",&b);
        scanf("%d",&c);
        bfs();
    }
    return 0;
}


路还很长啊。。。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值