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\n", 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\n", i);
        else if (t%2 == 0 && t >= 16)
            printf("Case #%d: Sheep\n", i);
        else
            printf("Case #%d: Draw\n", i);
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM