C LCS
题意
构造三个长度为 n n n 的字符串 s 1 , s 2 , s 3 s_1,s_2,s_3 s1,s2,s3 ,使得 L C S ( s 1 , s 2 ) = a , L C S ( s 2 , s 3 ) = b , L C S ( s 1 , s 3 ) = c LCS(s_1,s_2)=a,LCS(s_2,s_3)=b,LCS(s_1,s_3)=c LCS(s1,s2)=a,LCS(s2,s3)=b,LCS(s1,s3)=c
可以发现将 s 1 , s 2 , s 3 s_1,s_2,s_3 s1,s2,s3 具有相同部分的长度为 L C S ( s 1 , s 2 , s 3 ) = m i n ( a , b , c ) LCS(s_1,s_2,s_3)=min(a,b,c) LCS(s1,s2,s3)=min(a,b,c),将这一段字符设为相同,之后对 s 1 , s 2 , s 3 s_1,s_2,s_3 s1,s2,s3 两两之间相同的部分加上分别在后面加入不同的相同字符即可,最后对每个长度小于 n n n 的字符串在补全即可。
#include <bits/stdc++.h>
using namespace std;
#define rep(i, j, k) for (ll(i) = (j); (i) <= (k); (++i))
typedef long long ll;
signed main() {
int a, b, c, n;
cin >> a >> b >> c >> n;
string s1, s2, s3;
int minx = (min(a, min(b, c)));
a -= minx, b -= minx, c -= minx;
// 三个相同的部分
rep(i, 1, minx) s1 += 'o', s2 += 'o', s3 += 'o';
// 两两之间相同的部分
while (a--)
s1 += 'x', s2 += 'x';
while (b--)
s2 += 'y', s3 += 'y';
while (c--)
s3 += 'z', s1 += 'z';
if (s1.size() > n || s2.size() > n || s3.size() > n)
return cout << "NO\n", 0;
// 补全字符串
while (s1.size() < n)
s1 += 'a';
while (s2.size() < n)
s2 += 'b';
while (s3.size() < n)
s3 += 'c';
cout << s1 << '\n' << s2 << '\n' << s3 << endl;
return 0;
}
F Just a joke
题意
Alice and Bob 在玩游戏
现在有一张 n n n 个点 m m m 条边无向图,两个操作:选择图中的一条边将他删除 或 选择图中的一个无环连通块将它删除。
Alice 先手。当到某个玩家的回合时,不能对图进行操作时,就输了。
假设,Alice and Bob 不采用最优的解法,那么游戏最多操作数为 n + m n+m n+m (先删所有的边,再删所有的点)
在一种操作下,每轮操作后,操作数 − 1 -1 −1
那么对于采用第二个操作,假设删去的连通块中有 k k k 个点 那么对应的有 k − 1 k-1 k−1 条边,即操作数 − 2 n + 1 -2n+1 −2n+1
可以发现,无论选择哪种操作,剩余的操作数的奇偶性不变
#include <bits/stdc++.h>
using namespace std;
#define rep(i, j, k) for (ll(i) = (j); (i) <= (k); (++i))
typedef long long ll;
signed main() {
int n, m, x, y;
cin >> n >> m;
rep(i, 1, m) cin >> x >> y;
if ((n + m) & 1)
puts("Alice");
else
puts("Bob");
return 0;
}