• Educational Codeforces Round 55 题解


    题解 CF1082A 【Vasya and Book】

    史上最难A题,没有之一

    从题意可以看出,翻到目标页只有三种办法

    • 先从(x)(1),再从(1)(y)

    • 先从(x)(n),再从(n)(y)

    • 直接从(x)(y)

    三种的必要条件分别是

    • ((y-1)mod d equiv 0)

    • ((n-y)mod d equiv 0)

    • (|x-y|mod d equiv 0)

    所以如果上面三种都不满足的话就输出(-1)

    不然就取最小的输出

    # include <bits/stdc++.h>
    
    int main()
    {
        int T;
        scanf("%d", &T);
        while(T--)
        {
            int n, x, y, d;
            scanf("%d%d%d%d", &n, &x, &y, &d);
            int ans = 0x7f7f7f7f;
            if(abs(x - y) % d == 0)
                ans = abs(x - y) / d;
            if((y - 1) % d == 0)
                ans = std::min(ans, (x - 1) / d + bool((x - 1) % d) + (y - 1) / d);
            if ((n - y) % d == 0)
                ans = std::min(ans, (n - x) / d + bool((n - x) % d) + (n - y) / d);
            if(ans == 0x7f7f7f7f)
            {
                printf("-1
    ");
                continue;
            }
            printf("%d
    ", ans);
        }
        return 0;
    }
    

    题解 CF1082B 【Vova and Trophies】

    (B)(A)水qwq

    这题,对每一个''(G)'',求它这一块的左边界和右边界

    然后对于每一个''(S)'',求一下他左边那块的大小,右边那块的大小,再判断一下他能不能把两块连在一起,不能就取大的那块,做完了

    #include <bits/stdc++.h>
    
    using std::string;
    
    const int MaxN = 100010;
    
    int a[MaxN];
    int l[MaxN], r[MaxN];
    
    int main()
    {
        int n;
        string s;
        scanf("%d", &n);
        std::cin >> s;
        int len = s.length();
        int sum = 0, ans = 0;
        for (int i = 0; i < len; i++)
            a[i + 1] = s[i] == 'S' ? 0 : 1, sum += a[i + 1];
        if (sum == 0)
            return printf("0") * 0;
        if (sum == n)
            return printf("%d
    ", n) * 0;
        for (int i = 1; i <= n; i++)
        {
            if (a[i] == 1 && a[i - 1] == 1)
                l[i] = l[i - 1];
            else
                l[i] = i;
        }
        for (int i = n; i >= 1; i--)
        {
            if (a[i] == 1 && a[i + 1] == 1)
                r[i] = r[i + 1];
            else
                r[i] = i;
        }
        for (int i = 1; i <= n; i++)
        {
            if (a[i] == 0)
            {
                int tmp = 0;
                if (a[i - 1])
                    tmp += r[i - 1] - l[i - 1] + 1;
                if (a[i + 1])
                    tmp += r[i + 1] - l[i + 1] + 1;
                if(tmp == sum)
                    ans = std::max(ans, tmp);
                if (tmp < sum)
                    ans = std::max(ans, tmp + 1);
                if (a[i - 1] && r[i - 1] - l[i - 1] + 1 < sum)
                    ans = std::max(r[i - 1] - l[i - 1] + 2, ans);
                if (a[i + 1] && r[i + 1] - l[i + 1] + 1 < sum)
                    ans = std::max(r[i + 1] - l[i + 1] + 2, ans);
                
            }
        }
        printf("%d
    ", ans);
        return 0;
    }
    

    题解 CF1082C 【Multi-Subject Competition】

    这个(C)好难啊

    这是道前缀和好题

    首先,读入后,把每一个分数扔进相应学科的桶

    然后贪心地对每个桶排序

    然后对于每一个桶,求前缀和,如果大于(0),就加到对应的(ans[i])中((ans[i])记录的是每个学科(i)个人的最大得分)

    最后输出

    [max_{1<=i<=n}{ans[i]} ]

    #include <bits/stdc++.h>
    
    # define int long long
    
    using std::vector;
    const int MaxN = 100010;
    
    int ans;
    int sum[MaxN];
    vector<int> v[MaxN];
    int s[MaxN], rank[MaxN];
    
    int cmp(int a, int b) { return a > b; }
    
    signed main()
    {
        int n, m, maxn = 0;
        scanf("%I64d%I64d", &n, &m);
        for (int i = 1; i <= n; i++)
        {
            scanf("%I64d%I64d", &s[i], &rank[i]);
            v[s[i]].push_back(rank[i]);
            maxn = std::max(rank[i], maxn);
        }
        if (maxn == 0)
            return 0 * printf("0
    ");
        for (int i = 1; i <= m; i++)
        {
            if (v[i].size())
                std::sort(v[i].begin(), v[i].end(), cmp);//排序
        }
        for(int i = 1; i <= m; i++)
        {
            int tmp = 0;
            for(int j = 0; j < v[i].size(); j++)
            {
                tmp += v[i][j];
                if(tmp <= 0)
                    break;
                sum[j + 1] += tmp;//前缀和
            }
        }
        printf("%d", *std::max_element(sum + 1, sum + n + 1));
        return 0;
    }
    
  • 相关阅读:
    组策略导入导出secedit
    ipad常见错误
    ipad系统路径
    内核操作注册表例子
    WoW64子系统
    win2003 shutdown命令
    regedit 导入注册表
    windbg for CLR
    WM_POWERBROADCAST
    OpenSSL命令
  • 原文地址:https://www.cnblogs.com/little-sun0331/p/10046308.html
Copyright © 2020-2023  润新知