在马老板的难题里,最核心,最关键的地方在于让三种颜色的小球不相邻地排成一行。我们假设三种小球颜色数量分别为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;
}