状态搜索(广度优先)平分可乐问题

版权声明:感谢阅读,欢迎批评指正。 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); 
		 
	}
}

猜你喜欢

转载自blog.csdn.net/skyejy/article/details/89814232