Codeforces Round 883 (Div. 3)

Codeforces Round 883 (Div. 3)

题目链接:Codeforces Round 883 (Div. 3)

A. Rudolph and Cut the Rope

思路

统计\(a_i\)大于\(b_i\)的点的数量就行。

代码

#include <bits/stdc++.h>
using namespace std;


void sol() {
    int n, ans = 0;
    cin >> n;
    for (int i = 1; i <= n; ++i) {
        int x, y;
        cin >> x >> y;
        if (y < x) ans += 1;
    }
    cout << ans << endl;
}

int main() {
    int _;
    cin >> _;
    while (_--) sol();
    return 0;
}

B. Rudolph and Tic-Tac-Toe

思路

判断'O'和'×'有没有连成三个就行,否则就是平局

代码

#include <bits/stdc++.h>
using namespace std;

char s[5][5];

void sol() {
    for (int i = 1; i <= 3; ++i) cin >> (s[i] + 1);
    int win = 0;
    char wn;
    for (int i = 1; i <= 3; ++i) {
        if (s[i][1] == s[i][2] && s[i][2] == s[i][3]) {
            if (s[i][1] == '.') continue;
            win = 1;
            wn = s[i][1];
        }
    }
    if (win == 1) {
        cout << wn << endl;
        return;
    }
    for (int i = 1; i <= 3; ++i) {
        if (s[1][i] == s[2][i] && s[2][i] == s[3][i]) {
            if (s[1][i] == '.') continue;
            win = 1;
            wn = s[1][i];
        }
    }
    if (win == 1) {
        cout << wn << endl;
        return;
    }
    if ((s[1][1] == s[2][2] && s[2][2] == s[3][3]) ||
        (s[3][1] == s[2][2] && s[2][2] == s[1][3])) {
        if (s[2][2] != '.') {
            win = 1;
            wn = s[2][2];
        }
    }
    if (win == 1) {
        cout << wn << endl;
        return;
    }
    cout << "DRAW" << endl;
}

int main() {
    int _;
    cin >> _;
    while (_--) sol();
    return 0;
}

C. Rudolf and the Another Competition

思路

对于每个题目,不难看出,最优策略是先写简单题。

会爆int,需要开LL。

代码

#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 5;
#define LL long long

int a[maxn];

struct poi {
    LL sum;
    int t;
    bool operator<(const poi b) const {
        return t > b.t || (t == b.t && sum < b.sum);
    }
};

set<poi> s;
map<poi, vector<int>> p;

void sol() {
    s.clear();
    p.clear();
    int n, m, k;
    cin >> n >> m >> k;
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= m; ++j) cin >> a[j];
        sort(a + 1, a + m + 1);
        int sum = 0, t = 0;
        LL summ = 0;
        for (int j = 1; j <= m && sum + a[j] <= k; ++j) {
            sum += a[j];
            summ += sum;
            t += 1;
        }
        p[poi{summ, t}].push_back(i);
        s.insert(poi{summ, t});
    }
    int idx = 0;
    for (auto x : s) {
        for (auto xx : p[x]) {
            if (xx == 1) {
                cout << idx + 1 << endl;
                return;
            }
        }
        int i = p[x].size();
        idx += i;
    }
}

int main() {
    int _;
    cin >> _;
    while (_--) sol();
    return 0;
}

D. Rudolph and Christmas Tree

思路

简单数学计算面积题,一点弯都没绕,还以为他会卡double精度,但是也没卡

代码

#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 5;
#define LL long long

int a[maxn];

void sol() {
    int n, d, h;
    cin >> n >> d >> h;
    for (int i = 1; i <= n; ++i) cin >> a[i];
    sort(a + 1, a + n + 1);
    a[n + 1] = a[n] + h + 1;
    double ans = 0;
    for (int i = 1; i <= n; ++i) {
        if (a[i] + h <= a[i + 1]) {
            ans += 0.5 * d * h;
        }
        else {
            double tmp = 1.0 * d * (1.0 * (a[i] + h - a[i + 1]) / h);
            ans += 0.5 * d * h - 0.5 * tmp * (a[i] + h - a[i + 1]);
        }
    }
    printf("%.7lf\n", ans);
}

