zoukankan      html  css  js  c++  java
  • Educational Codeforces Round 104 (Rated for Div. 2) A-E 个人题解

    比赛链接


    1487A. Arena

    n 个 Hero,分别有 (a_i) 的初始等级。每次两个 Hero 战斗时:等级相同无影响,否则等级高的英雄等级+1。直到某个英雄等级到了 (100^{500})游戏结束。问有多少个英雄最后可能获胜。

    Solution

    只要所有英雄等级不是相同,那么必有 (n - b_0)个 Hero 获胜((b_0 代表等级最低的个数))

    Code

    int main() {
        ios_base::sync_with_stdio(false), cin.tie(0);
        for (cin >> _; _--;) {
            int n;
            cin >> n;
            vector<ll> a(n);
            for (auto& x : a) cin >> x;
            sort(a.begin(), a.end());
            int cnt = n, i = 0;
            while (a[i] == a[i + 1] && i < n) i++;
            if (i == n) {
                cout << 0 << "
    ";
                continue;
            }
            cout << n - count(a.begin(), a.end(), a[0]) << "
    ";
        }
        return 0;
    }
    

    1478B. Cat Cycle

    有一个(n)个点的圆环。A在 (n) 号点,B在 (1) 号点。A逆时针走,B顺时针走。如果A和B下一步是一个点,那么A走一步,B走两步。问经过 (K) 步后B在几号点

    Solution

    看了很久,发现是奇偶数问题,(n) 为偶数不会碰到一起,奇数个点时 B 多走 (frac{k}{n / 2})

    Code

    int main() {
        ios_base::sync_with_stdio(false), cin.tie(0);
        for (cin >> _; _--;) {
            ll n, k;
            cin >> n >> k;
            k--;                            // 第一秒
            if (n & 1) k += (k / (n / 2));  // 模拟奇数个点,k的变化
            k++, k %= n;
            cout << (k == 0 ? n : k) << "
    ";
        }
        return 0;
    }
    

    1478C. Minimum Ties

    (n) 支队伍要两两对战,平局各加一分,获胜加 3 分,失败无影响。请安排这些对局的结果使得最终所有人的分相等而且平局的数量尽可能少

    Solution

    显然总共有 (n*(n-1)/2) 局,如果全是非平局,那么一人 ((n-1)/2)局,那么只有在 (n) 是奇数的情况下成立。不然必定有平局产生。

    然后就按照每个人被分到多少局进行分配就好了。

    int main() {
        ios_base::sync_with_stdio(false), cin.tie(0);
        int n, i, j, k;
        for (cin >> n; cin >> n;)
            for (i = 0; i < n; i++)
                for (j = i + 1; k = (j - i) * 2, j < n; j++)
                    cout << (k == n ? 0 : k < n ? 1 : -1) << ' ';
        return 0;
    }
    

    1478D. Pythagorean Triples

    寻找三元组(a,b,c)满足 (c^2 = a^2 + b^2) and (c = a^2 - b)

    Solution

    两个算式联立:(a^2 = 2 * n + 1) and (c = b + 1)

    最后算出个:((ll)((sqrt(2 * n - 1) - 1) / 2))

    int main() {
        ios_base::sync_with_stdio(false), cin.tie(0);
        for (cin >> _; _--;) {
            ll n;
            cin >> n;
            cout << (ll)((sqrt(2 * n - 1) - 1) / 2) << "
    ";
        }
        return 0;
    }
    

    1478E. Cheap Dinner

    给定四个种类的菜各自的价格,给定一些关系:第一种菜中的某一种不能同时和第二种菜中的某一种一起被选中,然后2-nd和3-th,3-rd和4-th。

    问四种菜中各择一的最小代价。

    Solution

    如果单考虑前两种,那么对于第二种菜中的所有菜,可以通过不同时被选中关系得到自己的最小代价(或者不能),把这个代价移到第二种菜上,2-nd和3-rd的菜之间的转移等价于1-st和2-nd之间的转移。一种类似DP转移的思想。代码实现方面就用multiset乱搞,每次考虑两种关系的时候,先把当前点所不连通的点删掉,最后再加回来,可以这么做的原因是我只要考虑值,不需要考虑具体的关系。

    Code

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 2e5 + 10;
    int arr[5][maxn], dp[5][maxn];
    int nums[5];
    vector<int> vv[5][maxn];
    void solve() {
        for (int i = 1; i <= 4; ++i) scanf("%d", &nums[i]);
        for (int i = 1; i <= 4; ++i) {
            for (int j = 1; j <= nums[i]; ++j) {
                scanf("%d", &arr[i][j]);
            }
        }
        for (int i = 2; i <= 4; ++i) {
            int m;
            scanf("%d", &m);
            for (int j = 1, x, y; j <= m; ++j) {
                scanf("%d %d", &x, &y);
                vv[i][y].push_back(x);
            }
        }
        for (int i = 1; i <= nums[1]; ++i) {
            dp[1][i] = arr[1][i];
        }
        for (int i = 2; i <= 4; ++i) {
            multiset<int> ss;
            for (int l = 1; l <= nums[i - 1]; ++l) {
                if (dp[i - 1][l] != -1) ss.insert(dp[i - 1][l]);
            }
            for (int j = 1; j <= nums[i]; ++j) {
                for (int k = 0; k < vv[i][j].size(); ++k) {
                    int v = vv[i][j][k];
                    if (dp[i - 1][v] != -1) ss.erase(ss.find(dp[i - 1][v]));
                }
                if (ss.size() == 0)
                    dp[i][j] = -1;
                else
                    dp[i][j] = *ss.begin() + arr[i][j];
    
                for (int k = 0; k < vv[i][j].size(); ++k) {
                    int v = vv[i][j][k];
                    if (dp[i - 1][v] != -1) ss.insert(dp[i - 1][v]);
                }
            }
        }
        int ans = -1;
        for (int i = 1; i <= nums[4]; ++i) {
            if (dp[4][i] != -1) {
                if (ans == -1 || ans > dp[4][i]) ans = dp[4][i];
            }
        }
        printf("%d
    ", ans);
    }
    
    int main() {
        int t = 1;
        // scanf("%d", &t);
        while (t--) solve();
        return 0;
    }
    

    The desire of his soul is the prophecy of his fate
    你灵魂的欲望,是你命运的先知。

  • 相关阅读:
    Java实现 LeetCode 50 Pow(x,n)
    Java实现 LeetCode 50 Pow(x,n)
    Java实现 LeetCode 49 字母异位词分组
    Java实现 LeetCode 49 字母异位词分组
    Java实现 LeetCode 49 字母异位词分组
    Java实现 LeetCode 48 旋转图像
    Java实现 LeetCode 48 旋转图像
    Java实现 LeetCode 48 旋转图像
    Java实现 LeetCode 47 全排列 II(二)
    Java实现 LeetCode 47 全排列 II(二)
  • 原文地址:https://www.cnblogs.com/RioTian/p/14407568.html
Copyright © 2011-2022 走看看