zoukankan      html  css  js  c++  java
  • 2017 ACM-ICPC EC-Final ShangHai(思维乱搞赛)

    感觉全是思维乱搞题。

    Gym - 101775J Straight Master

    给你n种扑克,你每次可以出连续的3 ~ 5 张,问你能否出完。

    Sample Input
    2
    13
    1 2 2 1 0 0 0 0 0 0 0 0 0
    13
    1 1 1 1 0 1 1 0 0 0 0 0 0
    
    Sample Output
    Case #1: Yes
    Case #2: No
    

    相当于每次把一个长度为3~5的区间整体减1,问最后是否能够全部减成0。

    显然,每次把一个长度大于5的区间整体减1也是可以的,因为6 = 3+3,7 = 3+4......

    所以问题就变成了每次修改一个长度大于等于3的区间。

    可以先维护原本序列的差分,然后区间整体减1就相当于a[l]--, a[r+1]++。

    所以只要贪心的枚举每个大于0的位置,然后找后面的离他最近的小于0的数字匹配,把前者减,后者加,就可以了。

    如果最近的距离 < 3那么就是不可以。

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <iostream>
    
    using namespace std;
    typedef long long LL;
    const int maxn = 200000 + 100;
    
    int a[maxn];
    LL c[maxn];
    
    int main()
    {
        int t;
        scanf("%d", &t);
        for (int ca = 1; ca <= t; ca++)
        {
            memset(a, 0, sizeof(a));
            int n;
            scanf("%d", &n);
            for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
            for (int i = 1; i <= n+1; i++) c[i] = a[i]-a[i-1];
    
            bool flag = true;
            int r = 0;
            for (int i = 1; i <= n; i++)
            {
                while(c[i] > 0)
                {
                    while(c[r] >= 0)
                        if (++r > n+1) flag = false;
                    if (r-i <= 2) flag = false;
                    if (!flag) break;
                    c[r] += c[i], c[i] = 0;
                    if (c[r] > 0) c[i] = c[r], c[r] = 0;
                }
                if (!flag) break;
            }
    
            printf("Case #%d: %s
    ", ca, flag?"Yes":"No");
        }
    }

    Gym - 101775L SOS

    有一个长度为n的数组,Panda和Sheep轮流往一个空的位置上放 "S" 或者是 "O"。

    如果有人放完后,构成一个连续的 "SOS",那么这个人就胜利。

    现在是Panda先手,再两个人足够决策的情况下,谁会获胜?

    平局输出"Draw"。

    Sample Input
    2
    3
    7
    
    Sample Output
    Case #1: Draw
    Case #2: Panda
    

    首先,可以看出一个必胜态一定存在一个S_ _S的情况。

    如果构成了这个必胜态,n为奇数时先手胜,n为偶数时先手败。

    先讨论n为奇数:

    显然的一点就是当n >= 7时,一定存在一个位置,先手放S可以构成一个必胜态,此时后手是无法阻止他的。

    所以n为奇数且n >= 7时,先手是必胜的。

    再讨论n为偶数:

    根据上面的结论,此时先手一定不想构成一个S_ _S的局面,所以第一步一定放O,来尽可能阻止后手构成此必胜态。

    什么时候阻止不了呢?当放O的点左边或右边有至少8个点的时候。此时n为16。

    综上,n%2 == 1 && n >= 7,先手胜;n%2 == 0 && n >= 16,后手胜;否则就是平局。

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <iostream>
    
    using namespace std;
    typedef long long LL;
    
    int main()
    {
        int n;
        scanf("%d", &n);
        for (int i = 1; i <= n; i++)
        {
            int t;
            scanf("%d", &t);
            if (t%2 == 1 && t >= 7)
                printf("Case #%d: Panda
    ", i);
            else if (t%2 == 0 && t >= 16)
                printf("Case #%d: Sheep
    ", i);
            else
                printf("Case #%d: Draw
    ", i);
        }
    }
  • 相关阅读:
    leetcode Remove Linked List Elements
    leetcode Word Pattern
    leetcode Isomorphic Strings
    leetcode Valid Parentheses
    leetcode Remove Nth Node From End of List
    leetcode Contains Duplicate II
    leetcode Rectangle Area
    leetcode Length of Last Word
    leetcode Valid Sudoku
    leetcode Reverse Bits
  • 原文地址:https://www.cnblogs.com/ruthank/p/9568459.html
Copyright © 2011-2022 走看看