Educational Codeforces Round 100 (Rated for Div. 2)补题记录

总结:感觉这个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;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值