倒水问题
问题描述
有两个无刻度标志的水壶,分别可装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!");
}