思路:
-
简单的 6入口 BFS,但是:
- 我的思路偏了:
一开始我以为是3个瓶子只要有一个达到 1/2总水量 就可以了(前两张代码),后来发现样例 4 1 3 的答案是 3 不是 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;
}