• poj1066 Jugs


    poj1066 Jugs

    http://poj.org/problem?id=1606


    解题思路:本题可以用数学方法解得,最易理解,常规的解法是搜索。直接用接近模拟的广度优先搜索即可过。


    给两个容器,给出最大容量(ca,cb)和目标水量n,可以执行6种操作:

    (1)把A容器灌满水,操作名:fill A;

    (2)把B容器灌满水,操作名:fill B;

    (3)把A容器中的水倒出去,管它倒到哪里去,反正不在这两个容器里面,操作名:empty A;

    (4)把B容器中的水倒出去,操作名:empty B;

    (5)把A容器中的水倒到B容器中去,要是B容器装不下A容器中的水,则把B容器倒满,剩下的水留在A容器中,操作名:pour A B;

    (6)把B容器中得水倒到A容器中去,,操作名:pour B A ;

    要求最后留在B容器中的水量为n。

    按操作的顺序输出操作名,使B容器中的水量为n。


    直接用广度优先搜索即可,只是搜索时的搜索树,不是经典地图搜索中的四个方向,而是6种操作方法。

    (1)定义ca,cb,n,分别用于A容器,B容器的最大装水量和目的水量;定义一个二维数组flag[1002][1002],用于存储A容器B容器装的水的量用于搜索是的状态判重,定义一个串数组存储6种操作名,用于后面输出操作名;定义一个结构体,内涵a,b,s,分别表示A容器,B容器上次操作后的装水量,和以前所处理的操作的操作名在用于输出的操作名的数组中的下标。

    (2)对于每组测试案例,直接输入三个值,直到文件结束,程序终止。

    (3)对于每组测试数据,进行广度优先搜索,每次搜索都分成6种操作方法对两个容器中的水量进行处理,当B容器中的水量为n时停止搜索,按照当前处理的状态结构体中的S串输出操作顺序的操作名即可。

    (4)别忘了在每组数据最后输出“success”。

    由于是用广度优先搜索算法进行搜索的,故搜索到的操作次数必是最小的,无需再判断次数。

    注:本题是特殊对比方式判正误,即使样例输入得到的的答案和样例输出的内容有所不用也不要紧,只要后面B容器中得水的量是n的即可。


    12052890 20114045007 1606 Accepted 4100K 16MS C++ 1883B 2013-08-29 19:47:08
    #include<stdio.h>
    #include<iostream>
    #include<string.h>
    #include<string>
    #include<queue>
    using namespace std;
    int ca,cb,n;
    int flag[1002][1002];   //状态标记,用于判重
    string out[]={"fill A","fill B","empty A","empty B","pour A B","pour B A"};   //6个操作名
    struct node
    {
        int a;
        int b;
        string s;
    };
    void bfs()
    {
        memset(flag,0,sizeof(flag));
        node now,next;
        queue<node> q;
        now.a=0;
        now.b=0;
        flag[0][0]=1;
        q.push(now);
        while(!q.empty())
        {
            now=q.front();
            q.pop();
            if(now.b==n)  //B容器中得水量为n时,搜索成功
           {
                for(int i=0;i<now.s.size();i++)
                    cout<<out[now.s[i]-'0']<<endl;
                return;
            }
            //fill A
            next.a=ca;
            next.b=now.b;
            next.s=now.s+'0';
            if(!flag[next.a][next.b])flag[next.a][next.b]=1,q.push(next);
            next.a=now.a;
            next.b=cb;
            next.s=now.s+'1';
            if(!flag[next.a][next.b])flag[next.a][next.b]=1,q.push(next);
            //empty A
            next.a=0;
            next.b=now.b;
            next.s=now.s+'2';
            if(!flag[next.a][next.b])flag[next.a][next.b]=1,q.push(next);
            //empty B
            next.a=now.a;
            next.b=0;
            next.s=now.s+'3';
            if(!flag[next.a][next.b])flag[next.a][next.b]=1,q.push(next);
            //pour A B
            if(cb-now.b>=now.a)next.a=0,next.b=now.b+now.a;   //若B容器中还可装入的水量大于等于A容器中当前水量,则把A容器中的水全部倒入B容器中
            else next.a=now.a-cb+now.b,next.b=cb;  //否则,把B容器倒满,剩下的水留在A容器中
            next.s=now.s+'4';
            if(!flag[next.a][next.b])flag[next.a][next.b]=1,q.push(next);
            // pour B A
            if(ca-now.a>=now.b)next.b=0,next.a=now.a+now.b;   //同上
            else next.b=now.b-ca+now.a,next.a=ca;
            next.s=now.s+'5';
            if(!flag[next.a][next.b])flag[next.a][next.b]=1,q.push(next);
        }
    }
    int main()
    {
        while(scanf("%d%d%d",&ca,&cb,&n)!=EOF)
        {
            bfs();
            printf("success
    ");
        }
        return 0;
    }





  • 相关阅读:
    MyBatis动态SQL语句
    MyBatis分页
    理解 Linux 的处理器负载均值
    Linux命令之du
    Linux命令之df
    Linux命令之lsof
    maven打包加时间戳
    多线程学习-ListenableFuture使用介绍以及示例
    Host is not allowed to connect to this MySQL server解决方法
    Dapper,大规模分布式系统的跟踪系统
  • 原文地址:https://www.cnblogs.com/pangblog/p/3292285.html
Copyright © 2020-2023  润新知