• HDU1495 非常可乐(BFS)


      刚拿到这题时很纠结,没有思路。后来想了一天,问了问高手终于把思路整理出来。

    思路:三个瓶子,无非就是6种倒法,按杯子体积从大到小定义为s, m, n。则6种倒法分别是:s -> m, s -> n, m -> n, m -> s,  n -> m, n -> s;

    加一个标记变量,标记当前状态已经出现过。将没出现过的状态入队列,剩下的就是bfs的事了。。。

    My Code:

    #include <iostream>
    #include
    <cstdio>
    #include
    <cstring>

    using namespace std;
    const int N = 100000;
    struct coco
    {
    int s;
    int m;
    int n;
    int step;
    }q[N];

    int s, m, n;
    int vis[101][101];

    int bfs()
    {
    coco p, t;
    int cnt, r = 0, f = 0;
    q[
    0].s = s;
    q[
    0].m = 0;
    q[
    0].n = 0;
    q[
    0].step = 0;
    vis[m][n]
    = 1;
    r
    ++;
    while(f < r)
    {
    p
    = q[f++];
    cnt
    = 0;
    if(p.s == s/2) cnt++;
    if(p.m == s/2) cnt++;
    if(p.n == s/2) cnt++;
    if(cnt == 2) //satisfied the term
    return p.step;
    if(p.s)
    {
    t
    = p;
    if(t.m < m) //s -> m
    {
    if(t.m + t.s > m)
    {
    t.s
    -= (m-t.m);
    t.m
    = m;
    }
    else
    {
    t.m
    += t.s;
    t.s
    = 0;
    }
    t.step
    ++;
    if(!vis[p.m][p.n])
    {
    vis[p.m][p.n]
    = 1;
    q[r
    ++] = t;
    }
    }
    t
    = p;
    if(t.n < n) //s -> n
    {
    if(t.n + t.s > n)
    {
    t.s
    -= (n-t.n);
    t.n
    = n;
    }
    else
    {
    t.m
    += t.s;
    t.s
    = 0;
    }
    t.step
    ++;
    if(!vis[t.m][t.n])
    {
    vis[t.m][t.n]
    = 1;
    q[r
    ++] = t;
    }
    }
    }
    if(p.m)
    {
    t
    = p; //m -> n
    if(t.n < n)
    {
    if(t.n + t.m > n)
    {
    t.m
    -= (n-t.n);
    t.n
    = n;
    }
    else
    {
    t.n
    += t.m;
    t.m
    = 0;
    }
    t.step
    ++;
    if(!vis[t.m][t.n])
    {
    vis[t.m][t.n]
    = 1;
    q[r
    ++] = t;
    }
    }

    t
    = p; // m -> s
    t.s += t.m;
    t.m
    = 0;
    t.step
    ++;
    if(!vis[t.m][t.n])
    {
    vis[t.m][t.n]
    = 1;
    q[r
    ++] = t;
    }
    }
    if(p.n)
    {
    t
    = p; // n -> m
    if(t.n + t.m > m)
    {
    t.n
    -= (m - t.m);
    t.m
    = m;
    }
    else
    {
    t.m
    += t.n;
    t.n
    = 0;
    }
    t.step
    ++;
    if(!vis[t.m][t.n])
    {
    vis[t.m][t.n]
    = 1;
    q[r
    ++] = t;
    }

    t
    = p; //n -> s
    t.s += t.n;
    t.n
    = 0;
    t.step
    ++;
    if(!vis[t.m][t.n])
    {
    vis[t.m][t.n]
    = 1;
    q[r
    ++] = t;
    }
    }
    }
    return 0;
    }

    int main()
    {
    //freopen("data.in", "r", stdin);

    int ans;
    while(scanf("%d%d%d", &s, &n, &m), s||n||m)
    {
    memset(vis,
    0, sizeof(vis));
    if(m > n)
    {
    m
    = m+n;
    n
    = m-n;
    m
    = m-n;
    }
    if(s&1) //if 's' is odd
    {
    printf(
    "NO\n");
    continue;
    }
    ans
    = bfs();
    if(ans)
    printf(
    "%d\n", ans);
    else
    printf(
    "NO\n");
    }
    return 0;
    }
  • 相关阅读:
    P1908 逆序对
    P3834 【模板】可持久化线段树 1(主席树)
    BZOJ 4300: 绝世好题
    Codevs 2185【模板】最长公共上升子序列
    P1439 【模板】最长公共子序列
    P3865 【模板】ST表
    【转】良心的可持久化线段树教程
    Codevs 1299 切水果
    P3388 【模板】割点(割顶)&& 桥
    P3805 【模板】manacher算法
  • 原文地址:https://www.cnblogs.com/vongang/p/2164372.html
Copyright © 2020-2023  润新知