2014_3_29_周赛 倒水

题目描述

两个容量分别为 a 和 b 的容器,通过三种操作,直到某一容器装有体积为 c 的水,同时另一容器为空,使倒水次数最少。初始时容器皆空。三种操作分别为:把某容器全倒到下水道;把某容器用水龙头接满;从甲容器向乙容器倒水直到甲空或乙满。
输入格式

每组数据包含三个整数 a, b, c。输入以 EOF 结束
输出

对于每组数据:若有解则输出最少的倒水次数;若无解则输出 No solution!。
样例输入

7 10 4
58 1 3
44 9 4
3 8 10
样例输出

5
6
47
No solution!
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <iostream>
#include <queue>
#include <algorithm>

using namespace std;
typedef struct node {
    int x, y, step;
} node;

bool vis[1000][1000];
int a, b, c;

int bfs() {
    memset(vis, 0, sizeof (vis));
    queue<node> q;
    node h, n;
    h.x = 0;
    h.y = 0;
    h.step = 0;
    q.push(h);
    while (!q.empty()) {
        h = q.front();
        q.pop();
        if (h.x == c && h.y == 0)
            return h.step;
        if (h.y == c && h.x == 0)
            return h.step;
        if (h.x < a) {
            n.x = a;
            n.y = h.y;
            n.step = h.step + 1;
            if (!vis[n.x][n.y]) {
                q.push(n);
                vis[n.x][n.y] = true;
            }
        }
        if (h.x > 0) {
            n.x = 0;
            n.y = h.y;
            n.step = h.step + 1;
            if (!vis[n.x][n.y]) {
                q.push(n);
                vis[n.x][n.y] = true;
            }
        }
        if (h.y < b) {
            n.x = h.x;
            n.y = b;
            n.step = h.step + 1;
            if (!vis[n.x][n.y]) {
                q.push(n);
                vis[n.x][n.y] = true;
            }
        }
        if (h.y > 0) {
            n.x = h.x;
            n.y = 0;
            n.step = h.step + 1;
            if (!vis[n.x][n.y]) {
                q.push(n);
                vis[n.x][n.y] = true;
            }
        }
        if (h.y <= a - h.x) {
            n.x = h.x + h.y;
            n.y = 0;
            n.step = h.step + 1;
            if (!vis[n.x][n.y]) {
                q.push(n);
                vis[n.x][n.y] = true;
            }
        }
        if (h.y > a - h.x) {
            n.x = a;
            n.y = h.y + h.x - a;
            n.step = h.step + 1;
            if (!vis[n.x][n.y]) {
                q.push(n);
                vis[n.x][n.y] = true;
            }
        }
        if (h.x <= b - h.y) {
            n.x = 0;
            n.y = h.x + h.y;
            n.step = h.step + 1;
            if (!vis[n.x][n.y]) {
                q.push(n);
                vis[n.x][n.y] = true;
            }
        }
        if (h.x > b - h.y) {
            n.x = h.x + h.y - b;
            n.y = b;
            n.step = h.step + 1;
            if (!vis[n.x][n.y]) {
                q.push(n);
                vis[n.x][n.y] = true;
            }
        }
    }
    return -1;
}

int main() {
    while (scanf("%d%d%d", &a, &b, &c) == 3) {
        if (c > max(a, b)) {
            printf("No solution!\n");
            continue;
        }
        int ans = bfs();
        if (ans == -1) {
            printf("No solution!\n");
            continue;
        }
        else
            printf("%d\n", ans);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值