【M - 非常可乐】

80 篇文章 0 订阅
80 篇文章 0 订阅

思路:

  • 简单的 6入口 BFS,但是:

    1. 我的思路偏了:
      一开始我以为是3个瓶子只要有一个达到 1/2总水量 就可以了(前两张代码),后来发现样例 4 1 3 的答案是 3 不是 2,就以为是只能用杯子喝水,可以喝很多次(第三张代码),但是这样会出现一个比较难解决的问题就是最后一个人喝完,另一个人还需要倒几次水有些难写,终于放弃了。
    2. 第一张代码 map 的操作出了问题,尚未修复
  • 去搜题解,原来题意是:
    使用3个瓶子其中的2个,达到平分的效果。
    那么就仅仅改动一下第二张代码的结束条件就可以了,没有什么特殊的。

代码:

  • 第一版 map:
#include <iostream>
#include <queue>
#include <map>

using namespace std;


struct pot{
	int x,y,z;
	int step ;
	pot(int x,int y,int z,int step) : x(x) , y(y) , z(z) , step(step) {} ;
	friend bool operator < (const pot &a,const pot &b){
		return a.step < b.step;
	}
};
queue<pot> Q;
map<pot , bool> M;//map是<less>类有序容器,使用结构体要重载小于号 
int s,m,n;
int ans;

void init(){
	while(Q.size())
		Q.pop();
	M.clear();
	ans = 0;
	return ;
}

void POUR(int x,int y,int z,int step){
	int nx,ny,nz;
	int ns = step+1;//变量不要重名! 
	for(int i=1;i<=6;i++){
		nx=x,ny=y,nz=z;
		switch(i){
			case 1://s->m
				if(x+y<=m)
					nx=0,ny=x+y;
				else
					nx=x+y-m,ny=m;
				break;
			case 2://s->n
				if(x+z<=n)
					nx=0,nz=x+z;
				else
					nx=x+z-n,nz=n;
				break;
			case 3://m->s
				if(y+x<=s)
					nx=y+x,ny=0;
				else
					nx=s,ny=x+y-s;
				break;
			case 4://m->n
				if(y+z<=n)
					ny=0,nz=y+z;
				else
					ny=y+z-n,nz=n;
				break;
			case 5://n->s
				if(z+x<=s)
					nx=x+z,nz=0;
				else
					nx=s,nz=x+z-s;
				break;
			case 6://n->m
				if(z+y<=m)
					ny=z+y,nz=0;
				else
					ny=m,nz=y+z-m;
				break;
		}
		cout<<M[pot(nx,ny,nz,0)]<<endl;//输出永远是 1 1 1 1 1 1 NO 
		if(M[pot(nx,ny,nz,0)])
			continue;
		M.insert(map<pot,bool>::value_type(pot(nx,ny,nz,0),true));
		Q.push(pot(nx,ny,nz,ns));
	}
	return ;
}

void BFS(){
	Q.push(pot(s,0,0,0));
	M.insert(map<pot,bool>::value_type(pot(s,0,0,0) , true));//map中的step全部置零。
	//那这么一想,vis[maxn][maxn][maxn]足以解决问题,并不需要 map 
	while(Q.size()){
		pot cur = Q.front() ; Q.pop() ;
		int x = cur.x;
		int y = cur.y;
		int z = cur.z;
		if(x + y == z || x + z == y || y + z == x){
			ans = cur.step;
			break;
		}
		POUR(x,y,z,cur.step);
	}
	return ;
}

int main(){
	while(cin>>s>>m>>n && s){
		init();
		BFS();
		if(ans)
			cout<<ans<<endl;
		else
			cout<<"NO"<<endl;
	}
	return 0;
}
  • 第一版改进:
#include <iostream>
#include <queue>
#include <cstring>

using namespace std;

const int maxn = 105;

