非常可乐

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
广搜:
基本思路就是总共有6中情况,s->n,s->m,n->s,n->m,m->s,m->n,比如说s->n的意思就是把s中的饮料倒入到n中。 其中将一杯饮料倒入到另一杯中只有两种情况,要么一个瓶子空了,要么一个瓶子满了
1.首先对于题目中的S即饮料的总量,如果总量是奇数,那么无论怎么分,都是无法分出两杯完全一样的饮料的。
2.然后我们观察给出的样例,发现样例中的m,n的大小关系是不确定的,可能m大,可能n大,因此为了便于理解,我确定了n,m的大小关系,即n>m
3.对于很多求最快,最短,最少的问题,都可以用bfs来做

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
int n,m,s;//代表了三个瓶子的容量
int vis[120][120][120];//标记三个瓶子的状态是否出现过
struct node{
    int n,m,s;//记录每一次瓶子中可乐的状态
    int step;//记录倒可乐的次数
}rounds,nextrounds;
void Bfs(){//用广度优先搜索
    queue<node>q;
    int i;
    memset(vis,0,sizeof(vis));
    q.push(rounds);
    vis[rounds.s][rounds.n][rounds.m] = 1;
    while(!q.empty()){
        rounds = q.front();
        //printf("s:%d n:%d m:%d\n",rounds.s,rounds.n,rounds.m);
        if((rounds.s==rounds.n&&rounds.m==0)||(rounds.s==rounds.m&&rounds.n==0)||(rounds.m==rounds.n&&rounds.s==0)){//平分,输出次数,返回,注意相等时不能为0,否则一开始0,0程序就结束了
            printf("%d\n",rounds.step);//上面的判断改了很多次,一是一开始两个杯子都是0,是相等的但是不行,所以相等但不为零,二是及时相等相加必须为总数,否则样例1就不会输出no了
            return;
        }
        q.pop();
        for(i = 0; i < 6; i++){//6中情况s->n,n->s,s->m,m->s,n->m,m->n;重点
            if(i==0){//s->n
                if((n-rounds.n)>=rounds.s){//如果n中所剩空间大于等于s中的可乐,就可以把s中的可乐全部倒在n中
                    nextrounds.n = rounds.n + rounds.s;//原有的加上s中的
                    nextrounds.s = 0;//全部倒在n中了
                    nextrounds.m = rounds.m;//另一个瓶子不变
                    nextrounds.step = rounds.step + 1;//次数加一
                }
                else{//如果n所剩空间小于s中的可乐量,则把n倒满,s还剩下一部分
                    nextrounds.n = n;//n倒满了
                    nextrounds.s = rounds.s-(n-rounds.n);//s中剩下部分为原来s减去n中没装满的那一部分
                    nextrounds.m = rounds.m;//不变
                    nextrounds.step = rounds.step + 1;//次数加1
                }
                if(vis[nextrounds.s][nextrounds.n][nextrounds.m]==0){
                    q.push(nextrounds);
                    vis[nextrounds.s][nextrounds.n][nextrounds.m] = 1;
                }
            }
            else if(i==1){//n->s
                if((s-rounds.s)>=rounds.n){//s中所剩空间大于n的可乐量,可以把n中倒完
                    nextrounds.s = rounds.s + rounds.n;
                    nextrounds.n = 0;
                    nextrounds.m = rounds.m;
                    nextrounds.step = rounds.step + 1;
                }
                else{//s中所剩空间小于n中可乐量,可以把s倒满,n中剩余
                    nextrounds.s = s;
                    nextrounds.n = rounds.n - (s-rounds.s);
                    nextrounds.m = rounds.m;
                    nextrounds.step = rounds.step + 1;
                }
                if(vis[nextrounds.s][nextrounds.n][nextrounds.m]==0){
                    q.push(nextrounds);
                    vis[nextrounds.s][nextrounds.n][nextrounds.m] = 1;
                }
            }
            else if(i==2){//s->m
                if((m-rounds.m)>=rounds.s){//m中剩余空间大于s可乐量,s倒完
                    nextrounds.m = rounds.m + rounds.s;
                    nextrounds.s = 0;
                    nextrounds.n = rounds.n;
                    nextrounds.step = rounds.step + 1;
                }
                else{//m剩余空间小于s可乐量,m倒满,s剩余
                    nextrounds.m = m;
                    nextrounds.s = rounds.s - (m-rounds.m);
                    nextrounds.n = rounds.n;
                    nextrounds.step = rounds.step + 1;
                }
                if(vis[nextrounds.s][nextrounds.n][nextrounds.m]==0){
                    q.push(nextrounds);
                    vis[nextrounds.s][nextrounds.n][nextrounds.m] = 1;
                }
            }
            else if(i==3){//m->s
                    if((s-rounds.s)>=rounds.m){//s中剩余空间大于m可乐量,m倒完
                    nextrounds.s = rounds.m + rounds.s;
                    nextrounds.m = 0;
                    nextrounds.n = rounds.n;
                    nextrounds.step = rounds.step + 1;
                }
                else{//s剩余空间小于m可乐量,s倒满,m剩余
                    nextrounds.s = s;
                    nextrounds.m = rounds.m - (s-rounds.s);
                    nextrounds.n = rounds.n;
                    nextrounds.step = rounds.step + 1;
                }
                if(vis[nextrounds.s][nextrounds.n][nextrounds.m]==0){
                    q.push(nextrounds);
                    vis[nextrounds.s][nextrounds.n][nextrounds.m] = 1;
                }
            }
            else if(i==4){//n->m;
                    if((m-rounds.m)>=rounds.n){//m中剩余空间大于n可乐量,n倒完
                    nextrounds.m = rounds.m + rounds.n;
                    nextrounds.n = 0;
                    nextrounds.s = rounds.s;
                    nextrounds.step = rounds.step + 1;
                }
                else{//m剩余空间小于n可乐量,m倒满,n剩余
                    nextrounds.m = m;
                    nextrounds.n = rounds.n - (m-rounds.m);
                    nextrounds.s = rounds.s;
                    nextrounds.step = rounds.step + 1;
                }
                if(vis[nextrounds.s][nextrounds.n][nextrounds.m]==0){
                    q.push(nextrounds);
                    vis[nextrounds.s][nextrounds.n][nextrounds.m] = 1;
                }
            }
            else{//m->n
                    if((n-rounds.n)>=rounds.m){//n中剩余空间大于m可乐量,m倒完
                    nextrounds.n = rounds.n + rounds.m;
                    nextrounds.m = 0;
                    nextrounds.s = rounds.s;
                    nextrounds.step = rounds.step + 1;
                }
                else{//n剩余空间小于m可乐量,n倒满,m剩余
                    nextrounds.n = n;
                    nextrounds.m = rounds.m - (n-rounds.n);
                    nextrounds.s = rounds.s;
                    nextrounds.step = rounds.step + 1;
                }
                if(vis[nextrounds.s][nextrounds.n][nextrounds.m]==0){
                    q.push(nextrounds);
                    vis[nextrounds.s][nextrounds.n][nextrounds.m] = 1;
                }
            }
        }
    }
    printf("NO\n");//如果队列为空了说明方法都用完了,不可能平分
    return;
}
int main(){
    int i;
    while(~scanf("%d%d%d",&s,&n,&m)){
        if(s==0&&n==0&&m==0)break;
        rounds.s = s;
        rounds.n = 0;
        rounds.m = 0;
        rounds.step = 0;
        if(s%2){//奇数肯定不能平分
            printf("NO\n");
        }
        else{
            Bfs();
        }
    }
    return 0;
}

