Codeforces 883 Div. 3 题解 | JorbanS

A. Rudolph and Cut the Rope

题意 糖果上连着 n 个钉子,钉子的高度为 a[i],绳子长度为 b[i],求要剪短几个绳子才能使糖果掉落

#include <iostream>

using namespace std;

int solve() {
    int n; cin >> n;
    int res = 0;
    for (int i = 0; i < n; i ++) {
        int x, y; cin >> x >> y;
        if (x > y) res ++;
    }
    return res;
}

int main() {
    int T; cin >> T;
    while (T --) cout << solve() << endl;
    return 0;
}

B. Rudolph and Tic-Tac-Toe

题意 三人的井字棋,判断谁胜利,输出 X or O or +,平局则输出 DRAW

#include <iostream>

using namespace std;
const string str[3] = {"X", "O", "+"}; 
const char c[3] = {'X', 'O', '+'};

string solve() {
    string s[3];
    cin >> s[0] >> s[1] >> s[2];
    for (int i = 0; i < 3; i ++) {
        bool flag = false;
        for (int j = 0; j < 3; j ++) {
            if (s[j][0] == c[i] && s[j][1] == c[i] && s[j][2] == c[i])
                flag = true;
            if (s[0][j] == c[i] && s[1][j] == c[i] && s[2][j] == c[i])
                flag = true;
        }
        if (s[0][0] == c[i] && s[1][1] == c[i] && s[2][2] == c[i])
            flag = true;
        if (s[0][2] == c[i] && s[1][1] == c[i] && s[2][0] == c[i])
            flag = true;
        if (flag) return str[i];
    }
    return "DRAW";
}

int main() {
    int T; cin >> T;
    while (T --) cout << solve() << endl;
    return 0;
}

C. Rudolf and the Another Competition

题意 n 个人 mh 时长,已知每人做每道题的时长,根据 (做对题数, 罚时) 排名,求第一条记录对应的选手是第几名

罚时是累计计算的,即做对一题的已用时长

可能会爆 int,我这题当时就因此被 hack 了,悲(

#include <iostream>
#include <vector>
#include <algorithm>
#define aa first
#define bb second

using namespace std;
typedef pair<int, int> pii;
const int N = 2e5 + 2;
int a[N];
int n, m, h;

bool cmp(pii a, pii b) {
    if (a.aa == b.aa) return a.bb < b.bb;
    return a.aa > b.aa;
}

int solve() {
    cin >> n >> m >> h;
    vector <pii> v;
    for (int i = 0; i < m; i ++) cin >> a[i];
    sort(a, a + m);
    int xx = 0, yy = 0, zz = 0;
    for (int i = 0; i < m; i ++) {
        if (zz + a[i] <= h) {
            xx ++;
            zz += a[i];
            yy += zz;
        }
    }
    v.push_back({xx, yy});
    for (int i = 1; i < n; i ++) {
        for (int j = 0; j < m; j ++) cin >> a[j];
        sort(a, a + m);
        int x = 0, y = 0, z = 0;
        for (int i = 0; i < m; i ++) {
            if (z + a[i] <= h) {
                x ++;
                z += a[i];
                y += z;
            }
        }
        v.push_back({x, y});
    }
    sort(v.begin(), v.end(), cmp);
    for (int i = 0; i < n; i ++)
        if (v[i].aa == xx && v[i].bb == yy)
            return i + 1;
}

int main() {
    int T; cin >> T;
    while (T --) cout << solve() << endl;
    return 0;
}

D. Rudolph and Christmas Tree

题意 n 个三角形,d 为底边长,h 为高,都关于 y 轴对称,给定每个三角形底边对应的坐标 a[i],保证 a[i] < a[i + 1],重复面积只算一次,求所有覆盖的面积

#include <iostream>

using namespace std;
const int N = 2e5 + 2;
int n, d, h;
int a[N];

double solve() {
    cin >> n >> d >> h;
    for (int i = 0; i < n; i ++) cin >> a[i];
    a[n] = 2e9;
    double res = 0;
    double base = d * 0.5 * h;
    for (int i = 0; i < n; i ++) {
        int height = a[i + 1] - a[i];
        res += base;
        if (height < h) res -= base * (h - height) / h * (h - height) / h; 
    }
    return res;
}

int main() {
    int T; cin >> T;
    while (T --) printf("%.8lf\n", solve());
    return 0;
}

E1. Rudolf and Snowflakes (simple version)

题意 定义雪花图案,由一个点向外延申,每个点向外延申 k 个子节点 (k > 1),给定一个数 x 是否能够构造出一个雪花图案

数据范围 1 <= T <= 1e41 <= n <= 1e6

img

#include <iostream>
#include <map>

using namespace std;
typedef long long ll;
const int maxx = 1e6, maxk = 1e3;
map <int, bool> mp;

int main() {
    int T; cin >> T;
    for (int k = 2; k <= maxk; k ++) {
        int cnt = 1 + k;
        int pow_x = k * k;
        while (cnt + pow_x <= maxx) {
            cnt += pow_x;
            pow_x *= k;
            mp[cnt] = true;
            if (pow_x <= 0) break;
        }
    }
    while (T --) {
        int x; cin >> x;
        if (mp.count(x)) puts("YES");
        else puts("NO");
    }
    return 0;
}

E2. Rudolf and Snowflakes (hard version)

题意 定义雪花图案,由一个点向外延申,每个点向外延申 k 个子节点 (k > 1),给定一个数 x 是否能够构造出一个雪花图案

数据范围 1 <= T <= 1e41 <= n <= 1e18

题解 先处理 1 + k + k * k + k * k * k 以上的数据因此 maxk 开到 1e6 即可

特判 1 + k + k * k 的数据,先开根号,然后抖动一下

#include <iostream>
#include <cmath>
#include <map>

using namespace std;
typedef long long ll;
const ll maxk = 1e6, maxn = 1e18;
map <ll, bool> mp;

int main() {
    int T; cin >> T;
    for (ll k = 2; k <= maxk; k ++) {
        ll cnt = 1 + k;
        ll pow_x = k * k;
        while (true) {
            cnt += pow_x;
            mp[cnt] = true;
            if (pow_x > maxn / k) break;
            pow_x *= k;
        }
    }
    while (T --) {
        ll x; cin >> x;
        if (mp.count(x)) puts("YES");
        else {
            ll y = sqrt(x);
            while (y * y + y + 1 > x) y --;
            while (y * y + y + 1 < x) y ++;
            if (y > 1 && y * y + y + 1 == x) puts("YES");
            else puts("NO");
        }
    }
    return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JorbanS

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值