AtCoder Beginner Contest 043
A
\(\sum_{i = 1}^{n} i = \binom{n + 1}{2}\) 。
B
题意:
输入一个字符串。从左到右若有一个 \(B\) ,则 \(B\) 会把自己和右边一个字符(可能是空字符)删除。
询问最终字符。
题解:
栈。
std::string s; std::cin >> s;
std::string ans = "";
for (int i = 0; i < s.size(); i++) {
if (s[i] == 'B') {
if (ans.size() != 0) ans.pop_back();
}
else {
ans.push_back(s[i]);
}
}
std::cout << ans << "\n";
C
题意:
给定 \(n\) 个数 \(a_1, a_2, \cdots, a_n\) 。找到 \(x\) 使得所有 \(a_i\) 变为 \(x\) 花费代价最少。\(a_i\) 变为 \(x\) 花费代价为 \((a_i - x)^2\) 。
\(-100 \leq a_i \leq 100\) 。
题解:
找到最大最小的 \(a_i\) 为 \(MX, MI\) ,容易证明 \(x > MX, x < MI\) 显然不是最优解。
证明:
- 若 \(x > MX\) ,显然 \(x^{'} = MX\) 比 \(x\) 优。
- 若 \(x < MI\) ,显然 \(x^{'} = MI\) 比 \(x\) 优。
\(\square\)
暴力思路是枚举 \([MI, MX]\) 。
假设 \(a_i \in [-10^{9}, 10^{9}]\) 。应该使用什么算法?
\(\sum_{i = 1}^{n} (a_i - x)^{2} = Ax^{2} + Bx + C\) 是极其显然的一元二次函数,要么单峰要么单谷。
可以深入证明,但很容易通过特列反证是个单谷函数。
于是三分即可。
不容易列出多项式时。一种单谷函数的证明反向为:只需证明实数定义域内答案的唯一性。
这时候一种角度是:存在性显然,进而可以假设答案大于等于两个从而反证。一般会选取最左和最右的答案。
另一种角度是:某个答案两侧严格单调。
无法轻易证明时,但直觉上答案唯一时可以尝试三分,用评测机证明。
D
题意:
给定一个字符串 \(s\) 。定义它是不平衡的当且仅当 \(s\) 的长度不少于 \(2\) ,且某个字符出现次数 \(cnt\) 满足 \(cnt > \frac{len}{2}\) 。
这个转化即 \(cnt \geq \lfloor \frac{len}{2} \rfloor + 1\) 。
现在给一个字符串 \(s\) ,输出它任意一个子串的首尾位置。(从 \(1\) 开始编号)
\(1 \leq |s| \leq 10^{5}\) 。
题解:
如果一个字符串 \(s\) 是 \(unbalance\) 的,不妨定义出现次数 \(cnt \geq \lfloor \frac{len}{2} \rfloor + 1\) 的字符是 \(c\) ,不妨称 \(s\) 是 \(c\_unbalance\) 的。
则从 \(s\) 的端点处去除两个字符,依旧会是 \(c\_unbalance\) 的。显然 \(c\) 最多被去除两个,长度严格会减少二。若 \(cnt \geq \lfloor \frac{len}{2} \rfloor + 1\) ,一定有 \(cnt - 1 \geq \lfloor \frac{len}{2} \rfloor\) 。
已知 \(s\) 的字符串长度至少为 \(2\) ,则若存在 \(s\) ,一定存在一个 \(len = 2\ or\ 3\) 的 \(unbalance\) 串。
由于只需找任意一个答案,这时候问题已经显然,暴力去找长度为 \(2, 3\) 的串即可。
std::string s; std::cin >> s;
for (int i = 0; i < (int)s.size() - 2 + 1; i++) {
std::string tmp = s.substr(i, 2);
if (tmp[0] == tmp[1]) {
std::cout << i + 1 << " " << i + 2 << "\n";
return;
}
}
for (int i = 0; i < (int)s.size() - 3 + 1; i++) {
std::string tmp = s.substr(i, 3);
std::set<char> px; px.insert(tmp[0]); px.insert(tmp[1]); px.insert(tmp[2]);
if (px.size() <= 2) {
std::cout << i + 1 << " " << i + 3 << "\n";
return;
}
}
std::cout << -1 << " " << -1 << "\n";
长度为 \(2\) 时候 \(cnt \geq \lfloor \frac{2}{1} \rfloor + 1\) 的 \(cnt = 2\) 。
长度为 \(3\) 时候 \(cnt \geq 2\) 。这里是容斥出现种类,如果出现种类 \(\leq 2\) ,一定至少有两个字符相等。
浙公网安备 33010602011771号