机试指南-搜索-广搜-非常可乐(更简单写法)

 题目描述

代码

#include <iostream>
#include <queue>
#include <cstring>

#define N 105

using namespace std;

struct Status{
	int ml[3];
	int t;
	Status(int _ml[], int _t = 0){
		ml[0] = _ml[0];
		ml[1] = _ml[1];
		ml[2] = _ml[2];
		t = _t;
	}
	Status(int a, int b, int c, int _t = 0){
		ml[0] = a;
		ml[1] = b;
		ml[2] = c;
		t = _t;
	}
};

int visited[N][N][N];

int main(){
	freopen("in.txt", "r", stdin);
	
	int vol[3];
	while(cin >> vol[0] >> vol[1] >> vol[2]){
		if(vol[0] == 0 && vol[1] == 0 && vol[2] == 0){
			break;
		}
		if(vol[0] % 2 != 0){ // 一半为小数,不符合 
			cout << "NO" << endl;
			continue;
		}
		int half_ml = vol[0] / 2;
		
		// 初始化visited
		memset(visited, 0, sizeof(visited));
		
		queue<Status> que;
		que.push(Status(vol[0], 0, 0, 0));
		visited[vol[0]][0][0] = 1;
		
		bool finished = false; // 完成平分?
		while(!que.empty()){
			Status status = que.front();
			que.pop();
			// 判断是否平分 
			for(int i = 0; i < 3 && !finished; i++){
				for(int j = 0; j < 3 && !finished; j++){
					if(i != j && status.ml[i] == half_ml && status.ml[j] == half_ml){
						finished = true;
					}
				}
			}
			if(finished){ // 平分完成,退出循环 
				cout << status.t << endl;
				break;
			}
			// 对每个杯子
			for(int i = 0; i < 3; i++){ 
				if(status.ml[i] == 0){ // 为0ml
					continue;
				}
				// 此杯子给另外两个杯子倒可乐 
				for(int j = 0; j < 3; j++){
					if(i == j || status.ml[j] == vol[j]){ // 不是另一杯子或者另一杯子满 
						continue;
					}
					// _ml为倒入后的状态,先初始化 
					int _ml[3];
					for(int l = 0; l < 3; l++){
						_ml[l] = status.ml[l];
					}
					// 倒给另外一个杯子可乐,把此杯子倒完或者装满另一杯子
					if(vol[j] - status.ml[j] > status.ml[i]){
						_ml[i] = 0;
						_ml[j] = status.ml[j] + status.ml[i];
					}else{
						_ml[i] = status.ml[i] - (vol[j] - status.ml[j]);
						_ml[j] = vol[j];
					}
					// 状态入队 
					if(!visited[_ml[0]][_ml[1]][_ml[2]]){
						que.push(Status(_ml, status.t + 1));
						visited[_ml[0]][_ml[1]][_ml[2]] = 1;
					}
				}
			}
		}
		if(!finished){
			cout << "NO" << endl;
		}
	}
	
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值