B. 二进制串转回文串
本文最后更新于34 天前,其中的信息可能已经过时,如有错误请发送邮件到big_fw@foxmail.com

好的,明白了。我严格保持你提供的所有内容不变,只做格式整理(标题、代码块、公式符号等),不修改任何文字和代码。


Codeforces 题目链接

B. 二进制串转回文串

  • 每次测试时间限制:1 秒
  • 内存限制:256 MB

题目描述

给定一个长度为 $n$ 的二进制字符串 $b$。

请构造一个长度为 $n$、由小写英文字母组成的字符串 $s$,使得对于每个 $i$($1 \le i \le n$),满足:

  • 若 $b_i = 1$,则 $s$ 中所有长度为 $i$ 的子串都是回文串;
  • 若 $b_i = 0$,则 $s$ 中至少有一个长度为 $i$ 的子串不是回文串。

输出满足条件的字典序最小的字符串 $s$。如果不存在这样的字符串,输出 $-1$。


子串定义

字符串 $x$ 是字符串 $y$ 的子串,如果 $x$ 可以通过删除 $y$ 开头若干(可能为零或全部)个字符和结尾若干(可能为零或全部)个字符得到。例如,bcabcd 都是 abcd 的子串,而 acba 不是。

回文串定义

一个字符串是回文串,当且仅当它从左向右读和从右向左读完全相同,即字符串的逆序等于原串。例如,aabaabba 是回文串,而 ababc 不是。

字典序定义

字符串 $x$ 比字符串 $y$ 字典序更小,当且仅当:

  • $x$ 是 $y$ 的真前缀,或
  • 存在某个位置 $i$($1 \le i \le \min(|x|, |y|)$),使得 $x_i < y_i$,并且对于所有 $j < i$,都有 $x_j = y_j$。

输入格式

第一行包含一个整数 $t$($1 \le t \le 10^4$)—— 测试用例数。

每个测试用例的第一行包含一个整数 $n$($1 \le n \le 3 \times 10^5$)—— 字符串 $b$ 的长度。

第二行包含一个长度为 $n$ 的二进制字符串 $b$,由字符 01 组成。

保证所有测试用例的 $n$ 之和不超过 $3 \times 10^5$。


输出格式

对于每个测试用例,输出一行:若存在合法字符串,则输出字典序最小的 $s$;否则输出 $-1$。


示例

输入

3
2
10
3
001
4
1111

输出

ab
-1
aaaa

示例说明

  • 第一个测试用例:$b = 10$。长度为 $1$ 的所有子串都必须是回文串(单个字符总是回文),而长度为 $2$ 的唯一子串必须不是回文串。字典序最小的满足条件的字符串是 ab
  • 第二个测试用例:$b = 001$。由于 $b_1 = 0$,但单个字符总是回文串,因此不存在合法字符串,输出 $-1$。
  • 第三个测试用例:$b = 1111$。所有长度的所有子串都必须是回文串。字典序最小的满足条件的字符串是 aaaa

思路

这道题很巧妙
我们注意到一个字符,自己一定是回文,一定符合条件
而且如果连续两个字符相同,那么连续两个字符是 $aa$ 第二个和第三个是 $aa$,结果就是连续三个字符也相同,以此类推最后会得到一个全是 $1$ 的情况,对应下列情况1
这道题可以通过分类讨论得出答案

  1. s = $111111$ 任意长度子串都相同,所以最终答案就是 $aaaaaaaa$
  2. s = $101010$ 偶数是 $0$,奇数是 $1$,所以最终答案是 $abababab$
  3. s = $100000$ 所以只有一个字符是符合的,所以答案是 $aaaaaaab$
  4. s = $100001$ 所以一个字符和全选是回文,所以答案是 $aaaaabbaaaaa$ 或者 $aaaaaaabaaaaaa$

代码

//Sunshine sunshine ladybugs awake,
//Clap your hooves and do a little shack.

#include <bits/stdc++.h>
#define int long long
#define endl "\n"

using namespace std;

using PII = pair<int, int>;
const int MAXN = 300005;
const int mod = 998244353;
const int INF = 0x3f3f3f3f3f3f3f3f;

int n;
string s;

// 情况1: b 全为 '1'
bool case1() {
    string type1(n, '1');
    if (s == type1) {
        cout << string(n, 'a') << endl;
        return true;
    }
    return false;
}

// 情况2: b 为 "1010..."(偶数索引为 '1')
bool case2() {
    string type2(n, '0');
    for (int i = 0; i < n; i++) {
        if (i % 2 == 0) {
            type2[i] = '1';
        }
    }
    if (s == type2) {
        for (int i = 0; i < n; i++) {
            cout << (i % 2 == 0 ? 'a' : 'b');
        }
        cout << endl;
        return true;
    }
    return false;
}

// 情况3: b 为 "100...0"(仅第一个字符为 '1')
bool case3() {
    string type3 = string(n, '0');
    type3[0] = '1';
    if (s == type3) {
        for (int i = 0; i < n - 1; i++) {
            cout << "a";
        }
        cout << "b" << endl;
        return true;
    }
    return false;
}

// 情况4: b 为 "100...001"(首尾为 '1',中间全 '0')
bool case4() {
    string type4(n, '0');
    type4[0] = '1';
    type4[n - 1] = '1';
    if (s == type4) {
        string ans = string(n, 'a');
        // 将中间两个位置改为 'b',使得整个串不是回文
        ans[(n - 1) / 2] = 'b';
        ans[n / 2] = 'b';
        cout << ans << endl;
        return true;
    }
    return false;
}

void solve() {
    cin >> n >> s;

    if (case1()) return;
    if (case2()) return;
    if (case3()) return;
    if (case4()) return;

    cout << "-1" << endl;
}

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int t;
    cin >> t;
    while (t--) {
        solve();
    }
    return 0;
}
文末附加内容
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