原文链接: 分油
上一篇: hdu2612 Find a way
xmy开车
发布时间: 2017年6月26日 10:45 最后更新: 2017年6月29日 10:20 时间限制: 1000ms 内存限制: 128M
描述
某天xmy与他的朋友开车去兜风,为了炫富,他们2个人开了2辆车,然而不幸得是,他们的车同时没有了油,但此时每辆车想要到加油站还需要S/2升的油量,现在有一个好心人路过,给了他们3个容器:一个为S升(里面包含S升的汽油),一个为N升,一个为M升(这两个都是空的,且3个容器都没有刻度)。其中S=N+M,现在问你,能否通过它们3个之间相互倒的方式,来使得汽油均分(这样xmy和他的朋友就可以一起到加油站啦!)。
如果能的话,输出最少需要倒的次数,不能的话输出"NO"。这对于xmy来说太Naive啦,但是他想考考你~
输入
三个整数 : S , N 和 M是两个杯子的容量(全部不超过100),以"0 0 0"结束。
输出
如果能平分的话请输出最少要倒的次数,否则输出"NO"。
样例输入1 复制
7 4 3 4 1 3 0 0 0
样例输出1
NO 3
#include <iostream>
#include <cstdio>
#include <queue>
#include <set>
using namespace std;
int S, N, M;
struct Node {
int s, n, m, step;
Node() {}
Node(int s, int n, int m, int step) :s(s), n(n), m(m), step(step) {}
friend int operator <(const Node& a, const Node& b) {
if (a.s != b.s) return a.s < b.s;
if (a.n != b.n) return a.n < b.n;
if (a.m != b.m) return a.m < b.m;
return 0;
}
};
int main(int argc, char *argv[]) {
while (scanf("%d%d%d", &S, &N, &M) == 3 && (S || N || M)) {
Node start(S, 0, 0, 0);
queue<Node> q;
set<Node> vis;
q.push(start);
vis.insert(start);
bool flag = 0;
if (S % 2 == 1 || (N >= S && M >= S)) {
printf("NO\n");
continue;
}
while (!q.empty()) {
Node t = q.front();
q.pop();
if ((t.s == S / 2 && t.n == S / 2) ||
(t.s == S / 2 && t.m == S / 2) ||
(t.n == S / 2 && t.m == S / 2)) {
flag = 1;
printf("%d\n", t.step);
break;
}
Node next;
//s-->n
if (t.s > 0 && t.n < N) {
if (t.s >= N - t.n) {
next.s = t.s - (N - t.n);
next.n = N;
next.m = t.m;
next.step = t.step + 1;
} else {
next.s = 0;
next.n = t.s + t.n;
next.m = t.m;
next.step = t.step + 1;
}
if (vis.find(next) == vis.end()) {
vis.insert(next);
q.push(next);
}
}
//s-->m
if (t.s > 0 && t.m < M) {
if (t.s >= M - t.m) {
next.s = t.s - (M - t.m);
next.m = M;
next.n = t.n;
next.step = t.step + 1;
} else {
next.s = 0;
next.m = t.s + t.m;
next.n = t.n;
next.step = t.step + 1;
}
if (vis.find(next) == vis.end()) {
vis.insert(next);
q.push(next);
}
}
//n-->s
if (t.n > 0 && t.s < S) {
if (t.n >= S - t.s) {
next.n = t.n - (S - t.s);
next.s = S;
next.m = t.m;
next.step = t.step + 1;
} else {
next.n = 0;
next.s = t.n + t.s;
next.m = t.m;
next.step = t.step + 1;
}
if (vis.find(next) == vis.end()) {
vis.insert(next);
q.push(next);
}
}
//n-->m
if (t.n > 0 && t.m < M) {
if (t.n >= M - t.m) {
next.n = t.n - (M - t.m);
next.s = t.s;
next.m = M;
next.step = t.step + 1;
} else {
next.n = 0;
next.s = t.s;
next.m = t.m + t.n;
next.step = t.step + 1;
}
if (vis.find(next) == vis.end()) {
vis.insert(next);
q.push(next);
}
}
//m-->s
if (t.m > 0 && t.s < S) {
if (t.m >= S - t.s) {
next.m = t.m - (S - t.s);
next.s = S;
next.n = t.n;
next.step = t.step + 1;
} else {
next.m = 0;
next.s = t.s + t.m;
next.n = t.n;
next.step = t.step + 1;
}
if (vis.find(next) == vis.end()) {
vis.insert(next);
q.push(next);
}
}
//m-->n
if (t.m > 0 && t.n < N) {
if (t.m >= N - t.n) {
next.m = t.m - (N - t.n);
next.s = t.s;
next.n = N;
next.step = t.step + 1;
} else {
next.m = 0;
next.s = t.s;
next.n = t.n + t.m;
next.step = t.step + 1;
}
if (vis.find(next) == vis.end()) {
vis.insert(next);
q.push(next);
}
}
}
if (!flag) {
printf("NO\n");
}
}
return 0;
}