題目描述
小明的老師準備組織一次班級活動。班上一共有 ( n ) 名(( n ) 為偶數)同學,老師想把所有的同學進行分組,每兩名同學一組。為了公平,老師給每名同學隨機分配了一個 ( n ) 以內的正整數作為 id,第 ( i ) 名同學的 id 為 ( a_i )。
老師希望透過更改若干名同學的 id 使得對於任意一名同學 ( i ),有且僅有另一名同學 ( j ) 的 id 與其相同(( a_i = a_j ))。請問老師最少需要更改多少名同學的 id?
輸入格式
輸入共 2 行。
第一行為一個正整數 ( n )。
第二行為 ( n ) 個由空格隔開的整數 ( a_1, a_2, ..., a_n )。
輸出格式
輸出共 1 行,一個整數。
輸入輸出樣例
輸入 #1
4
1 2 2 3
輸出 #1
1
說明/提示
樣例說明
僅需要把 ( a_1 ) 改為 3 或者把 ( a_4 ) 改為 1 即可。
評測用例規模與約定
- 對於 20% 的資料,保證 ( n <= 10^3 )。
- 對於 100% 的資料,保證 ( n <= 10^5 )。
題解:
一共有兩種情況
- 只出現過一次的id個數 cnt1 >= 出現過2次以上的id個數 cnt2。 此時把 所有cnt2 都更改成一個id只出現過一次的, 再加上剩下的 cnt1 / 2
- 只出現過一次的id個數 cnt1 < 出現過2次以上的id個數 cnt2。 此時把 cnt1個cnt2 都改成一個id只出現過一次的, 再加上剩下的 cnt2 /2
ps: 說白了就是 當有cnt1的時候, 儘可能把cnt2變成cnt1, 當cnt2有剩餘的話, 還需要改變 "剩餘的cnt2的個數" 次, 當cnt1有剩餘的話, 還需要改變 "剩餘的cnt1的個數 / 2"
ac程式碼👇
#include <bits/stdc++.h>
using namespace std;
unordered_map<int,int> mp;
int main()
{
int n; cin >> n;
for (int i = 0; i < n; i ++)
{
int x; cin >> x;
mp[x] ++;
}
int cnt1 = 0, cnt2 = 0;
for (auto it : mp)
{
if (it.second == 1) cnt1 ++; // id出現過一次的個數
if (it.second > 2) cnt2 += it.second - 2; // id出現次數大於2的都要改成別的id
}
if (cnt2 - cnt1 >= 0) cout << cnt1 + (cnt2 - cnt1) << endl; // 情況1
else cout << cnt2 + (cnt1 - cnt2) / 2 << endl; // 情況2
return 0;
}
覺得寫的不錯的話, 點個贊吧~