• Educational Codeforces Round 104 (Rated for Div. 2) A B C D E


    比赛链接

    A - Arena

    有n个英雄,分别由ai的初始等级。每次两个英雄战斗,如果等级相同,无影响。否则等级高的英雄等级+1。直到某个英雄等级到了100500游戏结束。问有多少个英雄最后可能获胜。

    Solution

    只要英雄等级不是最低的就有可能获胜。

    Code

    #include<iostream>
    #include<cstdio>
    #include <cmath>
    #include <algorithm>
    #define ll long long
    const int maxn = 1e5 + 10;
    int arr[maxn];
    void solve()
    {
        int n;
        scanf("%d", &n);
        int ans = 0;
        int minn = 100000000;
        for (int i = 1; i <= n; ++ i)
        {
            scanf("%d", &arr[i]);
            if(arr[i] < minn)
                minn = arr[i];
        }
        for (int i = 1; i <= n; ++i)
            if (arr[i] != minn)
                ans++;
        printf("%d
    ", ans);
    }
    
    int main()
    {
        int t ;
        scanf("%d", &t);
        while(t --)
        {
            solve();
        }
        return 0;
    }

    B - The Great Hero

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

    Solution

    偶数个点,不会碰到一起。奇数个点B会多走 k/(n/2)步

    Code

    #include<iostream>
    #include<cstdio>
    #include <cmath>
    #include <algorithm>
    #define ll long long
    const int maxn = 1e5 + 10;
    int arr[maxn];
    void solve()
    {
        int n, k;
        scanf("%d %d", &n, &k);
        int ans = 0;
        k--;
        if(n % 2)
        {
            k += (k / (n / 2));
        }
        k++;
        k %= n;
    
        printf("%d
    ", k == 0 ? n : k);
    }
    
    int main()
    {
        int t ;
        scanf("%d", &t);
        while(t --)
        {
            solve();
        }
        return 0;
    }

    C - Searching Local Minimum

    n个人两两进行一场战斗。平局各加一分,获胜加3分,失败不影响。请安排这些对局的结果 s.t. 最终所有人的分相等而且平局的数量尽可能少

    Solution

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

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

    Code

    #include<iostream>
    #include<cstdio>
    #include <cmath>
    #include <algorithm>
    #define ll long long
    const int maxn = 1e2 + 10;
    int arr[maxn][maxn];
    void solve()
    {
        int n, k;
        scanf("%d", &n);
        int ans = 0;
        k--;
        if(n % 2)
        {
            for (int i = 1; i <= (n + 1) / 2; ++ i)
            {
                for (int j = 1; j <= (n - 1) / 2; ++ j)
                {
                    arr[i][j] = 1;
                }
                for (int j = (n - 1) / 2 + 1; j <= n - i; ++ j)
                {
                    arr[i][j] = -1;
                }
            }
            for (int i = (n + 1) / 2 + 1; i <= n; ++ i)
            {
                for (int j = 1; j <= n - i; ++ j)
                {
                    arr[i][j] = 1;
                }
            }
    
        }
        else
        {
            for (int i = 1; i <= n - (n / 2 - 1); ++i)
            {
                for (int j = 1; j <= n / 2 - 1; ++j)
                {
                    arr[i][j] = 1;
                }
                for (int j = n / 2; j <= n / 2; ++ j)
                    arr[i][j] = 0;
                for (int j = n / 2 + 1; j <= n - i; ++j)
                {
                    arr[i][j] = -1;
                }
            }
            for (int i = n - (n / 2 - 1) + 1; i <= n; ++ i)
            {
                for (int j = 1; j <= n - i; ++ j)
                {
                    arr[i][j] = 1;
                }
            }
        }
    
        for (int i = 1; i <= n; ++ i)
        {
            for (int j = 1; j <= n - i; ++ j)
            {
                printf("%d ", arr[i][j]);
            }
        }
        puts("");
    }
    
    int main()
    {
        int t ;
        scanf("%d", &t);
        while(t --)
        {
            solve();
        }
        return 0;
    }

    D - Pythagorean Triples

    找到数对(a,b,c) 满足 c^2 = a^2 + b^2 && c = a^2 - b

    Solution

    两个式子联立或者打表都知道 a^2 = 2*b+1 && c = b+1

    然后暴力判或者瞎调个终式(如下)出来。

     

    Code

    #include<iostream>
    #include<cstdio>
    #include <cmath>
    #include <algorithm>
    #define ll long long
    const int maxn = 1e2 + 10;
    int arr[maxn][maxn];
    int main()
    {
        int t ;
        scanf("%d", &t);
        while(t --)
        {
            int n ;
            scanf("%d", &n);
            int ans = 0;
            for (int i = 3; i <= n; i +=2)
            {
                if (i * i / 2 + 1 <= n)
                    ans++;
                else
                    break;
            }
            printf("%d
    ", ans);
        }
        return 0;
    }

    E - 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;
    }

     

  • 相关阅读:
    软件项目版本号的命名规则及格式
    你必须知道的C#的25个基础概念
    Visual C#常用函数和方法集汇总
    web标准下的web开发流程思考
    设计模式(5)>模板方法 小强斋
    设计模式(9)>迭代器模式 小强斋
    设计模式(10)>策略模式 小强斋
    设计模式(8)>代理模式 小强斋
    设计模式(7)>观察者模式 小强斋
    设计模式(7)>观察者模式 小强斋
  • 原文地址:https://www.cnblogs.com/wifePI/p/14405962.html
Copyright © 2020-2023  润新知