题意
王涵斌配了满满一烧杯的硫酸铜溶液,谢璟涵觉得很漂亮,就请王涵斌分一半给她。
王涵斌手中盛满硫酸铜溶液的烧杯容积为A,谢璟涵拿来了两个空烧杯,容积分别为B和C。现在王涵斌可以进行若干次操作。
每次操作都是将一个烧杯里的溶液倒到另一个烧杯中,但因为一些限制,王涵斌不能倒任意体积的溶液,只有当不能再倒了(即倒出的烧杯变空了或倒入的烧杯装满了)才能停止。
王涵斌想要知道最终能不能将这些溶液平分,如果能的话请你输出最少的操作步数。
解题
显然,A为奇数一定不可均分。
状态为每个烧杯内的溶液量以及到的次数。从每个状态最多有六种状态转移。将状态作为节点,状态转移连边,进行一次bfs。能bfs到所需状态说明有解,解为该状态的次数。否则,无解。
AC代码
//78ms 3040kB
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <iostream>
using namespace std;
const int maxn=101;
struct node
{
int all,x,y,t;
node(int all,int x,int y,int t):all(all),x(x),y(y),t(t){}
};
bool vis[maxn][maxn][maxn];
int a,b,c;
void bfs()
{
int ed=a/2;
memset(vis,false,sizeof(vis));
queue<node> Q;
vis[a][0][0]=true;
Q.push(node(a,0,0,0));
while(!Q.empty())
{
node now=Q.front();;Q.pop();
int all=now.all,x=now.x,y=now.y,t=now.t;
//cout<<all<<" "<<x<<" "<<y<<" "<<t<<endl;
if(all==ed&&x==ed || all==ed&&y==ed || x==ed&&y==ed)
{
cout<<t<<endl;
return ;
}
//all->x
if(all && x!=b)
{
int fa=all<=b-x?0:all-(b-x);
int fx=all<=b-x?x+all:b;
int fy=y;
//cout<<fa<<" "<<fx<<" "<<fy<<" "<<t+1<<endl;
if(!vis[fa][fx][fy])
{
vis[fa][fx][fy]=true;
Q.push(node(fa,fx,fy,t+1));
}
}
//all->y
if(all && y!=c)
{
int fa=all<=c-y?0:all-(c-y);
int fx=x;
int fy=all<=c-y?y+all:c;
if(!vis[fa][fx][fy])
{
vis[fa][fx][fy]=true;
Q.push(node(fa,fx,fy,t+1));
}
}
//x->all
if(x && all!=a)
{
int fx=x<=a-all?0:x-(a-all);
int fy=y;
int fa=x<=a-all?all+x:a;
if(!vis[fa][fx][fy])
{
vis[fa][fx][fy]=true;
Q.push(node(fa,fx,fy,t+1));
}
}
//x->y
if(x && y!=c)
{
int fx=x<=c-y?0:x-(c-y);
int fy=x<=c-y?y+x:c;
int fa=all;
if(!vis[fa][fx][fy])
{
vis[fa][fx][fy]=true;
Q.push(node(fa,fx,fy,t+1));
}
}
//y->x
if(y && x!=b)
{
int fy=y<=b-x?0:y-(b-x);
int fx=y<=b-x?x+y:b;
int fa=all;
if(!vis[fa][fx][fy])
{
vis[fa][fx][fy]=true;
Q.push(node(fa,fx,fy,t+1));
}
}
//y->all
if(y && all!=a)
{
int fy=y<a-all?0:y-(a-all);
int fa=y<a-all?all+y:a;
int fx=x;
if(!vis[fa][fx][fy])
{
vis[fa][fx][fy]=true;
Q.push(node(fa,fx,fy,t+1));
}
}
}
cout<<"NO"<<endl;
return ;
}
int main()
{
while(cin>>a>>b>>c)
{
if(a==b && b==c && c==0) break;
if(a&1)
{
cout<<"NO"<<endl;
continue;
}
bfs();
}
return 0;
}