1. 程式人生 > >AT2386 Colorful Hats (亂搞題,思維題)

AT2386 Colorful Hats (亂搞題,思維題)

分情況討論的神題...
max不等於min + 1 或者不等於min,這種情況顯然不存在.
如果都等於一個數
有兩種情況:
互相獨立,那麼a[i]肯定==n-1
有相同的,那麼a[i]一定不是獨立的.
那麼就會有a[i]即為出現顏色的總個數.
因為又不是獨立的.所以每種顏色至少出現兩次.
所以滿足\(2 * a[i] <= n\)即可.
繼續分析,如果max == min + 1的情況.
n : 人數
一個點至少能看到有max - 1種顏色.
max : 能看到最多的顏色. (總顏色)
max - 1 : 本身是獨立的顏色
設cnt 為max - 1出現的個數.
那麼cnt就是出現的獨立顏色.
把這些點剔除.
那麼n = n - cnt
下文中的n 都變成了 n - cnt
max - cnt就是剩下的顏色個數
剩下的顏色個數至少滿足兩個人擁有同一顏色.(相互不獨立,轉化為上面的問題)
所以當2 * (max - cnt) <= n的時候是有解得.
所以不獨立顏色個數是本題解題的關鍵.
但是再WA了十幾遍後,終於發現了\(BUG\)

所在.漏了一種情況.
當cnt >= maxx的時候(cnt == maxx的時候不存在合法情況.也要算上)是不合法的情況.
然後就A了.......

#include <iostream>
#include <cstdio>
#define gc getchar()
#define pc putchar
#define rep(i,x,p) for(int i = x;i <= p;++ i)
#define sep(i,x,p) for(int i = x;i >= p;-- i)
using namespace std;
const int maxN = 1e5 + 7;

int a[maxN];

inline int read() {
    int x = 0 ,f = 1;char c = gc;
    while(c < '0' || c > '9') {if(c == '-')f = -1;c = gc;}
    while(c >= '0' && c <= '9') {x = x * 10 + c - '0';c = gc;}
    return x * f;
}

void print(int x) {
    if(x < 0) {
        pc('-');
        x = -x;
    }
    if(x >= 10) print(x / 10);
    pc(x % 10 + '0');
}

int main() {
    int n,maxx = 0, minn = 1e6;
    n = read();
    rep(i,1,n) a[i] = read();
    rep(i,1,n) maxx = max(maxx,a[i]);
    rep(i,1,n) minn = min(minn,a[i]);
    if(maxx != minn + 1 && maxx != minn)  {puts("No");return 0;}
    if(maxx == minn) {
        if(a[1] == n - 1 || 2 * a[1] <= n) puts("Yes");
        else puts("No");
        return 0;
    }
    int cnt = 0;
    rep(i , 1 , n) if(a[i] == minn) cnt ++;
    if(cnt >= maxx || 2 * (maxx - cnt) > n - cnt) puts("No");
    else puts("Yes");
    return 0;
}