题解:B4371 [GXPC-S 2025] 序列 / sequence
Solution
我们需要构造一个由
-
所有子段的
K 的最大值恰好为k ,其中K 是子段中0 的数量减去子段中1 的数量。 -
在所有满足条件的字符串中,选择字典序最小的那个。
要构造满足条件的字符串,我们需要确保贪心:
-
字典序最小的字符串应该尽可能将
0 放在前面。 -
为了确保所有子段的
K 的最大值是k ,我们需要控制0 和1 的分布,避免出现某个子段的K 超过k 。 -
特别地,最长的连续
0 的子段会贡献最大的K 值。因此,我们可以先放置k 个连续的0 ,这样这些0 的子段的K 就是k 。 -
然后,我们需要确保其他子段的
K 不超过k 。可以通过交替放置1 和0 来实现这一点。
构造方法:
-
首先放置
k 个0 。这样,这k 个0 的子段的K 就是k 。 -
然后,将剩余的
0 和1 以10 的形式交替放置。这样,每个10 对的K 是1 - 1 = 0 ,不会增加K 的最大值。 -
最后,如果还有剩余的
1 ,直接放在末尾。因为1 会减少K ,所以不会影响最大值。
代码其实很短。
AC code
#include<bits/stdc++.h>
using namespace std;
int n,m,k;
int main()
{
cin>>n>>m>>k;
for(int i=1;i<=k;i++)// 第一步:输出 k 个 0
cout<<0;
m -= k; // 剩余的 0 的数量
for(int i=1;i<=m;i++) // 第二步:交替输出 1 和 0,每次输出 "10",共 m 次
cout<<10;
n -= m; // 剩余的 1 的数量
for(int i=1;i<=n;i++)// 第三步:输出剩余的 1
cout<<1;
return 0;
}