[每日一题]:C. Two Teams Composing
题目:
题目大意:
给一个序列,将这个序列分成两部分,一部分内是相同的元素,另一部分内是不同的元素。
然后不同的元素里面可以出现不同的元素里面的元素,但是位置不能相同。
问满足这样的条件的最大序列。
侃侃:
哈哈,一言难尽,实际上这道题不难,有一个点一直没有 get 到,导致 WA 了好几次。
显而易见,最后的最大序列一定是 两部分中较少的那部分。
思路:
用 map 统计每个数出现的次数(由于数值范围较小,也可用数组)
(用于找最大的相同的数 的数量)
用 set 统计有多少个不同的数
这时候 set 里面和 map 里面有一个值是重复的,我们要去掉哪个部分里面的最小值是不确定
的,干脆每个都取一下(实际上只有两种),然后从这两种情况里面取一个最大值即可。
Code:
#include <set>
#include <map>
#include <cstdio>
#include <string>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
set<int>sets;
map<int,int>maps;
map<int,int>::iterator it;
int t,n,value;
int main(void) {
scanf("%d",&t);
while(t --) {
scanf("%d",&n);
for(int i = 1; i <= n; i ++) {
scanf("%d",&value);
sets.insert(value);
maps[value] ++;
}
// 特判
if(n == 1) puts("0");
else if(sets.size() == n || (sets.size() == 1)) puts("1");
else {
int maxValue = -1;
// 遍历寻找相同的值中数量最多的,作为一部分
for(it = maps.begin(); it != maps.end(); it ++) {
maxValue = max(maxValue,it->second);
}
// 不同的数的数量
int ans = sets.size();
// 分别去掉相同的位置的那个重复的值
int min1 = min(ans - 1,maxValue);
int min2 = min(ans,maxValue - 1);
// 最后取最大值即可
printf("%d\n",max(min1,min2));
}
sets.clear();
maps.clear();
}
return 0;
}
后记:
发现自己越来越菜了,发现学弟越来越强了。
先想好每一步,再动手走下一步。
加油,奥里给!
如果说年轻人未来是一场盛宴的话,那么我首先要有赴宴的资格。