zoukankan      html  css  js  c++  java
  • HDU 1495 非常可乐

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=1495

    大意:有三个杯子,开始时第一个杯子装满水(体积为a)。。。。倒来倒去,得到其中2个杯里的水的体积都为

    a/2。。。。求最小次数。。。。不存在就输出NO。。。。

    从图(以前都是图题)的点转化成状态(这题比较现实化)。。。。

    struct point//a,b,c是某一状态下三个杯里装的水的体积。。。。v是从开始到该状态倒了多少次。。。。

    {

      int a, b, c, v;

    };

    在任意状态下(即每次的队头)。。。。都有6种倒法(即遍历6种)a->b,c。。。

    b->a,c。。。。c->a,b。。。。。

    #include <iostream>
    #include <cmath>
    #include <queue>
    using namespace std;

    const int INF = 1<<30;

    bool vis[111][111][111];

    struct point
    {
    int a, b, c, v;
    };


    void Bfs(int a, int b, int c)
    {
    point q1, q2;
    queue <point> q;
    q1.a = a;
    q1.b = 0;//初始状态是0,而不是b
    q1.c = 0;
    q1.v = 0;
    q.push(q1);
    memset(vis, 0, sizeof(vis));


    while (!q.empty())
    {
    q2 = q.front();
    q.pop();
    vis[q2.a][q2.b][q2.c] = 1;

    //有2个等于a/2就结束
    if ((q2.a == a/2 && q2.b == a/2) ||(q2.a == a/2 && q2.c == a/2) ||(q2.b == a/2 && q2.c == a/2))
    {
    printf("%d\n", q2.v);
    return ;
    }

    //a到其他
    if (q2.a != 0)
    {
    //a->b
    if (q2.a > b - q2.b)//倒不完
    {
    q1.a = q2.a - (b-q2.b);
    q1.b = b;
    q1.c = q2.c;
    q1.v = q2.v + 1;

    }
    else//倒完
    {

    q1.b = q2.b + q2.a;//后面是q2.a而不是q1.a
    q1.a = 0;
    q1.c = q2.c;
    q1.v = q2.v + 1;
    }
    if (!vis[q1.a][q1.b][q1.c])
    {
    q.push(q1);
    vis[q1.a][q1.b][q1.c] = 1;
    }


    //a->c
    if (q2.a > c - q2.c)//倒不完///b
    {
    q1.a = q2.a - (c-q2.c);
    q1.c = c;
    q1.b = q2.b;
    q1.v = q2.v + 1;
    }
    else//倒完
    {

    q1.c = q2.c + q2.a;
    q1.a = 0;
    q1.b = q2.b;
    q1.v = q2.v + 1;
    }
    if (!vis[q1.a][q1.b][q1.c])
    {
    q.push(q1);
    vis[q1.a][q1.b][q1.c] = 1;
    }


    }

    //b到其他
    if (q2.b != 0)
    {
    //b->a
    if (q2.b > a - q2.a)//倒不完
    {
    q1.b = q2.b - (a-q2.a);
    q1.a = a;
    q1.c = q2.c;
    q1.v = q2.v + 1;

    }
    else//倒完
    {

    q1.a = q2.a + q2.b;
    q1.b = 0;
    q1.c = q2.c;
    q1.v = q2.v + 1;
    }
    if (!vis[q1.a][q1.b][q1.c])
    {
    q.push(q1);
    vis[q1.a][q1.b][q1.c] = 1;
    }

    //b->c
    if (q2.b > c - q2.c)//倒不完//a
    {
    q1.b = q2.b - (c-q2.c);
    q1.c = c;
    q1.a = q2.a;
    q1.v = q2.v + 1;

    }
    else//倒完
    {

    q1.c = q2.c + q2.b;
    q1.b = 0;
    q1.a = q2.a;
    q1.v = q2.v + 1;

    }
    if (!vis[q1.a][q1.b][q1.c])
    {
    q.push(q1);
    vis[q1.a][q1.b][q1.c] = 1;
    }
    }

    //c到其他
    if (q2.c != 0)
    {
    //c->b
    if (q2.c > b - q2.b)//倒不完
    {
    q1.c = q2.c - (b-q2.b);
    q1.b = b;
    q1.a = q2.a;
    q1.v = q2.v + 1;
    if (!vis[q1.a][q1.b][q1.c])
    {
    q.push(q1);
    vis[q1.a][q1.b][q1.c] = 1;
    }
    }
    else//倒完
    {

    q1.b = q2.b + q2.c;
    q1.c = 0;
    q1.a = q2.a;
    q1.v = q2.v + 1;
    if (!vis[q1.a][q1.b][q1.c])
    {
    q.push(q1);
    vis[q1.a][q1.b][q1.c] = 1;
    }
    }

    //c->a
    if (q2.c > a - q2.a)//倒不完
    {
    q1.c = q2.c - (a-q2.a);
    q1.a = a;
    q1.b = q2.b;
    q1.v = q2.v + 1;
    if (!vis[q1.a][q1.b][q1.c])
    {
    q.push(q1);
    vis[q1.a][q1.b][q1.c] = 1;
    }
    }
    else//倒完
    {

    q1.a = q2.a + q2.c;
    q1.c = 0;
    q1.b = q2.b;
    q1.v = q2.v + 1;
    if (!vis[q1.a][q1.b][q1.c])
    {
    q.push(q1);
    vis[q1.a][q1.b][q1.c] = 1;
    }
    }
    }

    }
    puts("NO");
    return ;
    }

    int main()
    {
    int t;
    int n;
    int i, j;
    int a, b, c;
    while (scanf("%d%d%d", &a, &b, &c), a+b+c)
    {
    if (a % 2 == 1)//剪枝
    {
    puts("NO");
    }
    else
    {
    Bfs(a, b, c);
    }
    }
    return 0;
    }
  • 相关阅读:
    WPF 基础
    设计模式
    设计模式
    设计模式
    设计模式
    设计模式
    设计模式
    【DFS】hdu 1584 蜘蛛牌
    【优先队列】hdu 1434 幸福列车
    【最长公共子序列】hdu 1243 反恐训练营
  • 原文地址:https://www.cnblogs.com/qiufeihai/p/2431998.html
Copyright © 2011-2022 走看看