非常可乐
Problem Description
大家一定觉的运动以后喝可乐是一件很惬意的事情,但是seeyou却不这么认为。因为每次当seeyou买了可乐以后,阿牛就要求和seeyou一起分享这一瓶可乐,而且一定要喝的和seeyou一样多。但seeyou的手中只有两个杯子,它们的容量分别是N 毫升和M 毫升 可乐的体积为S (S<101)毫升 (正好装满一瓶) ,它们三个之间可以相互倒可乐 (都是没有刻度的,且 S==N+M,101>S>0,N>0,M>0) 。聪明的ACMER你们说他们能平分吗?如果能请输出倒可乐的最少的次数,如果不能输出"NO"。
Input
三个整数 : S 可乐的体积 , N 和 M是两个杯子的容量,以"0 0 0"结束。
Output
如果能平分的话请输出最少要倒的次数,否则输出"NO"。
Sample Input
7 4 3 4 1 3 0 0 0
Sample Output
NO 3
题意:三个瓶子(设为a,b,c)倒可乐。容积满足关系a=b+c.瓶子是没有刻度线的。问最小多少次能是可乐平分。如果不能输出no。否则输出次数
分析:三个瓶子倒可乐,因为没有刻度线。所以每次倒可乐是必然要使得一个瓶子被倒满。取不同瓶子来倒可乐是应有6种。即a->b,a-c.b->c,b->a.c->b,c->a;
广度优先搜索枚举这六种情况即可!
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<queue>
using namespace std;
bool flag[102][102][102];
struct lmx{
int a;
int b;
int c;
int k;
lmx(int a=0,int b=0,int c=0,int k=0):a(a),b(b),c(c),k(k){}
};
int s,n,m;
int bfs(lmx ss)
{
queue<lmx> q;
int cnt=s/2;
q.push(ss);
flag[ss.a][ss.b][ss.c]=true;
while(!q.empty())
{
lmx s=q.front();
q.pop();
int x=s.a,y=s.b,z=s.c,mm=s.k+1;
if((x==cnt&&y==cnt)||(x==cnt&&z==cnt)||(y==cnt&&z==cnt))
{
return mm-1;
}
else
{
if(x>0)
{
if(y!=n&&z!=m)
{
int x1=x+y-n;
if(!flag[x1][n][z])
{
flag[x1][n][z]=true;
q.push(lmx(x1,n,z,mm));
}
int x2=x+z-m;
if(!flag[x2][y][m])
{
flag[x2][y][m]=true;
q.push(lmx(x2,y,m,mm));
}
}
}
if(y>0)
{
if(z!=m)
{
int y1=y+z-m;
if(y1<0)
{
if(!flag[x][0][z+y])
{
q.push(lmx(x,0,z+y,mm));
flag[x][0][z+y]=true;
}
}
else
{
if(!flag[x][y1][m])
{
q.push(lmx(x,y1,m,mm));
flag[x][y1][m]=true;
}
}
}
if(!flag[x+y][0][z])
{
q.push(lmx(x+y,0,z,mm));
flag[x+y][0][z]=true;
}
}
if(z>0)
{
if(y!=n)
{
int z1=z+y-n;
if(z1<0)
{
if(!flag[x][z+y][0])
{
q.push(lmx(x,z+y,0,mm));
flag[x][z+y][0]=true;
}
}
else
{
if(!flag[x][n][z1])
{
q.push(lmx(x,n,z1,mm));
flag[x][n][z1]=true;
}
}
}
}
if(!flag[x+z][y][0])
{
q.push(lmx(x+z,y,0,mm));
flag[x+z][y][0]=true;
}
}
}
return -1;
}
int main()
{
while(scanf("%d%d%d",&s,&n,&m)&&s+n+m)
{
if(s&1) {puts("NO");continue;}
memset(flag,false,sizeof(flag));
int temp=bfs(lmx(s,0,0));
if(temp==-1) puts("NO");
else printf("%d\n",temp);
}
return 0;
}
#include<string.h>
#include<iostream>
#include<queue>
using namespace std;
bool flag[102][102][102];
struct lmx{
int a;
int b;
int c;
int k;
lmx(int a=0,int b=0,int c=0,int k=0):a(a),b(b),c(c),k(k){}
};
int s,n,m;
int bfs(lmx ss)
{
queue<lmx> q;
int cnt=s/2;
q.push(ss);
flag[ss.a][ss.b][ss.c]=true;
while(!q.empty())
{
lmx s=q.front();
q.pop();
int x=s.a,y=s.b,z=s.c,mm=s.k+1;
if((x==cnt&&y==cnt)||(x==cnt&&z==cnt)||(y==cnt&&z==cnt))
{
return mm-1;
}
else
{
if(x>0)
{
if(y!=n&&z!=m)
{
int x1=x+y-n;
if(!flag[x1][n][z])
{
flag[x1][n][z]=true;
q.push(lmx(x1,n,z,mm));
}
int x2=x+z-m;
if(!flag[x2][y][m])
{
flag[x2][y][m]=true;
q.push(lmx(x2,y,m,mm));
}
}
}
if(y>0)
{
if(z!=m)
{
int y1=y+z-m;
if(y1<0)
{
if(!flag[x][0][z+y])
{
q.push(lmx(x,0,z+y,mm));
flag[x][0][z+y]=true;
}
}
else
{
if(!flag[x][y1][m])
{
q.push(lmx(x,y1,m,mm));
flag[x][y1][m]=true;
}
}
}
if(!flag[x+y][0][z])
{
q.push(lmx(x+y,0,z,mm));
flag[x+y][0][z]=true;
}
}
if(z>0)
{
if(y!=n)
{
int z1=z+y-n;
if(z1<0)
{
if(!flag[x][z+y][0])
{
q.push(lmx(x,z+y,0,mm));
flag[x][z+y][0]=true;
}
}
else
{
if(!flag[x][n][z1])
{
q.push(lmx(x,n,z1,mm));
flag[x][n][z1]=true;
}
}
}
}
if(!flag[x+z][y][0])
{
q.push(lmx(x+z,y,0,mm));
flag[x+z][y][0]=true;
}
}
}
return -1;
}
int main()
{
while(scanf("%d%d%d",&s,&n,&m)&&s+n+m)
{
if(s&1) {puts("NO");continue;}
memset(flag,false,sizeof(flag));
int temp=bfs(lmx(s,0,0));
if(temp==-1) puts("NO");
else printf("%d\n",temp);
}
return 0;
}
为了明天所以选择坚定的执着今天。