agc016B – Colorful Hats(智商題)

自為風月馬前卒發表於2018-09-20

題意

題目連結

有$n$個人,每個人有一種顏色,第$i$個人說除了我之外有$a_i$種不同的顏色,問是否存在一組合法解

Sol

700分的題就這麼神仙了麼。。好難啊。。。

先說結論吧

設$mx, mn$分別為最大 / 最小值,顯然$mx – mn > 1$的時候無解

接下來分兩種情況討論

$mx = mn$:這時候每一種顏色要麼是互不相同,要麼是至少出現兩次

$mx = mn +1$:這時候小的元素一定是獨一無二的,大的元素至少出現兩次。

以上結論都可以用反證法證明。

總結:
雖然結論證起來不難,但是自己想的話確實是太難受了,因為會有很多干擾你的模型(我最開始的時候還想tarjan縮點來著qwq)。
自己推了一個多小時也剛剛推除了無解的情況和$mx = mn$的情況,推到最後直接心態爆炸,我甚至都感覺自己的思路有問題,
因為每個結論要證明都不是很顯然,總是感覺自己想複雜了。不過這題確實是好題

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1e6 + 10, INF = 1e9 + 10;
inline int read() {
    char c = getchar(); int x = 0, f = 1;
    while(c < `0` || c > `9`) {if(c == `-`) f = -1; c = getchar();}
    while(c >= `0` && c <= `9`) x = x * 10 + c - `0`, c = getchar();
    return x * f;
}
int N, a[MAXN];
main() {
    N = read();
    for(int i = 1; i <= N; i++) a[i] = read();
    sort(a + 1, a + N + 1);
    int mn = 0, mx = 0, num;
    a[0] = -1;
    for(int i = 1; i <= N; i++) 
        if(a[i] != a[i - 1]) {
            if(!mn) mn = a[i];
            else if(!mx) mx = a[i], num = i - 1;
            else {puts("No"); return 0;}
        }
    if(!mx) {
        if((mn == N - 1) || (mn * 2 <= N)) puts("Yes");
        else puts("No");
    } else {
        if((mx == mn + 1) && (2 * (mx - num) <= N - num) && (mx - num > 0)) puts("Yes");
        else puts("No");
    }
    return 0;
}

 

相關文章