P11323 【MX-S7-T1】「SMOI-R2」Happy Card

blind5883發表於2024-11-24

P11323 【MX-S7-T1】「SMOI-R2」Happy Card - 洛谷 | 電腦科學教育新生態 (luogu.com.cn)

這題不復雜,本質就是一個貪心,可以發現,三帶一和炸彈可以合併為三個相同的帶任意一張牌。那我們儘量都選三張相同的,這樣每種牌最後只剩 \(0,1,2\) 張牌,我們先用三張帶走儘量帶走只剩 1 張的牌,如果還有多的三張,就去不斷帶只剩 2 張的(花費兩個三張),如果兩張帶完還有剩的,用三帶自己帶自己,

#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

typedef long long LL;

const int N = 300010;

int n, m;
int g[N];
LL t[3];

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

int main()
{
    int T;
    cin >> T;
    while (T -- )
    {
        cin >> n;
        memset(t, 0, sizeof t);
        LL cnt = 0; // 三帶的數量(三張相同)
        for (int i = 1; i <= n; i ++ ) 
        {
            g[i] = read();
            cnt += g[i] / 3;
            t[g[i] % 3] ++ ;
        }
        if (t[1] > cnt) cout << t[1] - cnt + cnt + t[2] << endl; // 帶不走全部1
        else 
        {
            if ((cnt - t[1]) / 2 >= t[2]) // 還能帶走2
            {
                LL x = cnt - t[1] - 2 * t[2]; // 剩餘三帶數量
                LL sum = t[1] + 2 * t[2] + x * 3 / 4; // x * 3 / 4是三帶帶自己
                if (x * 3 % 4 == 3) sum += 2; // 帶完還剩三張相同,(不能直接輸出三張相同),就分為一個單牌和一個對子
                else if (x * 3 % 4 == 2 || x * 3 % 4 == 1) sum ++ ; // 直接輸出對子/單牌
                cout << sum << endl;
            } // 帶不走2
            else cout << cnt + t[2] - (cnt - t[1]) / 2 << endl;
        } // (cnt - t[1]) / 2 是還能帶走2的的數量
    }
    
    return 0;
}

相關文章