九度 OJ 1457 非常可乐

#include <stdio.h>
#include <queue>
using namespace std;

struct P{
	int x , y , z;
	int cost;
};

queue<P> Q;
bool mark[101][101][101];

void AtoB(int &a , int sa , int &b , int sb)//倾倒函数
//sa,sb为杯子体积;a,b,初始为杯中体积,调用后为新体积
{
	if(sb - b >= a){
		b += a;
		a = 0;
	}
	else{
		a -= sb - b;
		b = sb;
	}
}

int BFS(int s , int n , int m)
{
	while(!Q.empty()){
		P now=Q.front();
		Q.pop();
		int a , b , c;

		a = now.x;		// 1.a倒b
		b = now.y;
		c = now.z;
		AtoB(a,s,b,n);
		if(mark[a][b][c] == false){
			mark[a][b][c] = true;
			P newp;
			newp.x = a;
			newp.y = b;
			newp.z = c;
			newp.cost = now.cost + 1;
			if(a == s / 2 && b == s / 2) return newp.cost;//若当前状态已平分,直接返回耗时
			if(a == s / 2 && c == s / 2) return newp.cost;
			if(b == s / 2 && c == s / 2) return newp.cost;
			Q.push(newp);
		}

		a = now.x;		//2.b倒a---与1类似,下同。
		b = now.y;
		c = now.z;
		AtoB(b,n,a,s);
		if(mark[a][b][c] == false){
			mark[a][b][c] = true;
			P newp;
			newp.x = a;
			newp.y = b;
			newp.z = c;
			newp.cost = now.cost + 1;
			if(a == s / 2 && b == s / 2) return newp.cost;
			if(a == s / 2 && c == s / 2) return newp.cost;
			if(b == s / 2 && c == s / 2) return newp.cost;
			Q.push(newp);
		}

		a = now.x;		//3.a倒c
		b = now.y;
		c = now.z;
		AtoB(a,s,c,m);
		if(mark[a][b][c] == false){
			mark[a][b][c] = true;
			P newp;
			newp.x = a;
			newp.y = b;
			newp.z = c;
			newp.cost = now.cost + 1;
			if(a == s / 2 && b == s / 2) return newp.cost;
			if(a == s / 2 && c == s / 2) return newp.cost;
			if(b == s / 2 && c == s / 2) return newp.cost;
			Q.push(newp);
		}

		a = now.x;		//4.c倒a
		b = now.y;
		c = now.z;
		AtoB(c,m,a,s);
		if(mark[a][b][c] == false){
			mark[a][b][c] = true;
			P newp;
			newp.x = a;
			newp.y = b;
			newp.z = c;
			newp.cost = now.cost + 1;
			if(a == s / 2 && b == s / 2) return newp.cost;
			if(a == s / 2 && c == s / 2) return newp.cost;
			if(b == s / 2 && c == s / 2) return newp.cost;
			Q.push(newp);
		}

		a = now.x;		//5.b倒c
		b = now.y;
		c = now.z;
		AtoB(b,n,c,m);
		if(mark[a][b][c] == false){
			mark[a][b][c] = true;
			P newp;
			newp.x = a;
			newp.y = b;
			newp.z = c;
			newp.cost = now.cost + 1;
			if(a == s / 2 && b == s / 2) return newp.cost;
			if(a == s / 2 && c == s / 2) return newp.cost;
			if(b == s / 2 && c == s / 2) return newp.cost;
			Q.push(newp);
		}

		a = now.x;		//6.c倒b
		b = now.y;
		c = now.z;
		AtoB(c,m,b,n);
		if(mark[a][b][c] == false){
			mark[a][b][c] = true;
			P newp;
			newp.x = a;
			newp.y = b;
			newp.z = c;
			newp.cost = now.cost + 1;
			if(a == s / 2 && b == s / 2) return newp.cost;
			if(a == s / 2 && c == s / 2) return newp.cost;
			if(b == s / 2 && c == s / 2) return newp.cost;
			Q.push(newp);
		}
	}
	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){	//S为奇一定不可能平分
			printf("NO\n");
			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;
				}
			}
		}

		P  tmp;
		tmp.x = s;
		tmp.y = 0;
		tmp.z = 0;
		tmp.cost = 0;
		while(!Q.empty()) Q.pop();
		mark[s][0][0] = true;
		Q.push(tmp);

		int ans = BFS(s,n,m);
		if(ans > 0) printf("%d\n",ans);
		else printf("NO\n");
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/xp1994816/article/details/52489881
今日推荐