这场难度跨度好大 感觉前四题好简单 手速题 后两题一点思路都无
A. Mocha and Math
题意是对于可以任取的一个区间内 元素可以对偶进行&运算 即由两边到中间 两边可以进行与运算 而且可以操作无数次 对于任意两个元素的& 都会使得变小或不变 所以可以从头到尾依次取&
代码
#include <bits/stdc++.h>
using namespace std;
const int N = 40;
int n, m;
int main()
{
int T;
scanf("%d", &T);
while (T -- )
{
scanf("%d", &n);
int ans = -1;
for (int i = 1; i <= n; i ++ )
{
cin >> m;
if (ans == -1) ans = m;
ans &= m;
}
printf("%d\n", ans);
}
return 0;
}
B. Mocha and Red and Blue
先找到第一个不是?的 然后从它往后遍历 如果有问号的 就和前面的取反 再从后往前遍历 同样?取反 这样是最优的
代码
#include <bits/stdc++.h>
using namespace std;
const int N = 110;
int n, m;
string s;
int main()
{
int T;
scanf("%d", &T);
while (T -- )
{
cin >> n >> s;
int t = 0;
while (s[t] == '?') t ++ ;
for (int i = t; i < n; i ++ )
if (s[i] == '?') s[i] = s[i - 1] == 'R' ? 'B' : 'R';
for (int i = n - 1; i >= 0; i -- )
if (s[i] == '?') s[i] = s[i + 1] == 'R' ? 'B' : 'R';
cout << s << endl;
}
return 0;
}
C. Mocha and Hiking
分类讨论
如果第一个a为1 则为 n+1 -> 1 -> 2 -> ··· -> n
如果最后一个a为0 则为1 -> 2 -> ··· -> n -> n+1
若都不是 则在序列中寻找 前面一项为0后面一项为1的 从i连向n+1 再连回i+1
代码
#include <bits/stdc++.h>
using namespace std;
const int N = 10010;
int n, m;
int a[N];
string s;
int main()
{
int T;
scanf("%d", &T);
while (T -- )
{
scanf("%d", &n);
for (int i = 1; i <= n; i ++ ) scanf("%d", &a[i]);
if (!a[n])
for (int i = 1; i <= n + 1; i ++ )
cout << i << " \n"[i == n + 1];
else
{
if (a[1])
{
printf("%d", n + 1);
for (int i = 1; i <= n; i ++ )
printf(" %d", i);
puts("");
}
else
{
for (int i = 1; i < n; i ++ )
{
if (!a[i] && a[i + 1])
{
for (int j = 1; j <= i; j ++ ) printf("%d ", j);
printf("%d", n + 1);
for (int j = i + 1; j <= n; j ++ ) printf(" %d", j);
puts("");
break;
}
}
}
}
}
return 0;
}
D1. Mocha and Diana (Easy Version)
用并查集来防止加边后成环 或者加边时另一条边已有这条边
#include <bits/stdc++.h>
#define x first
#define y second
using namespace std;
typedef pair<int, int> PII;
const int N = 1010;
int n, m1, m2;
int p[N], q[N];
PII ans[N];
int findp(int u)
{
if (u != p[u]) p[u] = findp(p[u]);
return p[u];
}
int findq(int u)
{
if (u != q[u]) q[u] = findq(q[u]);
return q[u];
}
int main()
{
scanf("%d%d%d", &n, &m1, &m2);
for (int i = 1; i <= n; i ++ ) p[i] = i, q[i] = i;
while (m1 -- )
{
int a, b;
scanf("%d%d", &a, &b);
int pa = findp(a), pb = findp(b);
if (pa != pb) p[pa] = pb;
}
while (m2 -- )
{
int a, b;
scanf("%d%d", &a, &b);
int pa = findq(a), pb = findq(b);
if (pa != pb) q[pa] = pb;
}
int cnt = 0;
for (int i = 1; i <= n; i ++ )
for (int j = 1; j <= n; j ++ )
{
int pa = findp(i), pb = findp(j);
int qa = findq(i), qb = findq(j);
if (pa == pb || qa == qb) continue;
ans[++ cnt] = {i, j};
p[pa] = pb, q[qa] = qb;
}
printf("%d\n", cnt);
for (int i = 1; i <= cnt; i ++ )
printf("%d %d\n", ans[i].x, ans[i].y);
return 0;
}