问题描述
小明的老师准备组织一次班级活动。班上一共有 nn 名 (nn 为偶数) 同学,老师想把所有的同学进行分组,每两名同学一组。为了公平,老师给每名同学随机分配了一个 nn 以内的正整数作为 idid,第 ii 名同学的 idid 为 aiai。
老师希望通过更改若干名同学的 idid 使得对于任意一名同学 ii,有且仅有另一名同学 jj 的 idid 与其相同 (ai=ajai=aj)。请问老师最少需要更改多少名同学的 idid?
输入格式
输入共 22 行。
第一行为一个正整数 nn。
第二行为 nn 个由空格隔开的整数 a1,a2,...,ana1,a2,...,an。
#include <stdio.h>
//大思路:通过统计每个id出现的次数,出现一次的则是我们需要更改的,按照这种想法我们用n = 6 可以举出很多例子,自己写一写算一算找出规律即可
int main(int argc, char *argv[])
{int i = 0 ;int id; int n;scanf("%d",&n);int count[100005]={0};//获取班上一共有n名同学for(i = 0 ; i < n ; i++){scanf("%d",&id);count[id]++;}//获取随机的id,并且统计每个id出现的次数int moreNum = 0;int onceNum = 0;//more记录出现超过两次的id次数//once记录出现次数只有一次的id数量for(i = 1 ; i <= n ; i ++ ){//!!易错,我一开始在这里从 i= 0 , i < n 但是实际上我们需要遍历到n因为在这里不是指的下标,而是每个键所对应的值if (count[i] > 2){moreNum = moreNum + (count[i] - 2);}else if( count[i] == 1){onceNum = onceNum + 1;}}//分别统计超过两次的id 和 只出现一次的idif(moreNum >= onceNum ){printf("%d",moreNum);}else{printf("%d",(onceNum + moreNum) / 2);}//如果moreNUM 是大于等于 onceNum 的情况,则 moreNum 有多少至少就需要更改多少 //例如 1 1 1 1 2 3 和 1 1 1 1 1 2//由于题目中所说任意的 i 有且仅有 一个 j 与其对应 , 所以moreNum就是至少需要更改次数//如果是小于的情况 则他俩相加除二即可//例如 1 1 1 2 3 4 和 1 1 1 2 3 4 5 6 //多出来的一个至少可以解决一个落单的,则剩下两个至少要改变一次return 0;
}