返回顶部

All Distinct

题意

有多组数据。 给你若干个数,每次删除 2 个数,求删除若干次后使数中没有重复的前提下剩下最多的数。

传送门

思路

每次删除两个数,那我们可以脑补出删除完之后的数列是什么样子的。

以样例1的第一组样例为例:

2 2 2 3 3 3

那我们就可以想出,不重复数字的数列应该是 2 3

倒推每次删除两个数就可以想出删了 \(2\) 次,即删除了 \(2\)\(2\)\(3\) 。剩下 \(2\) 个数字就输出 \(2\)

我们想统计数列中数字出现的个数,即定义 \(vis[a[i]] ++\) 统计数字。

由于剩下的数列中的数字总是不重复的,统计出重复的即可。

但是以样例1的第二组样例为例时:

9 1 9 9 1

这里有 \(3\)\(9\)\(2\)\(1\),有两个数字。

综上第一组样例描述,最后不重复的应该是 9 1 对吧?

但是第二组样例有 \(3\)\(9\),所以剩下的不是 \(1\) 就是 \(9\)

看下面的表格

数字 原数量 第一次操作数量 第二次操作数量
9 3 2 0
1 2 1 1

由于数字 \(1\) 在第二次操作时候只剩下 \(1\),假设最后剩下的只有 \(1\)\(1\)\(9\) 有一个必须没)。

所以把锅推到 \(9\) 头上去,\(9\) 的数量就变成了 \(0\),剩下就只有 \(1\) 这个一个数字了。

该组样例最后输出 1

由第二组样例得出,当要减去的数量是奇数,就要多减一个数字。(即上文所说不够减数了一个必须没)

最后把总数量减去重复的数量就是剩下不重复数字的个数。

代码

#include <bits/stdc++.h>
using namespace std;
const int N = 50 + 10, M = 1e4 + 10;
int t;
int n;
int a[N], vis[M];
int main()
{
    cin >> t;
    while (t--)
    {
        memset(vis, 0, sizeof(vis)); // 初始化
        cin >> n;
        for (int i = 1; i <= n; ++i)
        {
            cin >> a[i];
            vis[a[i]]++; // 统计出现个数
        }
        int ans = 0;
        for(int i = 1; i <= n; ++i)
        {
            ans += vis[a[i]] - 1; 
            vis[a[i]] = 1; // 等于1下次加的时候就是0了,避重
        }
        if (ans % 2 == 1)
            ans++;
        cout << n - ans << endl;
    }
    cout << endl;
    return 0;
}

谢谢大家~

posted @ 2022-07-21 13:17  zrc4889  阅读(40)  评论(0)    收藏  举报