zoukankan      html  css  js  c++  java
  • AcWing 耍杂技的牛(国王游戏) 2021第一篇题解

    国王游戏网上的题解已经够多了,这里贴上我艰难地写出的代码,之后讲解一个使用相同思想但实现起来简单得多的题目.

    // 国王游戏
    // 高精度写得并不完善, 精力所限没有继续追究
    // 我的高精度总结:https://www.cnblogs.com/Gaomez/p/14198544.html
    
    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    using namespace std;
    
    typedef pair<int, int> PII;
    int n, cur[5000], curtmp[5000], ans[5000], tmp[5000], lena = 0, lenc = 1, lent = 1;
    PII s[1010];
    
    int mul1(int x, int l) {
        memset(tmp, 0, sizeof(tmp));
    
        for (int i = 1; i <= l; i++) tmp[i] = cur[i] * x;
        
        for (int i = 1; i < 4999; i++) {
            tmp[i + 1] += tmp[i] / 10;
            tmp[i] %= 10;
        }
        l = 4999;
        while(!tmp[l] && l) l--;
        l = (l ? l : 1);
        for (int i = 1; i <= 4999; i++) cur[i] = tmp[i];
        return l;
    }
    
    int div1(int x, int l) {
        memset(tmp, 0, sizeof(tmp));
        memcpy(curtmp, cur, sizeof(cur));
    
        for (int i = l; i >= 1; i--) {
            tmp[i] = curtmp[i] / x;
            curtmp[i - 1] += (curtmp[i] % x) * 10;
        }
        while (!tmp[l] && l) l--;
        l = (l ? l : 1);
        for (int i = l; i >= 1; i--) curtmp[i] = tmp[i];
    
        return l;
    }
    
    void cmp() {
        bool big = false;
    
        if (lent != lena)
            big = lent > lena;
        else
            for (int i = lent; i >= 1; i--)
                if (ans[i] != curtmp[i]) {
                    big = curtmp[i] > ans[i];
                    break;
                }
        if (big) {
            for (int i = lent; i >= 1; i--) ans[i] = curtmp[i];
            lena = lent;
        }
    }
    
    int main() {
        int a, b;
        scanf("%d", &n);
        for (int i = 0; i <= n; i++) {
            scanf("%d%d", &a, &b);
            s[i] = {a * b, b};
        }
    
        cur[1] = 1;
        curtmp[1] = 1;
        lenc = mul1(s[0].first / s[0].second, lenc);
        sort(s + 1, s + 1 + n);
    
        for (int i = 1; i <= n; i++) {
            lent = div1(s[i].second, lenc);  // curtmp = cur, curtmp /= b
            cmp();                           // cur_tmp > ans ?
            lenc = mul1(s[i].first / s[i].second, lenc);  // cur *= a / b
        }
    
        int head = 4999;
        while (!ans[head] && head) head--;
        head = (head ? head : 1);
        for (int i = head; i >= 1; i--) printf("%d", ans[i]);
        putchar('
    ');
    
        return 0;
    }
    国王游戏,难点在于高精度

    (注意理解题意,最高处的牛也要算上,它头上的总重量是0)

    假设有如下的奶牛堆叠:(括号内分别表示W,S)

    (e,f)

    (c,d)

    (a,b)

    (e,f)

    (a,b)

    (c,d)

    这两种方式区别在于下面两头奶牛的位置相反,现在讨论一下哪种情况下更优.

    设最大风险值为D.

    ①D=max{e-d, e+c-b}.

    ②D=max{e-b, e+a-d}.

    可见两种情况下最大风险值都不会受到牛(e,f)的影响,牛(e,f)及其以上所有的牛在这里都可以合成为一头牛,不妨设e=0,就可以排除所有其它牛的干扰.

    ①D=max{-d, c-b}.

    ②D=max{-b, a-d}.

    现在想要找到哪种情况下可以取得更小的D,注意到交叉项有-d<a-d, -b<c-b,

    如果假设情况①优于情况②,即max{-d, c-b} < max{-b, a-d},

    若左边取得-d,右边>=a-d,不等式一定成立;

    若左边取得c-b,右边只有取a-d时可能成立,成立时有c-b < a-d, 即当且仅当c + d < a + b时情况①优于情况②.

    所以将所有的牛按照w+s的大小为关键字进行排序即可,大者在下,这与直观的逻辑是符合的:重量越大,力量越大越应该在下面.

     相比于国王游戏,这题不需要高精度,实现起来简单得多.

    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    using namespace std;
    
    int n;
    long long ans = -1e18, sum;
    pair<int, int> p[50010];
    
    int main(){
        int w, s;
        scanf("%d", &n);
        for(int i = 1; i <= n; i++){
            scanf("%d%d", &w, &s);
            p[i] = {w + s, s};
        }
        if(n == 1){
            printf("%d", -p[1].second);
            return 0;
        }
        sort(p + 1, p + 1 + n);
    
        for(int i = 0; i < n; i++){
            sum += p[i].first - p[i].second;
            ans = max(ans, sum - p[i + 1].second);
        }
    
        printf("%lld
    ", ans);
    
        return 0;
    }
    AC Code
  • 相关阅读:
    CE6内核启动过程新角度
    Eboot 中给nandflash分区实现
    Feedsky 上 csdn blog 订阅数排名 (zz)
    c# 枚举 enum 类型
    64bit系统下操作注册表的注意事项 ZZ
    良方治奇病,Visual Studio正则替换大法 (转)
    关于23种设计模式的有趣见解
    NHibernate快速指南(一)
    网站、数据库的衍变之路(二) (转)
    网站、数据库的衍变之路(一) (转)
  • 原文地址:https://www.cnblogs.com/Gaomez/p/14212984.html
Copyright © 2011-2022 走看看