Codeforces Round 1009 (Div. 3)

A. Draw a Square

题目大意

给你(-l,0)、(r,0)、(0,-d)、(0,u)四个坐标,问是不是一个正方形

解题思路

都相等就是正方形

代码实现

#include <bits/stdc++.h>

using i64 = long long;

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    std::cout.tie(0);

    int tt;
    std::cin >> tt;

    while (tt--) {
        int l, r, d, u;
        std::cin >> l >> r >> d >> u;

        std::set<int> st = {l, r, d, u};
        if (st.size() == 1) {
            std::cout << "Yes\n";
        } else {
            std::cout << "No\n";
        }
    }
}

B. The Third Side

题目大意

给你一个数组a,选择其中两个元素删除,再加入一个元素满足它和被删除的元素能构成一个三角形,问a最后一个元素的最大值

解题思路

显然每次新加的元素都是最大边,它的值是被删除元素之和-1,共计执行n-1次操作

代码实现

#include <bits/stdc++.h>

using i64 = long long;

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    std::cout.tie(0);

    int tt;
    std::cin >> tt;

    while (tt--) {
        int n;
        std::cin >> n;

        std::vector<int> a(n);
        for (int i = 0; i < n; i++) {
            std::cin >> a[i];
        }

        std::cout << std::accumulate(a.begin(), a.end(), -n + 1ll) << "\n";
    }
}

C. XOR and Triangle

题目大意

给你一个x,找到一个y满足y小于x并且让x,y,x^y(称其为z)能构成三角形,找不到输出-1

解题思路

让y把x的高位之后全部填1就能让异或之后的z得到和x相同的高位,之后再加上y的所有低位1一定会比x大,这种情况下如果存在一定会满足,检查能否构成三角形即可

代码实现

#include <bits/stdc++.h>

using i64 = long long;

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    std::cout.tie(0);

    int tt;
    std::cin >> tt;

    while (tt--) {
        int x;
        std::cin >> x;

        int y = (1 << std::__lg(x)) - 1;
        int z = x ^ y;
        if (y >= 1 && z >= 1 && x + y > z && y + z > x) {
            std::cout << y << "\n";
        } else {
            std::cout << -1 << "\n";
        }
    }
}

D. Counting Points

题目大意

给你n个圆心在x轴上的圆和半径(半径和为m),问有多少个整数点在这些圆内

解题思路

发现m的范围比较小,因此可以从m入手,暴力检查所有的半径范围,查看当前这个x对应的最大y是多少,离散化之后对每个位置的最大y求和即可

代码实现

#include <bits/stdc++.h>

using i64 = long long;

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    std::cout.tie(0);

    int tt;
    std::cin >> tt;

    while (tt--) {
        int n, m;
        std::cin >> n >> m;

        std::vector<i64> x(n), r(n);
        std::map<i64, i64> mp;
        for (int i = 0; i < n; i++) {
            std::cin >> x[i];
        }
        for (int i = 0; i < n; i++) {
            std::cin >> r[i];
        }

        for (int i = 0; i < n; i++) {
            for (int j = x[i] - r[i]; j <= x[i] + r[i]; j++) {
                mp[j] = std::max(mp[j], (i64)std::sqrt(r[i] * r[i] - (x[i] - j) * (x[i] - j)));
            }
        }

        i64 ans = 0;
        for (auto [x, y] : mp) {
            ans += y * 2 + 1;
        }

        std::cout << ans << "\n";
    }
}

E. Empty Triangle

题目大意

交互题,每次可以询问三个索引,表示本次询问的点集的索引,如果三点构成的三角形内部有其他的点,会回答三角形内部任意一个点的索引,如果没有回答0,用不超过75次询问选择找到一个一组三角形内部没有其他点

解题思路

随机数乱搞,证明

代码实现

#include <bits/stdc++.h>

using i64 = long long;
std::mt19937 rng(std::chrono::steady_clock::now().time_since_epoch().count());

int main() {
    int tt;
    std::cin >> tt;

    while (tt--) {
        int n;
        std::cin >> n;

        int a = 1, b = 2, c = 3;
        while (1) {
            std::cout << "?" << " " << a << " " << b << " " << c << std::endl;
            int p = std::uniform_int_distribution<int>(0, 3)(rng), idx;
            std::cin >> idx;
            if (idx == 0) {
                std::cout << "!" << " " << a << " " << b << " " << c << std::endl;
                break;
            }

            if (p == 0) {
                a = idx;
            } else if (p == 1) {
                b = idx;
            } else {
                c = idx;
            }
        }
    }
}

F. Counting Necessary Nodes

题目大意

题目没懂

解题思路

代码抄的

代码实现

#include <bits/stdc++.h>

using i64 = long long;

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    std::cout.tie(0);

    int tt;
    std::cin >> tt;

    while (tt--) {
        i64 l1, r1, l2, r2;
        std::cin >> l1 >> r1 >> l2 >> r2;

        std::vector<i64> a(32);
        for (int k = 0; k <= 30; k++) {
            i64 bit = 1ll << k;
            i64 x = std::max(0ll, r1 / bit - (l1 + bit - 1) / bit);
            i64 y = std::max(0ll, r2 / bit - (l2 + bit - 1) / bit);
            a[k] = x * y;
        }

        i64 ans = 0;
        for (int k = 0; k <= 30; k++) {
            ans += a[k] - 4 * a[k + 1];
        }

        std::cout << ans << "\n";
    }
}

G. Game With Triangles: Season 2

题目大意

给你一个正n边形,每个顶点上有一个正整数,要求选择若干个不相交的三角形,使得这些三角形的顶点值乘积之和最大

解题思路

区间dp,先复制一次数组破坏为链,然后考虑lr区间里选择第三个点得到最优解或者最优解来自lr里的两个区间即可

代码实现

#include <bits/stdc++.h>

using i64 = long long;

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    std::cout.tie(0);

    int tt;
    std::cin >> tt;

    while (tt--) {
        int n;
        std::cin >> n;

        std::vector<int> a(2 * n + 1);
        for (int i = 1; i <= n; i++) {
            std::cin >> a[i];
            a[i + n] = a[i];
        }

        std::vector<std::vector<i64>> dp(2 * n + 1, std::vector<i64>(2 * n + 1));
        for (int len = 3; len <= n; len++) {
            for (int l = 1; l + len - 1 <= 2 * n; l++) {
                int r = l + len - 1;
                for (int k = l; k < r; k++) {
                    dp[l][r] = std::max(dp[l][r], dp[l][k] + dp[k + 1][r]);
                    if (k > l) {
                        dp[l][r] = std::max(dp[l][r], a[l] * a[r] * a[k] + dp[l + 1][k - 1] + dp[k + 1][r - 1]);
                    }
                }
            }
        }

        i64 ans = 0;
        for (int i = 1; i <= n; i++) {
            ans = std::max(ans, dp[i][i + n - 1]);
        }

        std::cout << ans << "\n";
    }
}
posted @ 2025-04-09 18:51  udiandianis  阅读(29)  评论(0)    收藏  举报