马老板遇到了一个难题,你能帮帮他吗?

        在马老板的难题里,最核心,最关键的地方在于让三种颜色的小球不相邻地排成一行。我们假设三种小球颜色数量分别为a,b,c。如果假设三种小球都只有一个你会怎么排?是不是直接abc直接一字排开来的直接。


        那如果是三种小球中a,b各有两个,c有一个呢?我们可以将abc先排起来,再将ab排到c的后面,形成abcab这样的字符串。


        好了,前面都是基础教学,是不是非常简单呢?当大家能理解以上两个例子后我们就可以试着理解这一题的思路了。

 

 


        当a,b,c三种小球数量不同时,我们可以选出三种颜色中数量最小的那个定为Min,然后从三种小球中各拿出Min个小球,剩余小球数量分别为a-Min,b-Min和c-Min,然后将拿出的3Min个小球以abc的形式依次排开,此时小球长度length为3Min,如下图所示。


        由于Min是a,b,c中的最小值,说明现在只剩两种小球了,那我们可以重复上面的步骤,从剩下两种球最小的那种定为Min1,然后从中剩下的小球拿出Min1个球,也就是剩下的小球数量都减去Min1,然后将拿出的2Min1个小球按照ab/bc/ac的顺序从abc的尾部排开,此时小球长度length为3Min+2Min1,如下图所示。

 


        此时若是最后一种小球还有剩余则需要进行插入操作,即a有剩余往bc之间插入,b有剩余往ac之间插入,c有剩余往ab之间插入。经过观察可以发现,总是有几个abc就可以向其中插入几个a/b/c,同时头和尾的位置也总至少有一个能插入(这个地方我在下一段会具体叙述)。即可以定义cnt=Min+1,当cnt≥数量最多小球的剩余数量时,小球长度length为3Min+2Min1+数量最多小球的剩余数量;当<时小球长度length为3Min+2Min1+cnt。


        当排序情况固定为abc,ab,bc和ac时,a,b,c数量由大到小头和尾能插入几个a,b,c中数量最大的小球。当然,我的代码里并未体现当b最多a最少时头和尾能插入两个b,但此时abc里能插入的数量会-1(即cnt在这时为Min-1+2),特此进行更正。


————

        以下部分为代码,玄某人推荐大家先自己手敲一遍然后和我的进行对照,学习c语言最重要的是实践!

————

 

#include <bits/stdc++.h>
using namespace std;
string s;
int cal(int x,int y)
{
    return x==0?y:x;
}
int minn(int a,int b,int c)
{
    int d=min(a,b),e=min(b,c);
    return min(d,e);
}
int main()
{
    int a,b,c,all;
    cin>>a>>b>>c;
    int Min=minn(a,b,c);
    a-=Min;
    b-=Min;
    c-=Min;
    if(c==0)
    {
        if(a!=b)
        {
            int Min1=min(a,b);
            a-=Min1;
            b-=Min1;
            int cnt=Min+1;
            //cout<<a<<" "<<b<<endl;
            //cout<<Min<<" "<<Min1<<" "<<cnt<<endl;
            if(cnt>=cal(a,b))
            {
                cout<<cal(a,b)+3*Min+2*Min1;
            }
            else
                cout<<cnt+3*Min+2*Min1;
        }
        else
        {
            int Min1=a;
            cout<<3*Min+2*Min1;
        }
    }
    else if(b==0)
    {
        if(a!=c)
        {
            int Min1=min(a,c);
            a-=Min1;
            c-=Min1;
            int cnt=Min+1;
            if(cnt>=cal(a,c))
            {
                cout<<cal(a,c)+3*Min+2*Min1;
            }
            else
                cout<<cnt+3*Min+2*Min1;
        }
        else
        {
            int Min1=a;
            cout<<3*Min+2*Min1;
        }
    }
    else if(a==0)
    {
        if(c!=b)
        {
            int Min1=min(c,b);
            c-=Min1;
            b-=Min1;
            int cnt=Min+1;
            if(cnt>=cal(c,b))
            {
                cout<<cal(c,b)+3*Min+2*Min1;
            }
            else
                cout<<cnt+3*Min+2*Min1;
        }
        else
        {
            int Min1=b;
            cout<<3*Min+2*Min1;
        }
    }
    return 0;
}

 

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值