1. Codeforces Round 1081 (Div.2) 题解与思考
作为一名算法竞赛选手,参加Codeforces比赛是提升编程能力的重要途径。最近我参加了Codeforces Round 1081 (Div.2)的比赛,虽然只AC了A题,但通过赛后补题,对B-E题的解法有了深入理解。本文将详细解析这五道题的解题思路和实现细节,希望能帮助到同样在算法竞赛道路上探索的朋友们。
1.1 A. String Rotation Game
这道题要求我们对字符串进行循环旋转,使得相邻相同字符的数量最大化。题目看似简单,但需要考虑旋转过程中得分变化的规律。
1.1.1 问题分析
给定一个字符串s,我们可以进行任意次数的循环旋转操作。每次旋转将字符串最后一个字符移动到第一个位置。得分定义为字符串中相邻相同字符的对数。例如,"aabb"的初始得分为2(aa和bb)。
关键观察点:
- 初始得分可以通过遍历字符串直接计算
- 每次旋转时,如果首尾字符相同,旋转后会破坏这对相邻字符,得分减1
- 如果新移动到首位的字符与其后字符相同,得分加1
1.1.2 算法实现
cpp复制#include<iostream>
#include<string>
using namespace std;
int main() {
int t, n;
cin >> t;
while (t--) {
cin >> n;
string s;
cin >> s;
int Size = s.size();
int brick = 1;
for (int i = 0; i < Size-1; ++i) {
if (s[i] != s[i + 1]) {
++brick;
}
}
int cur = brick;
int res = brick;
bool flag = 0;
if (s[0] == s[Size - 1]) {
flag = 1;
}
for (int i = Size - 1; i >= 1; --i) {
cur = brick;
if (s[i-1] == s[i]) {
++cur;
}
if(flag){
--cur;
}
res = max(cur, res);
}
cout << res << endl;
}
}
1.1.3 复杂度分析
时间复杂度:O(n^2),其中n是字符串长度。对于每个测试用例,我们需要遍历字符串两次。
空间复杂度:O(1),只使用了常数级别的额外空间。
注意:在实际比赛中,对于n≤1000的数据规模,这个复杂度是完全可接受的。但如果n更大,可能需要寻找线性解法。
1.2 B. Flipping Binary String
这道题要求我们通过特定操作将二进制字符串转换为全0字符串。操作规则是:选择一个位置,翻转除该位置外的所有字符。
1.2.1 问题分析
关键观察点:
- 每个字符被翻转的次数等于不被选中的次数
- 对于偶数长度的字符串,总能通过适当操作得到全0字符串
- 对于奇数长度的字符串,当且仅当1的个数为偶数时才可能有解
解题思路:
- 统计字符串中0和1的个数
- 根据字符串长度和1的个数的奇偶性决定操作方案
- 输出需要翻转的位置索引
1.2.2 算法实现
cpp复制#include<iostream>
#include<vector>
#include<string>
#define int long long
using namespace std;
signed main() {
int t, n;
cin >> t;
while (t--) {
cin >> n;
string m;
int zero = 0;
int one = 0;
vector<int>list_zero;
vector<int>l