struct pot{
	int x,y,z;
	int step ;
	pot(int x,int y,int z,int step) : x(x) , y(y) , z(z) , step(step) {} ;
};
queue<pot> Q;
int s,m,n;
int ans;
bool vis[maxn][maxn][maxn];

void init(){
	while(Q.size())
		Q.pop();
	ans = 0;
	memset(vis,false,sizeof(vis));
	return ;
}

void POUR(int x,int y,int z,int step){
	int nx,ny,nz;
	int ns = step+1;//变量不要重名! 
	for(int i=1;i<=6;i++){
		nx=x,ny=y,nz=z;
		switch(i){
			case 1://s->m
				if(x+y<=m)
					nx=0,ny=x+y;
				else
					nx=x+y-m,ny=m;
				break;
			case 2://s->n
				if(x+z<=n)
					nx=0,nz=x+z;
				else
					nx=x+z-n,nz=n;
				break;
			case 3://m->s
				if(y+x<=s)
					nx=y+x,ny=0;
				else
					nx=s,ny=x+y-s;
				break;
			case 4://m->n
				if(y+z<=n)
					ny=0,nz=y+z;
				else
					ny=y+z-n,nz=n;
				break;
			case 5://n->s
				if(z+x<=s)
					nx=x+z,nz=0;
				else
					nx=s,nz=x+z-s;
				break;
			case 6://n->m
				if(z+y<=m)
					ny=z+y,nz=0;
				else
					ny=m,nz=y+z-m;
				break;
		}
		if(vis[nx][ny][nz])
			continue;
		Q.push(pot(nx,ny,nz,ns));
		vis[nx][ny][nz] = true;
	}
	return ;
}

void BFS(){
	Q.push(pot(s,0,0,0));
	vis[s][0][0] = true; 
	while(Q.size()){
		pot cur = Q.front() ; Q.pop() ;
		int x = cur.x;
		int y = cur.y;
		int z = cur.z;
		if(x + y == z || x + z == y || y + z == x){
			ans = cur.step;
			break;
		}
		POUR(x,y,z,cur.step);
	}
	return ;
}

int main(){
	while(cin>>s>>m>>n && s){
		init();
		BFS();
		if(ans)
			cout<<ans<<endl;
		else
			cout<<"NO"<<endl;
	}
	return 0;
}
  • 第二版 POUR_DRINK:
#include <iostream>
#include <queue>
#include <cstring>

using namespace std;

const int maxn = 105;

int S,M,N;
int ans;
int tar;
bool vis[maxn][maxn][maxn];
struct pot{
	int x,y,z;
	int A;//此时先喝水的人已经喝到了多少水 
	int step;
	pot(int a,int b,int c,int d,int e) : x(a) , y(b) , z(c) , A(d) , step(e) {} ;
};
queue<pot> Q;

void init(){
	tar = S/2;
	memset(vis,false,sizeof(vis));
	while(Q.size())
		Q.pop();
	ans = 0;
	return ;
}

void POUR_DRINK(int x,int y,int z,int A,int s){
	int nx,ny,nz,nA,ns;
	for(int i=1;i<=6;i++){
		nx=x,ny=y,nz=z,nA=A,ns=s+1;
		switch(i){
			case 1://S->M
				if(x+y<=M)
					nx=0,ny=x+y;
				else
					nx=x+y-M,ny=M;
				break;
			case 2://S->N
				if(x+z<=N)
					nx=0,nz=x+z;
				else
					nx=x+z-N,nz=N;
				break;
			case 3://M->S
				if(y+x<=S)
					nx=y+x,ny=0;
				else
					nx=S,ny=x+y-S;
				break;
			case 4://M->N
				if(y+z<=N)
					ny=0,nz=y+z;
				else
					ny=y+z-N,nz=N;
				break;
			case 5://N->S
				if(z+x<=S)
					nx=x+z,nz=0;
				else
					nx=S,nz=x+z-S;
				break;
			case 6://N->M
				if(z+y<=M)
					ny=z+y,nz=0;
				else
					ny=M,nz=y+z-M;
				break;
		}
		if(vis[nx][ny][nz])
			continue;
		Q.push(pot(nx,ny,nz,nA,ns));vis[nx][ny][nz] = true;
	}
	for(int i=1;i<=2;i++){
		nx=x,ny=y,nz=z,nA=A,ns=s;
		switch(i){
			case 1:
				nA+=y,ny=0;
				break;
			case 2:
				nA+=z,nz=0;
				break;
		}
		if(vis[nx][ny][nz])
			continue;
		if(nA == tar){
			ans = ns;
			break;
		}
		if(nA > tar)
			continue;
		Q.push(pot(nx,ny,nz,nA,ns));vis[nx][ny][nz]=true;
	}
	return ;
}

