A. Opponents(Codeforces 688A)
思路
用
cnt[i]
表示第
i
天主人公是否获胜(
代码
#include <bits/stdc++.h>
using namespace std;
const int maxd = 110;
int n, d, cnt[maxd];
string s;
int main() {
cin >> n >> d;
for(int i = 0; i < d; i++) {
cin >> s;
for(int j = 0; j < s.size(); j++) {
if(s[j] == '0') {
cnt[i] = 1;
break;
}
}
}
for(int i = 1; i < d; i++) {
if(cnt[i-1] > 0 && cnt[i] > 0) {
cnt[i] += cnt[i-1];
}
}
cout << (*max_element(cnt, cnt + d)) << endl;
return 0;
}
B. Lovely Palindromes(Codeforces 688B)
思路
第
1
个可爱回文是
代码
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6;
char s[maxn], t[maxn];
int n;
int main() {
scanf("%s", s);
n = strlen(s);
for(int i = 0; i < n; i++) {
t[i] = s[n-i-1];
}
t[n] = '\0';
strcat(s, t);
printf("%s\n", s);
return 0;
}
C. NP-Hard Problem(Codeforces 688C)
思路
题目要我们求图
代码
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 10;
bool ok = true;
int n, m, u, v, color[maxn];
vector <int> v1, v2, G[maxn];
// color[u]的值为1和2分别代表为u涂上两种不同的颜色
void dfs(int u, int c) {
for(int i = 0; i < G[u].size(); i++) {
int v = G[u][i];
// 如果下一个点没涂过色的话,为其涂上不同的颜色
if(color[v] == 0) {
color[v] = c ^ 3;
dfs(v, c ^ 3);
}
// 如果下一个点跟当前点颜色相同的话,失败返回
if(color[v] == c) {
ok = false;
return;
}
}
}
int main() {
scanf("%d%d", &n, &m);
for(int i = 0; i < m; i++) {
scanf("%d%d", &u, &v);
G[u].push_back(v);
G[v].push_back(u);
}
// 为每个连通分量涂色
for(int i = 1; i <= n; i++) {
if(color[i] == 0) {
color[i] = 1;
dfs(i, 1);
}
}
// 输出失败或A和B
if(ok == false) {
puts("-1");
}
else {
for(int i = 1; i <= n; i++) {
if(color[i] == 1) {
v1.push_back(i);
}
if(color[i] == 2) {
v2.push_back(i);
}
}
printf("%d\n", v1.size());
for(int i = 0; i < v1.size(); i++) {
printf("%d ", v1[i]);
}
printf("\n%d\n", v2.size());
for(int i = 0; i < v2.size(); i++) {
printf("%d ", v2[i]);
}
puts("");
}
return 0;
}
D. Remainders Game(Codeforces 688D)
思路
要解决这题,必须先了解一个叫做“中国剩余定理”的定理。定理的内容如下:
设 m1,m2,m3...mn 为互质的整数,
则同余方程组
x≡a1(modm1)
x≡a2(modm2)
......
x≡an(modmn)
在模M下有唯一的整数解x。
(M=m1⋅m2⋅...⋅mn)
反过来在本题中,若想得出 nmodk 的唯一解,就必须知道
nmodm1,nmodm2...nmodmn
(被模数n与小标n为不同的数,虽然题目存在歧义,但是这里仍按照题目的规定)
考虑题给条件,若 nmodc1,nmodc2...nmodcn 中含有上述信息的话,就能得出 nmodk 的唯一解。
为此,现将
n
分解为
若 对任意
i
有”
而上面加粗字体语句的充要条件是 lcm(c1,c2,...cn) 为 k 的倍数。
因此本题输出
代码
#include <bits/stdc++.h>
using namespace std;
long long n, k, a, lcm;
int main() {
scanf("%I64d%I64d", &n, &k);
lcm = 1;
while(n--) {
scanf("%I64d", &a);
lcm = a * lcm / __gcd(a, lcm);
lcm %= k;
}
puts(lcm ? "No" : "Yes");
return 0;
}
E. The Values You Can Make(Codeforces 688E)
思路
若只求有几种恰好组成
一种显然的思路是先搜索出一个满足条件的硬币子集
将
d[0][0][0]
初始化为
1
,最后
代码
#include <bits/stdc++.h>
using namespace std;
const int maxn = 505, maxk = 505;
int n, m, a, ans, d[maxk][maxk];
int main() {
scanf("%d%d", &n, &m);
d[0][0] = 1;
while(n--) {
scanf("%d", &a);
for(int i = m; i >= a; i--) {
for(int j = 0; j <= m; j++) {
d[i][j] |= d[i-a][j];
d[i][j] |= (j < a ? 0 : d[i-a][j-a]);
}
}
}
for(int j = 0; j <= m; j++) {
ans += d[m][j];
}
printf("%d\n", ans);
for(int j = 0; j <= m; j++) {
if(d[m][j] == 1) {
printf("%d ", j);
}
}
puts("");
return 0;
}