题意
要求输出一个只含有4和7的字符串满足: 只有a1个4,a2个7,a3个47,a4个74 不可能则输出-1 输入格式为: 一排四个数分别为a1,a2,a3,a4
分析:
首先我们看一下47和74的关系,474444 这样47和74的数量是一样的, 4747 这样47比74多一个,没有多两个的情况,所以我们可以先比较这两个的数量,判断一下是否可能有答案。
其次:我们看47与74最少怎么组成,因为我们组成47和74之后可以把多的7或者4放到对应的位置上,就是让原本组成47,74的位置上让其重复即可。
然后我们看如果47比74多的话一定时候4747这样的4在前,7在后。如果74多的话就是7在前,4在后。然后相等我们先用4747试下,因为要满足最小。
然后 通过组数求出最少需要的4和7的数量。 数量不够肯定这样不行。
之后我们循环找到第一个放4的地方直接将剩余的4也都放到这个位置上,保证最优最小,同样我们把剩余的7放到最后的7那个地方。
ll num_4, num_7, num_47, num_74;
bool solve()
{
if(abs(num_47 - num_74) > 1) return false;///最多相差1 否则一定构不成
for(int top = 4; top < 8; top += 3)
{
if(top == 4 && num_47 < num_74) continue; ///4开头但是 74的数量多 ,所以不行
if(top == 7 && num_47 > num_74) continue; ///同理
ll m4 = (top == 4 ? 1 : 0) + num_74;/// 需要4的数量
ll m7 = (top == 7 ? 1 : 0) + num_47;/// 需要7的数量
if(m4 > num_4 || m7 > num_7) continue; ///数量不够
ll sum = num_47 + num_74 + 1; ///构成符合47和74需要多长
ll yu4 = num_4 - m4; ///还剩多少4
ll yu7 = num_7 - m7; ///还剩多少7
for(int i = 0; i < sum; i++)
{
int p = ((top == 4) ^ (i % 2 == 0) ^ 1) ? 4 : 7;// 该放什么了
printf("%d", p);
if(i <= 1 && p == 4)//只有前两个放4是最优的方案
for (int i = 0; i < yu4; ++i)
{
printf("4");///顺着把4全放上面
}
if (i >= sum - 2 && p == 7)///只有最后连个放7是最优方案
{
for (int i = 0; i < yu7; ++i)
{
printf("7");///顺着把7全部放上
}
}
}
puts("");
return true;
}
return false;
}