利用数论:

#include<stdio.h>
int gcd(int a,int b)
{
	if(b==0) return a;
	else return gcd(b,a%b);
}
int main()
{
	int s,m,n;
	while(scanf("%d%d%d",&s,&m,&n)!=EOF)
	{
		if(m==0&&n==0) break;
		s/=gcd(m,n);
		if(s%2==0) printf("%d\n",s-1);
		else printf("NO\n");
	}
	return 0;
}

BFS二维数组:

#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;//我在这定义了v[3]数组来存储s,n,m,
//这样子定义而不定义成s,n,m是为了与我定义的结构体数组中的成员名称一致,方便理解。
int v[3],ans;//定义了一个二维数组book来标记情况,
int book[105][105];
struct node
{
    int v[3],step;
} q[1000005];
void bfs()
{//用的是手写队列的方法,(不会queue的悲伤)
    int head=1;
    int tail=1;
    q[head].v[0]=v[0];
    q[head].v[1]=0;
    q[head].v[2]=0;
    q[head].step=0;
    tail++;
    book[v[0]][q[head].v[1]]=1;
    int flag=0;//flag用于标记是否找到了答案
    int nx[3];
    while(head<tail)
    {//因为v[0]其实是最大瓶的饮料,v[1]经过处理后是第二大瓶的饮料,
        //所以说当v[0]中的数量是瓶容量的一半,
        //并且v[2]瓶(容量最小的瓶)没有饮料的时候(即v[1]瓶的容量也是v[0]瓶的一半的时候),
        //就是我们最终可以跳出循环的时候
        if(q[head].v[0]==v[0]/2&&q[head].v[2]==0)
        {
            printf("%d\n",q[head].step);
            flag=1;
            break;
        }
        for(int i=0; i<3; i++)
        {
            for(int j=0; j<3; j++)
            {
                if(i==j) continue;//(i,j)的意思是将v[i]中的饮料倒入v[j]中
                int amount=min(q[head].v[i],v[j]-q[head].v[j]);//这个amount好精髓,我一开始做题的时候还在想要不要分类讨论
                for(int k=0; k<3; k++) nx[k]=q[head].v[k];
                nx[i]=nx[i]-amount;
                nx[j]=nx[j]+amount;
                if(book[nx[0]][nx[1]]==0)//如果下一次倒水三个瓶中的情况之前还没出现过,就将这种情况入列
                {
                    book[nx[0]][nx[1]]=1;
                    q[tail].v[0]=nx[0];
                    q[tail].v[1]=nx[1];
                    q[tail].v[2]=nx[2];
                    q[tail].step=q[head].step+1;
                    tail++;
                }
            }
        }
        head++;
    }if(flag==0) printf("NO\n");

}
int main()
{
    while(~scanf("%d%d%d",&v[0],&v[1],&v[2]),v[0]+v[1]+v[2])
    {
        if(v[0]%2)
        {
            printf("NO\n");
            continue;
        }
        memset(book,0,sizeof(book));
        ans=0;
        int t;
        if(v[1]<v[2])
        {
            t=v[1];
            v[1]=v[2];
            v[2]=t;
        }
        bfs();
    }
    return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当人们喝下一瓶冰镇的可乐时,他们可能不会考虑到这种饮料的制作过程。因为可乐制作非常复杂,需要多种原料和工艺。下面是可乐的制作过程,只是简化的概述: 1. 原料准备 可乐的主要成分是水、糖和二氧化碳气体。通过特殊的工艺还需要添加一些香料和色素,以及少量的咖啡因。这些成分需要遵循特定的比例来准备。 2. 糖浆制造 糖浆是可乐的一个关键组成部分,它由白砂糖、孟宗竹和水制成。这些原料在大锅里煮沸,直到它们完全融化并形成糖浆。糖浆需要冷却和过滤,以去除杂质。 3. 香料和色素的添加 香料和色素的添加是可乐制造中的另一个关键步骤。香料通常是由柠檬、甜橙、丁香、肉桂等物品中提取出来的,并经过精细调配以达到所需的口感和香气。色素通常是焦糖,会使可乐的颜色更深、更饱和。 4. 混合 在混合过程中,制造商需要将糖浆、水、香料和色素混合在一起,以制成基础混合物。这种混合物必须保持在恒定的温度和压力环境中。 5. 炭酸化 炭酸是可乐中能形成气泡的原因,而它的形成是通过将二氧化碳气体注入基础混合物完成的。在这个过程中,瓶子或罐子需要密封,以确保可乐不会因为气泡的膨胀而泄漏。 6. 消毒和包装 准备好的可乐混合物需要进行消毒,以确保它没有细菌污染。然后才能被灌装瓶子或罐子中, 7. 检验和内部测试 制造商必须对每批可乐进行检验和内部测试,以确保它符合所有的质量和安全标准。 综上所述,这大概是可乐的制作过程。由于制作过程中的配方和工艺不同,每个制造商的可乐口味和口感也会有所不同。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值