非常可乐原题链接
题目描述:
思路:
当可乐总量为奇数时,不可能均分,直接输出结果;将i被子倒入j杯中时,分两种情况,一种是能倒完,一种还有剩余
AC代码:
#include <iostream>
#include <queue>
#include <string.h>
using namespace std;
int N,M,S;
struct node
{
int num[3];
int steps;//次数
}now,nex;
int vis[101][101][101];
int rq[3];//最大容量
bool check(node x)//检查
{
if((x.num[0] == x.num[1] && x.num[2] == 0 )||(x.num[0] == x.num[2] && x.num[1] == 0)||(x.num[1] == x.num[2] && x.num[0] == 0))
{
return true;
}
else return false;
}
void bfs()
{
queue<node> Q;
memset(vis,0,sizeof(vis));
now.num[0] = S;
now.num[1] = 0;
now.num[2] = 0;
vis[S][0][0] = 1;//记录当前的情况已经访问了
now.steps = 0;//记录次数
Q.push(now);
while(!Q.empty())
{
now = Q.front();
Q.pop();
if(check(now))
{
printf("%d\n",now.steps);
return;
}
for(int i = 0; i < 3; i++)
{
for(int j = 0; j < 3; j++)
{
if(i == j) continue;
if(now.num[i] <= rq[j] - now.num[j])//能倒完
{
nex.num[j] = now.num[j] + now.num[i];
nex.num[i] = 0;
}
else//不能倒完
{
nex.num[i] = now.num[i] - (rq[j] - now.num[j]);
nex.num[j] = rq[j];
}
//另外一个不变
for(int k = 0; k < 3; k++)
{
if(k == i || k == j)
{
continue;
}
nex.num[k] = now.num[k];
}
//步数加一,注意别写成now.steps++!!!
nex.steps = now.steps + 1;
if(vis[nex.num[0]][nex.num[1]][nex.num[2]]==0){
vis[nex.num[0]][nex.num[1]][nex.num[2]]=1;
Q.push(nex);
}
}
}
}
printf("NO\n");
return;
}
int main()
{
while(scanf("%d%d%d",&S,&N,&M)!=EOF && S!=0 && N!=0 && M!=0)
{
if(S / 2 == 1)
{
printf("NO\n");
}
else{
rq[0] = S;
rq[1] = N;
rq[2] = M;
bfs();
}
}
return 0;
}