[M - non Cola]

Train of thought:

  • 6 entrance BFS, but my thinking deviated:
    At first, I thought that if one of the three bottles reached 1 / 2 of the total water volume (the first two codes), then I found that the answer of example 4 13 was "3 is not 2", I thought that it was only possible to drink water with a cup, which could be drunk many times (the latter code), but in this way, a more difficult problem would arise, that is, the last person would drink it, and the other person would have to pour water several times Some difficult to write, finally gave up.

  • There was a problem with the operation of the first code map.

  • To search for the answers to the questions, the original meaning is:
    Use 2 of the 3 bottles to achieve the effect of even score.
    Nothing special.

Code:

  • First version 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 is an ordered container of the < less > class. When using a structure, you need to overload the less than sign 
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;//Do not duplicate variable name! 
	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;//The output is always 1 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));//All step s in the map are zeroed.
	//In that case, vis[maxn][maxn][maxn] is enough to solve the problem and does not need 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;
}
  • First edition improvements:
#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;//Do not duplicate variable name! 
	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;
}
  • Second edition pour'u drive:
#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;//How much water has the first drinker already drunk 
	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;
}

Tags: less

Posted on Fri, 08 Nov 2019 12:29:22 -0500 by aquila125