[每日一题]: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;
}

后记:

发现自己越来越菜了,发现学弟越来越强了。
先想好每一步,再动手走下一步。
加油,奥里给!
posted @ 2020-04-28 19:17  IceSwords  阅读(213)  评论(0编辑  收藏  举报