题目链接:点我啊╭(╯^╰)╮
题目大意:
一杯可乐,两个杯子,体积分别为 , , 。一开始可乐是满的,问怎么互相倒,可以对半分 ???
解题思路:
六入口BFS,很简单,但是看了另一个人的数论解题,感觉很牛X
这里贴出数论解题的博客:点我啊点我啊
代码思路:
BFS 或 数论
核心:数论的运用
数论:
#include<bits/stdc++.h>
using namespace std;
int gcd(int a, int b){
return b ? gcd(b, a%b) : a;
}
int main()
{
int a, b, c;
while(scanf("%d%d%d", &a,&b,&c), a+b+c)
{
a /= gcd(b,c);
if(a&1) printf("NO\n");
else printf("%d\n", a-1);
}
}
BFS:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int a, b, c, ans;
bool vis[105][105][105];
struct pot {
int s, u, v;
int step;
};
void BFS() {
queue <pot> Q;
pot q, n;
q.s = a, q.u = 0, q.v = 0;
q.step = 0;
Q.push(q);
vis[a][0][0] = true;
while(!Q.empty()) {
q = Q.front();
Q.pop();
for(int i=1; i<=6; i++) {
if(i==1 && q.s && q.u!=b) { // a->b
if(b-q.u>q.s) {
n.s = 0;
n.u = q.s + q.u;
n.v = q.v;
} else {
n.s = q.s - (b - q.u);
n.u = b;
n.v = q.v;
}
}
if(i==2 && q.s && q.v!=c) { // a->c
if(c-q.v>q.s) {
n.s = 0;
n.u = q.u;
n.v = q.s + q.v;
} else {
n.s = q.s - (c - q.v);
n.u = q.u;
n.v = c;
}
}
if(i==3 && q.u && q.s!=a) { // b->a
if(a-q.s>q.u) {
n.s = q.s + q.u;
n.u = 0;
n.v = q.v;
} else {
n.s = a;
n.u = q.u - (a - q.s);
n.v = q.v;
}
}
if(i==4 && q.u && q.v!=c) { // b->c
if(c-q.v>q.u) {
n.s = q.s;
n.u = 0;
n.v = q.u + q.v;
} else {
n.s = q.s;
n.u = q.u - (c - q.v);
n.v = c;
}
}
if(i==5 && q.v && q.s!=a) { // c->a
if(a-q.s>q.v) {
n.s = q.s + q.v;
n.u = q.u;
n.v = 0;
} else {
n.s = a;
n.u = q.u;
n.v = q.v - (a - q.s);
}
}
if(i==6 && q.v && q.u!=b) { // c->b
if(b-q.u>q.v) {
n.s = q.s;
n.u = q.u + q.v;
n.v = 0;
} else {
n.s = q.s;
n.u = b;
n.v = q.v - (b - q.u);
}
}
if(vis[n.s][n.u][n.v]) continue;
vis[n.s][n.u][n.v] = true;
n.step = q.step + 1;
if(n.s==a/2&&n.u==a/2 || n.s==a/2&&n.v==a/2 || n.u==a/2&&n.v==a/2) {
ans = n.step;
return;
}
Q.push(n);
}
}
}
int main() {
while(scanf("%d%d%d", &a, &b, &c), a) {
memset(vis, 0, sizeof(vis));
ans = 0;
if(a%2){
printf("NO\n");
continue;
}
BFS();
if(!ans) printf("NO\n");
else printf("%d\n", ans);
}
}