版权声明:感谢阅读,欢迎批评指正。 https://blog.csdn.net/skyejy/article/details/89814232
题目:
#include<stdio.h>
#include<queue>
using namespace std;
struct N{
int a,b,c;
int t;
};
queue<N> Q;
bool mark[101][101][101];
void AtoB(int &a,int sa,int &b,int sb){
//两杯子容积分别为sa ,sb
//两杯子里原有可乐体积 a ,b
//?不加&会怎样
if(sb-b>=a)//a可以全部倒进b中
{
b+=a;
a=0;
}
else{
a-=sb-b;
b=sb;
}
}
int BFS(int s,int n,int m){
while(Q.empty()==false){
//当队列非空
N now=Q.front();//拿出队头状态
Q.pop();//弹出队头状态
int a,b,c;//临时保存三个杯子中的可乐
a=now.a;
b=now.b;
c=now.c;
AtoB(a,s,b,n);//由a倾倒向b
if(mark[a][b][c]==false){
//若该体积组尚未标记
mark[a][b][c]=true;
N tmp;
tmp.a=a;
tmp.b=b;
tmp.c=c;
tmp.t=now.t+1;//生成新的状态
if(a==s/2&&b==s/2) return tmp.t;
if(c==s/2&&b==s/2)return tmp.t;
if(a==s/2&&c==s/2)return tmp.t;
//若该状态已经为平分状态,则直接返回该状态的耗时
Q.push(tmp);//没找到目标状态,则放入队列
}
a=now.a;
b=now.b;
c=now.c;//重置a,b,c为未倾倒前的体积
AtoB(b,n,a,s);//b倒向a
if(mark[a][b][c]==false){
mark[a][b][c]=true;
N tmp;
tmp.a=a;
tmp.b=b;
tmp.c=c;
tmp.t=now.t+1;//生成新的状态
if(a==s/2&&b==s/2) return tmp.t;
if(c==s/2&&b==s/2)return tmp.t;
if(a==s/2&&c==s/2)return tmp.t;
Q.push(tmp);
}
a=now.a;
b=now.b;
c=now.c;//重置a,b,c为未倾倒前的体积
AtoB(a,s,c,m);//a倒向c
if(mark[a][b][c]==false){
mark[a][b][c]=true;
N tmp;
tmp.a=a;
tmp.b=b;
tmp.c=c;
tmp.t=now.t+1;//生成新的状态
if(a==s/2&&b==s/2) return tmp.t;
if(c==s/2&&b==s/2)return tmp.t;
if(a==s/2&&c==s/2)return tmp.t;
Q.push(tmp);
}
a=now.a;
b=now.b;
c=now.c;//重置a,b,c为未倾倒前的体积
AtoB(c,m,a,s);//c倒向a
if(mark[a][b][c]==false){
mark[a][b][c]=true;
N tmp;
tmp.a=a;
tmp.b=b;
tmp.c=c;
tmp.t=now.t+1;//生成新的状态
if(a==s/2&&b==s/2) return tmp.t;
if(c==s/2&&b==s/2)return tmp.t;
if(a==s/2&&c==s/2)return tmp.t;
Q.push(tmp);
}
a=now.a;
b=now.b;
c=now.c;//重置a,b,c为未倾倒前的体积
AtoB(b,n,c,m);//b倒向c
if(mark[a][b][c]==false){
mark[a][b][c]=true;
N tmp;
tmp.a=a;
tmp.b=b;
tmp.c=c;
tmp.t=now.t+1;//生成新的状态
if(a==s/2&&b==s/2) return tmp.t;
if(c==s/2&&b==s/2)return tmp.t;
if(a==s/2&&c==s/2)return tmp.t;
Q.push(tmp);
}
a=now.a;
b=now.b;
c=now.c;//重置a,b,c为未倾倒前的体积
AtoB(c,m,b,n);//c倒向b
if(mark[a][b][c]==false){
mark[a][b][c]=true;
N tmp;
tmp.a=a;
tmp.b=b;
tmp.c=c;
tmp.t=now.t+1;//生成新的状态
if(a==s/2&&b==s/2) return tmp.t;
if(c==s/2&&b==s/2)return tmp.t;
if(a==s/2&&c==s/2)return tmp.t;
Q.push(tmp);
}
}
return -1;
}
int main(){
int s,n,m;
while(scanf("%d%d%d",&s,&n,&m)!=EOF){
if(s==0) break;
if(s%2==1)
{
puts("NO");
continue;
}
for(int i=0;i<=s;i++){
for(int j=0;j<=n;j++){
for(int k=0;k<=m;k++){
mark[i][j][k]=false;
}
}
}//初始化状态
N tmp;
tmp.a=s;
tmp.b=0;
tmp.c=0;
tmp.t=0;
while(Q.empty()==false) Q.pop();
Q.push(tmp);//将初始状态放入队列
mark[s][0][0]=true;
int rec=BFS(s,n,m);//广度优先搜索
if(rec==-1)
puts("NO");
else printf("%d\n",rec);
}
}