倒水问题

倒水问题

问题描述

有两个无刻度标志的水壶,分别可装x升和y升(x、y为整数,且x、y<=100)的水。设另有一水缸(有无限水,也可以装无限水),可用来向水壶灌水或者倒出水,两水壶间,水可以相互倾灌。已知x升水壶开始时满壶,y升壶为空壶,问通过倒水或者灌水操作,最少用多少步才能在y升壶中量出z(z<=100)升水来

输入

输入文件为一行,分别表示x、y、z的值

输出

输出文件为一行,即为最少的步数,如果无法达到目标,则输出”No solution!”

样例输入

8 5 3

样例输出

3

题目解读

bfs板子题,状态设为x升壶和y升壶当前里面有多少水就好,每次将多种状态压入队列即可

code

#include <bits/stdc++.h>

using namespace std;

inline int read() {
    int x = 0 , f = 1; char ch = getchar();
    for ( ; !isdigit(ch) ; ch = getchar()) if (ch == '-') f = -1;
    for ( ; isdigit(ch) ; ch = getchar()) x = x * 10 + ch - '0';
    return x * f;
}

const int maxn = 101;

struct data {
    int x , y , step;
}_begin;

int maxX , maxY , aim;

queue <data> Q;

bool vis[maxn][maxn];

int main() {
    maxX = read() , maxY = read() , aim = read();
    if (maxX < aim) {
        puts("No solution!");
        exit(0);
    }
    _begin.step = 0 , _begin.x = maxX;
    vis[maxX][0] = true;
    Q.push(_begin);

    while (Q.size()) {
        data now = Q.front(); Q.pop();

        if (now.y == aim) {
            printf("%d\n" , now.step);
            exit(0);
        }

        else {
            if (now.x && !vis[0][now.y]) {
                Q.push({0 , now.y , now.step + 1});
                vis[0][now.y] = true;
            }
            if (now.y && !vis[now.x][0]) {
                Q.push({now.x , 0 , now.step + 1});
                vis[now.x][0] = true;
            }
            //quan dao diao

            if (now.x < maxX && !vis[maxX][now.y]) {
                Q.push({maxX , now.y , now.step + 1});
                vis[maxX][now.y] = true;
            }
            if (now.y < maxY && !vis[now.x][maxY]) {
                Q.push({now.x , maxY , now.step + 1});
                vis[now.x][maxY] = true;
            }
            //quan dao man

            if (now.x + now.y <= maxY && !vis[0][now.x + now.y]) {
                Q.push({0 , now.x + now.y , now.step + 1});
                vis[0][now.x + now.y] = true;
            }
            if (now.x + now.y > maxY && !vis[now.x + now.y - maxY][maxY]) {
                Q.push({now.x + now.y - maxY , maxY , now.step + 1});
                vis[now.x + now.y - maxY][maxY] = true;
            }
            if (now.x + now.y <= maxX && !vis[now.x + now.y][0]) {
                Q.push({now.x + now.y , 0 , now.step + 1});
                vis[now.x + now.y][0] = true;
            }
            if (now.x + now.y > maxX && !vis[maxX][now.x + now.y - maxX]) {
                Q.push({maxX , now.x + now.y - maxX , now.step + 1});
                vis[maxX][now.x + now.y - maxX] = true;
            }
            //hu xiang dao
        }
    }

    puts("No solution!");
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值