传送门:P10330 [UESTCPC 2024] 黑白珠串

更佳的阅读体验:洛谷 P10330 题解


简要题意:构造一个存在长度为 $x_i$ 且包含 $y_i$ 个 $\texttt{1}$ 的最短的 $\texttt{01}$ 串,并给出每个子串开始的位置。

可以想到,我们只需要构造一个前半段全是 $\texttt{1}$,后半段全是 $\texttt{0}$ 的字符串即可。这样,每个子串都在这个 $\texttt{01}$ 串中间,包含几个 $\texttt{1}$ 和几个 $\texttt{0}$,就可以使得这个 $\texttt{01}$ 串最短。

我们设 $\texttt{1}$ 的个数为 $m_1$,$\texttt{0}$ 的个数为 $m_0$,则有 $m_1 = \max \limits_{i = 1}^{k} y_i$,$m_0 = \max \limits_{i = 1}^{k} (x_i - y_i)$,满足第 $i$ 个条件的子串从 $m_1 - y_i$ 开始。

#include <iostream>
using namespace std;

const int N = 1e5 + 10;
int k, x[N], y[N], m0, m1;

int main() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    cin >> k;
    for (int i = 1; i <= k; ++i) {
        cin >> x[i] >> y[i];
        m0 = max(m0, x[i] - y[i]), m1 = max(m1, y[i]);
    } cout << m0 + m1 << '\n';
    for (int i = 1; i <= m1; ++i) cout << 1;
    for (int i = 1; i <= m0; ++i) cout << 0;
    cout << '\n';
    for (int i = 1; i <= k; ++i) cout << m1 - y[i] << '\n';
    return 0;
}
最后修改:2024 年 04 月 07 日
如果觉得我的文章对你有用,请随意赞赏