int main() {
    int _;
    cin >> _;
    while (_--) sol();
    return 0;
}

E. Rudolf and Snowflakes

思路

这个题实际上是让判断n是否能写成\(1+x+x^2+...+x^k=n\)的形式。

简单版本可以遍历\(x\),再遍历每个\(k\)就行。

由于困难版本\(1≤n≤1e18\),所以不能直接遍历\(x\)。考虑到两种情况:\(1≤x<1e6\)时,\(x\)可代入\(k≥3\)时的式子,但当\(x\)再大的话代入\(k≥3\)时的式子的之后,产生的n就会比\(1e18\)大,此时只能通过\(1+x+x^2=n\)来产生合法的n。从而对于\(k≥3\),遍历\(x\)\(1\)\(1e6\),产生所有可能的\(n\);对于\(k<3\),二分\(x\)\(2\)\(1e9\)来判断\(n\)能不能被生成。

代码

#include <bits/stdc++.h>
using namespace std;
#define LL long long

map<LL, bool> vis;

LL bs(LL l, LL r, LL x) {
    if (l == r) return l;
    LL mid = (l + r) / 2;
    if (mid * mid + mid + 1 < x)
        return bs(mid + 1, r, x);
    else
        return bs(l, mid, x);
}

void sol() {
    LL n;
    cin >> n;
    if (vis[n]) {
        cout << "YES" << endl;
        return;
    }
    LL x = bs(2, 1000000000, n);
    if (x * x + x + 1 != n) {
        cout << "NO" << endl;
    } else {
        cout << "YES" << endl;
    }
}

int main() {
    LL n = 1e6, nn = 1e18;
    for (LL i = 2; i <= n; i++) {
        LL sum = i + 1 + i * i, tmp = i * i * i;
        while (sum + tmp <= nn) {
            sum += tmp;
            vis[sum] = true;
            if ((nn - sum) / tmp < i) break;
            tmp *= i;
        }
    }
    int _;
    cin >> _;
    while (_--) sol();
    return 0;
}

F. Rudolph and Mimic

没意思,直接下一题。。

G. Rudolf and CodeVid-23

思路

由于\(1\leq n\leq 10\),所以所有健康状态的数量最大为1024,将每个健康状态看成点,边数最多为\(1e6\)水平,其实就是让求最短路,dijkstra一下就行。

代码

#include <bits/stdc++.h>
using namespace std;

const int maxn = 1030;

struct edge {
    int to, w;
    bool operator<(const edge b) const {
        return to < b.to || (to == b.to && w < b.w);
    }
};

struct node {
    int idx, dis;
    bool operator<(const node b) const {
        return dis > b.dis || (dis == b.dis && idx > b.idx);
    }
};

set<edge> edges[maxn];

int dijkstra(int x, int n) {
    vector<int> dis(n, INT_MAX);
    vector<bool> vis(n, false);
    priority_queue<node> q;
    q.push(node{x, 0});
    dis[x] = 0;
    while (!q.empty()) {
        node now = q.top();
        q.pop();
        if (vis[now.idx]) continue;
        vis[now.idx] = true;
        for (auto x : edges[now.idx]) {
            if (dis[x.to] > x.w + now.dis) {
                dis[x.to] = x.w + now.dis;
                q.push(node{x.to, dis[x.to]});
            }
        }
    }
    if (dis[0] == INT_MAX)
        return -1;
    else
        return dis[0];
}

void sol() {
    int n, m;
    cin >> n >> m;
    for (int i = 0; i < 1 << n; ++i) edges[i].clear();
    bitset<10> s;
    cin >> s;
    int x = (int)s.to_ulong();
    for (int i = 1; i <= m; ++i) {
        int w, l, r;
        cin >> w >> s;
        l = (int)s.to_ulong();
        cin >> s;
        r = (int)s.to_ulong();
        for (int j = 0; j < 1 << n; ++j)
            edges[j].insert(edge{(j & (j ^ l)) | r, w});
    }
    cout << dijkstra(x, 1 << n) << endl;
}

int main() {
    int _;
    cin >> _;
    while (_--) sol();
    return 0;
}
posted @ 2023-07-11 15:28  FlyingLight  阅读(59)  评论(0编辑  收藏  举报