void BFS(){
	if(S%2)
		return ;
	Q.push(pot(S,0,0,0,0));vis[S][0][0] = true;
	while(Q.size()){
		pot cur = Q.front();Q.pop();
		int x = cur.x , y = cur.y , z = cur.z , A = cur.A , step = cur.step ;
		POUR_DRINK(x,y,z,A,step);
		if(ans)
			break;
	}
	return ;
}

int main(){
	while(cin>>S>>M>>N && S){
		init();
		BFS();
		if(ans)
			cout<<ans<<endl;
		else
			cout<<"NO"<<endl;
	}
	return 0;
}
  • 265ms 2552kB
//265ms		2552kB


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

using namespace std;

const int maxn = 105;

struct pot{
	int x,y,z;
	int step ;
	pot(int x,int y,int z,int step) : x(x) , y(y) , z(z) , step(step) {} ;
};
queue<pot> Q;
int s,m,n;
int ans;
bool vis[maxn][maxn][maxn];

void init(){
	while(Q.size())
		Q.pop();
	ans = 0;
	memset(vis,false,sizeof(vis));
	return ;
}

void POUR(int x,int y,int z,int step){
	int nx,ny,nz;
	int ns = step+1;//变量不要重名! 
	for(int i=1;i<=6;i++){
		nx=x,ny=y,nz=z;
		switch(i){
			case 1://s->m
				if(x+y<=m)
					nx=0,ny=x+y;
				else
					nx=x+y-m,ny=m;
				break;
			case 2://s->n
				if(x+z<=n)
					nx=0,nz=x+z;
				else
					nx=x+z-n,nz=n;
				break;
			case 3://m->s
				if(y+x<=s)
					nx=y+x,ny=0;
				else
					nx=s,ny=x+y-s;
				break;
			case 4://m->n
				if(y+z<=n)
					ny=0,nz=y+z;
				else
					ny=y+z-n,nz=n;
				break;
			case 5://n->s
				if(z+x<=s)
					nx=x+z,nz=0;
				else
					nx=s,nz=x+z-s;
				break;
			case 6://n->m
				if(z+y<=m)
					ny=z+y,nz=0;
				else
					ny=m,nz=y+z-m;
				break;
		}
		if(vis[nx][ny][nz])
			continue;
		Q.push(pot(nx,ny,nz,ns));
		vis[nx][ny][nz] = true;
	}
	return ;
}

void BFS(){
	Q.push(pot(s,0,0,0));
	vis[s][0][0] = true; 
	while(Q.size()){
		pot cur = Q.front() ; Q.pop() ;
		int x = cur.x;
		int y = cur.y;
		int z = cur.z;
		if((x == y && !z)||(x == z && !y)||(y == z)&&!x){
			ans = cur.step;
			break;
		}
		POUR(x,y,z,cur.step);
	}
	return ;
}

int main(){
	while(cin>>s>>m>>n && s){
		init();
		BFS();
		if(ans)
			cout<<ans<<endl;
		else
			cout<<"NO"<<endl;
	}
	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值