Skip to content

算法刷题【洛谷U193902】橡皮泥

信息学竞赛

2022-04-18

题目描述

陶陶有 nn 个橡皮泥,每个橡皮泥的体积为 aia_i

陶陶是一个泥人巨匠,于是他可以进行以下操作:

每次操作选择两个橡皮泥,将其合并,新橡皮泥的体积为两个原体积之和,并将合成后的橡皮泥插入原序列,当然插入的位置无关紧要。

例如,三个橡皮泥的体积为 [2, 1, 4] ,陶陶能够获得 [3, 4], [1, 6] 或 [2, 5] 。

陶陶想知道经过若干次操作后,体积是 3 的倍数的橡皮泥个数最多是多少个?

输入格式

第一行一个整数 TT

接下来 TT 组数据,每组数据第一行为一个整数 nn ,接下来一行有 nn 个整数,表示这 nn 个橡皮泥的体积。

输出格式

对于每组数据,输出体积是 3 的倍数的橡皮泥个数最多是多少个

输入输出样例

In 1:

2
5
3 1 2 3 1
7
1 1 1 1 1 2 2

Out 1:

3
3

数据范围

对于100%100\%的数据点:1T1000,1n100,1ai1091\leq T\le 1000, 1\leq n\le 100, 1\leq a_i \le 10^9

题解

显而易见:

  1. 本身是三的倍数直接统计;
  2. 不是的优先一个 除以3余数为1的数 和一个 除以3余数为2的数 配对(因为这样消耗的数字少,严格证明我也不会 );
  3. 再针对多余出来的数字(这些数字取余3的余数一定单调为1或者2),每3个相加配成一个3的倍数。
#include <bits/stdc++.h>
using namespace std;

int n, temp, ans = 0;

int main() {
    int tttt;
    cin >> tttt;
    while (tttt--) {
        cin >> n;
        ans = 0;  // 总共可以形成多少
        int one = 0, two = 0;  // 余数为1或2的数字的个数

        for (int i = 1; i <= n; i++) {
            cin >> temp;
            if (temp % 3) {
                // 不是3的倍数,记录余数是几的个数
                temp % 3 == 1 ? one++ : two++;
            } else
                ans++;  // 是3的倍数则直接累加
        }
        ans += min(one, two);  // 一个余数为1的数字和一个余数为2的数字可以凑成一个3的倍数
        ans += abs(one - two) / 3;  // 多余的部分,每3个数可以凑成一个3的倍数,向下取整
        cout << ans << endl;
    }
}

Ukraine 在俄罗斯对乌克兰发动的野蛮的侵略战争中矢志不渝地支持乌克兰