AtCoder Beginner Contest 048
A
给三个字符串,输出三个字符串的首字母。
考虑加点难度,一次输入一个带空格串,输出前三个单词的首字母。
std::string s;
std::getline(std::cin, s);
std::string ans = "";
for (int i = 0, cnt = 3; cnt && i < (int)s.size(); i++) {
if (i == 0 || s[i - 1] == ' ') {
ans.push_back(s[i]);
cnt--;
}
}
std::cout << ans << "\n";
如果 getline 前有 cin ,回车不会被吃掉。这时候在 cin 后补一个 std::cin.get() 。
B
题意:
给 \(a, b, x\) ,询问有多少个 \(y \in [a, b]\) 满足 \(x \mid y\) 。
\(0 \leq a, b \leq 10^{18},1 \leq x \leq 10^{18}\) 。
题解:
一眼不会。
首先答案不是 \(\lfloor \frac{b - a + 1}{x} \rfloor\) ,连续 \(x\) 个数有且仅有一个会被 \(x\) 整除,但连续 \(z(z < x)\) 个数不一定不存在某个数被 \(x\) 整除。
其次答案不是 \(\lfloor \frac{b}{x} \rfloor - \lfloor \frac{a - 1}{x} \rfloor\) 。深究发现和上面的道理一样。
一种方法是:find 最小的 \(l \geq a\) 满足 \(x \mid l\) ,find 最大的 \(r \leq b\) 满足 \(x \mid r\) ,答案一定是 \((r - l) / x + 1\) 。
若 \(r - l \leq 0\) ,去掉左端点后,每 \(x\) 段有一个答案。最后补上左端点的答案。
若 \(r - l < 0\) ,\(r - l\) 一定是 \(-x\) ,因为 \(|r - l| = x\) 。+1 后答案依旧为 \(0\) 。
题解确实也是这种方法。
C
题意:
\(N, (N \leq 10^5)\) 个盒子排在一列,从左到右第 \(i\) 个盒子有 \(a_i\) 个糖果。。
选择以下操作任意次:吃掉某个盒子中的一个糖果(如果有)。
任务是用最小的操作,让任意相邻两个盒子的糖果之和不超过 \(x\) 。
题解:
不考虑边界,观察任意 \(i\) ,若 \(y = a_i + a_{i + 1} > x\) ,\(i\) 或 \(i + 1\) 的位置一定需要操作共 \(y - x\) 次。
变数在于 \(i\) 的操作会影响 \(i - 1\) ,\(i + 1\) 的操作会影响 \(i + 2\) 。
考虑边界,\(1, 2\) 如果需要操作,一定是 \(2\) 操作,因为操作 \(1\) 没有意义。不操作 \(2\) 没有意义,因为最终 \(2\) 还是要操作。
\(2, 3\) 需要操作,一定是 \(3\) 操作,因为操作 \(2\) 没有意义。不操作 \(3\) 没有意义,因为最终 \(3\) 还是要操作。
于是问题可以从一个端点单向迭代。或者说也可以证明每次随机 rand 一个端点迭代也是对的。
加点难度,如果一开始给的是一个环?如何用最小操作完成目标。
若开始存在 \(i\) 满足 \(a_i + a_{i + 1} \leq x\) ,则可以按照单调迭代做法。
若不存在 \(i\) 满足 \(a_i + a_{i + 1} \leq x\) ,且 \(\forall a_i \geq \lfloor \frac{x}{2} \rfloor\) 那么一定有 \(\sum_{i = 1}^{n} a_i^{'} = \lfloor \frac{nx}{2} \rfloor\) 。
再否则不是很好做。
D
题意:
给一个字符串 \(s(|s| \geq 3)\) ,任意相邻字不同。
\(Alice\) 和 \(Bob\) 在玩一个游戏,可以选取 \(s\) 中除了端点字符的一个字符移除,并且不能使新的 \(s\) 有相邻字符。
\(Alice\) 进行第一步操作,之后两人轮流操作。最后不能移除字符的玩家失败,询问谁能获得胜利。
题解:
平等博弈论其实有点 dp 思想的。
一类比较简单的博弈,终态可以被观察到且很少。
只考虑两个端点。有两种情况,xx 或 xy (不特指特定字符,指端点是否相等)。
如果局面是 xx ,则 win 。不在乎是否能到达这个局面。
于是 x?x lose 。不在乎是否能到达这个局面。
x??x win 。不在乎是否能到达这个局面。
x???x lose 。不在乎是否能到达这个局面。
...
初始局面一定可以到达,是 \(Alice\) 面临的。如果 ? 是偶数则 Alice win ,否则 Bob win 。
如果局面是 xy ,则 lose 。不在乎能否到达这个局面。
于是 x?y win 。不在乎能否到达这个局面。
x??y lose 。不在乎能否到达这个局面。
x???y win 。不在乎能否到达这个局面。
...
初始局面一定可以到达,是 \(Alice\) 面临的。如果 ? 是奇数则 Alcie win ,否则 Bob win 。
这里 Alice 赢则输出 First ,否则输出 Second 。
std::string s; std::cin >> s;
char a = s[0], b = s.back();
int n = (int)s.size() - 2;
if (a == b) std::cout << (n % 2 == 0 ? "First" : "Second") << "\n";
if (a != b) std::cout << (n % 2 == 1 ? "First" : "Second") << "\n";
浙公网安备 33010602011771号