比赛链接
A - flip
题意:
给你一个01串,把其中的0换成1,1换成0,然后输出.
参考代码:
void solve() {
std::string s;
std::cin >> s;
for (char c : s)
std::cout << (!(c - '0'));
}
void solve() {
std::string s;
std::cin >> s;
for (auto &c : s)
c ^= 1;
std::cout << s;
}
B - V
题目大意:
对于每个最长连通块,把其中的元素逆序输出.
参考代码:
void solve() {
int n, m;
std::cin >> n >> m;
std::vector<bool> a(n - 1);
for (int i = 0; i < m; i++) {
int x;
std::cin >> x;
x--;
a[x] = true;//标记一下
}
for (int i = 0; i < n;) {
int j = i;
//用于遍历连通块的指针
while (j < n - 1 && a[j]) {
j++;
}
for (int x = j; x >= i; x--) {
std::cout << x + 1 << ' ';
}
i = j + 1;
//从当前连通块后面开始遍历
}
std::cout << '\n';
}
C - Coverage
题目大意:
这里有m个集合,每次选取若干个,问有多少种方案可以满足:选择的所有集合的并集可以覆盖1-n这n个整数.
思路:
状态压缩枚举子集.
参考代码:
void solve() {
int n, m;
std::cin >> n >> m;
std::vector<int> a(m);
for (int i = 0; i < m; i++) {
int c;
std::cin >> c;
for (int j = 0; j < c; j++) {
int x;
std::cin >> x;
x--;
a[i] |= 1 << x;
}
}
int ans = 0;
for (int s = 1; s < (1 << m); s++) //枚举子集
{
int res = 0;
for (int i = 0; i < m; i++) {
if (s >> i & 1) {
res |= a[i];
}
}
if (res == (1 << n) - 1) {
ans++;
}
}
std::cout << ans << "\n";
}
D - Step Up Robot
题意:
初始时,在楼梯的位置0有一个机器人,机器人每一步可以向上走 a [ i ] 的距离,楼梯上有m个障碍,每一个障碍对于机器人都无法到达,问能否到达点 x ?
思路:
动态规划.
参考代码:
void solve() {
int n;
std::cin >> n;
std::vector<int> a(n);
for (int i = 0; i < n; i++) {
std::cin >> a[i];
}
int m;
std::cin >> m;
std::vector<int> b(m);
for (int i = 0; i < m; i++) {
std::cin >> b[i];
}
int x;
std::cin >> x;
std::vector<int> dp(x + 1);
std::vector<bool> trap(x + 1);
for (auto i : b) {
trap[i] = true;
//把障碍标记为true
}
dp[0] = 1;
for (int i = 1; i <= x; i++) {
if (trap[i])
continue;
for (auto d : a) {
if (d <= i)
dp[i] |= dp[i - d];
}
}
//dp[i]=true:位置i可以到达.
//dp[i]=false:位置i无法到达.
if (dp[x]) {
std::cout << "Yes\n";
} else {
std::cout << "No\n";
}
}