专栏文章

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

P11323题解参与者 6已保存评论 5

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
5 条
当前快照
1 份
快照标识符
@mir0aoy9
此快照首次捕获于
2025/12/04 13:39
3 个月前
此快照最后确认于
2025/12/04 13:39
3 个月前
查看原文

「SMOI-R2」Happy Card

上午的模拟赛第一题成功写挂了。本来分类讨论了一百多行喜提 00 分,借助 dalao 的思路重构一下代码。

思路

相较于官方题解,感觉还是有不一样的地方。此题核心的思想就是贪心。对于所有的单张,必然要花费一次打出去,所以最好的情况是三带一打出去。
那么我们先提出所有的三张,跟剩下的数量的牌从小到大分开组合。对于所有都是三张,就要拆开有三张的牌进行组合。实际上我们把炸弹和三带一看成一种东西。

代码

CPP
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 3e5 + 10;
long long a[MAXN];
int main()
{
    int T,n;
    long long sum = 0;
    long long cnt1 = 0 , cnt2 = 0 , cnt3 = 0;
    cin >> T; // 输入询问次数
    for (int t = 1 ; t <= T ; ++t)
	{
        memset(a,0,sizeof(a));
        cnt1 = cnt2 = cnt3 = sum = 0;
        cin >> n;
        for (int i = 1 ; i <= n ; ++i)
		{
            cin >> a[i]; // 输入每种牌的数量
            sum += a[i];
            cnt3 += a[i]/3;// 累加可以组成三张的组合
        }
        if (cnt3 > sum/4) // 如果所有“三张”的总数足以覆盖至少四张一组的分布
		{
            if (sum % 4 == 1) cout << sum / 4 + 1 << endl;
            else if (sum % 4 ==2) cout << sum / 4 + 1 << endl;
            else if (sum % 4 == 3) cout << sum / 4 + 2 << endl;
            else if (sum % 4 == 0) cout << sum / 4 << endl;
        }
        else if (cnt3 <= sum/4)
		{
            for (int i = 1 ; i <= n ; i++)
			{
                if (a[i] % 3 == 1) cnt1++;// 模 3 余 1 的牌数量
                else if (a[i] % 3 == 2) cnt2++;// 模 3 余 2 的牌数量
            }
            if (cnt3 <= cnt1) cout << cnt1 + cnt2 << endl;// 如果“三张”不足够,使用余数牌
            else if (cnt3 > cnt1) cout << cnt3 + cnt2 - (cnt3 - cnt1) / 2 << endl;// 用余数的 2 补充“三带一”或其他牌
        }
    }

    return 0;
}

评论

5 条评论,欢迎与作者交流。

正在加载评论...