• poj 1606 BFS 经典问题


    题意:倒水问题,现在有两个容积为a和b的水壶,对每个水壶可以进行4种操作,两个水壶之间相互倒水(一个水壶倒空或者一个水壶倒满为止),从水农头那里灌水(将水壶灌满为止),向外倒水(将水壶倒空为止),问对这两个水壶进行这样的一系列操作是否可以量出容积为c的水(两个杯子中有一个水壶中的水的容积恰好为c)     由于题目是"Special Judge",即答案不是唯一的,题目给出了三项假设:       1> 只有两个水壶       2> 对于每个输入,都有一个确定的输出       3> 0<c[a]<=c[b]和N<=c[b]<=1000     也就是水壶A肯定比水壶B小,水壶B肯定能装下目标水量N.     算法:仅仅是将水壶A灌满水,也只从水壶A向水壶B倒水,当水壶B灌满水时就倒空,最后的答案就是水壶B中的水量.

    这是摘录的

    这是我做的第一个BFS题,感觉其中主要是有个while循环,加上一个结构体或者一个数组当做队列,进行队列操作;

    问题的实质是(0,0)如何在指定的操作范围内到(i,n)或(n,i)


    技巧性 缩小支路 确定只要对的就行 没有要求最优解
    #include<iostream>
    #include<string>
    #include<algorithm>
    using namespace std;

    int main()
    {
    int a,b,t,n;
    while(scanf("%d%d%d",&a,&b,&n)!=EOF)
    {
    if(a==1)

    //如果水壶A的容量只有1加仑,那么直接倒水n次就可以了
    {
    for(t=1;t<=n;t++)
    {
    printf("fill A\n");
    printf("pour A B\n");
    }
    printf("success\n");
    continue;
    }
    t=0; //

    水壶B的当前水量
    while(t!=n)
    {
    printf("fill A\n");
    printf("pour A B\n"); //

    向水壶B倒水
    t+=a;
    if(t>=b) //

    如果水壶B要溢出,则倒掉一个水壶B的容量
    {
    t-=b;
    printf("empty B\n");
    printf("pour A B\n");
    }
    }
    printf("success\n");
    }
    system("pause");
    return 0;
    }




    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    using namespace std;
    #include <fstream>
    #define MAXN 105

    int a,b,n,vis[MAXN][MAXN],str[MAXN*MAXN],r,l;

    char ss[7][10]={" ","fill A","fill B","empty A","empty B","pour B A","pour A B"};

    struct action
    {
    int va;
    int vb;
    int step;
    int opr;
    int pre;
    }ac[MAXN*MAXN];

    void make(int va,int vb,int opr)
    {
    if(vis[va][vb])
    return ;
    vis[va][vb]=1;
    ac[r].va=va;
    ac[r].vb=vb;
    ac[r].step=ac[l].step+1;
    ac[r].opr=opr;
    ac[r].pre=l;
    r++;
    }

    int min(int o,int m)
    {
    return o>m?m:o;
    }

    void ouput()
    {
    int top,i;
    top=0;
    while(l!=0)
    {
    str[top++]=ac[l].opr;
    l=ac[l].pre;
    }

    for(i=top-1;i>=0;i--)
    {
    printf("%s\n",ss[str[i]]);
    }
    printf("success\n");
    }

    void bfs()
    {
    ac[0].va=0;
    ac[0].vb=0;
    ac[0].step=0;
    vis[0][0]=1;

    l=0;
    r=1;

    while(l!=r)
    {
    if(ac[l].vb==n)
    {
    ouput();
    return ;
    }

    int xa,xb,x;

    xa=a;
    xb=ac[l].vb;
    make(xa,xb,1);

    xa=ac[l].va;
    xb=b;
    make(xa,xb,2);

    xa=0;
    xb=ac[l].vb;
    make(xa,xb,3);

    xa=ac[l].va;
    xb=0;
    make(xa,xb,4);

    x=min(a-ac[l].va,ac[l].vb);
    xa=ac[l].va+x;
    xb=ac[l].vb-x;
    make(xa,xb,5);

    x=min(b-ac[l].vb,ac[l].va);
    xa=ac[l].va-x;
    xb=ac[l].vb+x;
    make(xa,xb,6);

    l++;
    }
    }

    int main()
    {
    //ifstream cin("input.txt");

    while(cin>>a>>b>>n)
    {
    memset(vis,0,sizeof(vis));
    bfs();
    }

    return 0;
    }
  • 相关阅读:
    位运算大集合
    一道百度面试题——位运算
    一道Google面试题——基数排序思想
    ubuntu12.04 安装nginx+php+mysql (lnmp)的web服务器环境
    Linux常用命令及Vim使用
    Gcc手册(转)
    C语言标准
    匈牙利游戏(次短路问题)
    高级打字机
    矩阵乘法
  • 原文地址:https://www.cnblogs.com/jackes/p/2427572.html
Copyright © 2020-2023  润新知