总结:感觉这个educational场好难啊(蒟蒻视角),又被虐了,唉
A. Dungeon
- 每一枪会造成1点伤害对一个单位,但是当开7的倍数枪时会造成3点伤害
- 每7次一个轮回,一个完整的轮回共造成9点伤害,如果最后一起死,那个最小值至少需要承受每个轮回的1点伤害
#include <bits/stdc++.h>
#define lowbit(x) ((x) & (-x))
using namespace std;
typedef long long ll;
int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif
int t;
cin >> t;
while (t--) {
int a, b, c;
cin >> a >> b >> c;
int min1 = min(a, min(b, c));
ll sum = a + b + c;
if (sum % 9 == 0 && min1 >= sum / 9) cout << "YES" << endl;
else cout << "NO" << endl;
}
return 0;
}
B - Find The Array
- 哇,这个题可真是够难,想不出来
- 最后经大神提醒,每个数直接取他的二进制最高位就可以,既保证了倍数,又保证了总和不会超过原来的一半
#include <bits/stdc++.h>
#define lowbit(x) ((x) & (-x))
using namespace std;
typedef long long ll;
const int N = 100;
int a[N], b[N];
int solve(int x) {
int cnt = 0;
while (x) {
cnt++;
x >>= 1;
}
return 1 << (cnt - 1);
}
int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif
int t;
cin >> t;
while (t--) {
int n;
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a[i];
b[i] = solve(a[i]);
}
for (int i = 1; i <= n; i++) {
if (i != 1) cout << " ";
cout << b[i];
}
cout << endl;
}
return 0;
}
C - Busy Robot
模拟题
- 最后的时间时是正无穷
- 一个命令若是要执行成功,那么必须在下一个命令要求的时间之前(包括端点)到达这个命令的终点
- 一个命令执行时,会忽略在此期间发过来的命令(虽然被忽略,但是也可能成功执行,符合上一个条件即可)
- 一个被忽略的命令若想成功执行,则至少需要包含在正在行进的路径中
#include <bits/stdc++.h>
#define lowbit(x) ((x) & (-x))
using namespace std;
typedef long long ll;
const int N = 1e5 + 10;
const int inf = 0x3f3f3f3f;
#define int long long
struct node {
ll t, pos;
}e[N];
int book[N];
signed main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif
int t;
scanf("%lld", &t);
while (t--) {
int n;
scanf("%lld", &n);
memset(book, 0, sizeof book);
for (int i = 1; i <= n; i++) scanf("%lld%lld", &e[i].t, &e[i].pos);
e[n + 1].t = 1e18;
int cnt = 0, st = 0;
for (int i = 1; i <= n; i++) {
if (!book[i]) {
book[i] = 1;
if ((e[i + 1].t - e[i].t >= abs(e[i].pos - st))) cnt++;
int ed = e[i].t + abs(e[i].pos - st);
int j = i + 1;
while (j <= n && e[j].t < ed) {
book[j] = 1;
int flag = 0;
if (e[j].pos >= st && e[j].pos <= e[i].pos) flag = 1;
if (e[j].pos >= e[i].pos && e[j].pos <= st) flag = 1;
if (flag && (e[j].t - e[i].t) <= abs(e[j].pos - st) && (e[i].t + abs(e[j].pos - st) <= e[j + 1].t)) cnt++;
j++;
}
st = e[i].pos;
}
}
printf("%lld\n", cnt);
}
// return 0;
}
D - Pairs
这位大佬的思路 https://blog.csdn.net/ANTFANAAA/article/details/111351485
也是模拟题
- 有些点只能作为最小值出现
- 有些点只能作为最大值出现
- 有些点既能作为最小值,也能作为最大值
- 那么怎么求重合的这部分呢?那就是ans1 + ans2 - n
- 最终是求最小值包含的数的所有情况,那就是 重合部分 + 初始值(也就是1)
#include <bits/stdc++.h>
#define lowbit(x) ((x) & (-x))
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
// #define int long long
const int N = 1e6 + 10;
int book[N], a[N];
int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif
int t;
scanf("%d", &t);
while (t--) {
int n;
scanf("%d", &n);
set<int> v1, v2;
for (int i = 1; i <= 2 * n; i++) book[i] = 0;
for (int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
book[a[i]] = 1;
}
for (int i = 1; i <= 2 * n; i++) {
if (!book[i]) {
v1.insert(i);
v2.insert(i);
}
}
int ans1 = 0, ans2 = 0;
for (int i = 1; i <= n; i++) {
auto t1 = v1.lower_bound(a[i]);
auto t2 = v2.lower_bound(a[i]);
if (t1 != v1.end()) {
ans1++;
v1.erase(t1);
}
if (t2 != v2.begin()) {
ans2++;
t2--;
v2.erase(t2);
}
}
printf("%d\n", (ans1 + ans2 - n) + 1);
}
return 0;
}