沉鱼落雁(思维题)
題目描述
胖頭魚在苦惱“沉魚落雁”是什么好吃的東西,這很顯然是因為他成語沒背夠。
于是他決定開始背成語。胖頭魚身為魚界大佬,背成語的姿勢自然也和常人不一:
他會先將所有要背的成語一字排開,比較難背的成語會重復出現,最多重復 3 次 (也就是出現次數可能為 1, 2 或 3)。這樣就得到了一個可能有重復元素的成語序列,然后他會將這個序列打亂順序,并按打亂后的順序背下去。為了均勻的背所有成語,提高背成語的效率,相同成語在打亂后的序列中出現位置的最小間隔自然是越大越好。 (編號為 a 和 b (a<b) 的兩個位置的間隔定義為 b?a?1)
現在胖頭魚把打亂前的成語序列給你,你需要幫他打亂順序,使得相同成語的最小間隔最大。
你不需要輸出確切的方案,僅求出最小間隔的最大值即可。
特別地,當每種成語都只出現一次時,把最小間隔的最大值視為n。
輸入描述
第一行一個整數 n ( 1≤n≤10^5),表示成語序列長度為 n。同一個成語最在序列中最多出現 3 次。
接下來 n 個整數 a1, a2, …, an (1≤ai≤10^9) 表示一個成語序列,每個正整數都代表一個成語,兩個成語不同當且僅當值不同。
輸出描述
輸出一個整數,表示最小間隔的最大值。
樣例輸入 1
9 5 4 3 1 3 1 1 5 5樣例輸出 1
2樣例解釋1
其中一組可行方案是1 3 5 1 3 5 1 4 5,容易驗證沒有比 22 更大的答案。
樣例輸入2
5 1 2 3 4 5樣例輸出2
5鏈接:
https://www.cometoj.com/contest/65/problem/B?problem_id=3683
解析:
思維題。
我們可以統計出現三次兩次一次元素的個數,分別記為a,b,c;
假設11122233344556,我們可以發現有3個出現三次元素,2個出現兩次的元素,1個出現一次的元素。我們可以這樣 123 45 6 123 45 6 123這樣分。
那么這時間隔為a-1+b+c/2,下取整。
如果沒有出現三次的元素,例如112234
我們可以 12 3 4 12這樣分
即 a+b-1
代碼:
#include <bits/stdc++.h> using namespace std; const int maxn = 1e5+20; int a[maxn]; map<int, int> mp; int main() {ios::sync_with_stdio(false);int n;cin >> n;mp.clear();int count1,count2,count3;count1 = count2 = count3 = 0;for(int i = 0; i < n; i++) {cin >> a[i];mp[a[i]]++;}int mx = 0;for(auto u:mp) {if(u.second == 1)count3++;else if(u.second == 2)count2++;else if(u.second == 3)count1++;mx = max(mx, u.second);}if(mx == 1) {cout << n << endl;}else if(mx == 2){cout << count2 + count3 - 1 << endl;}else cout << count1 + count2 - 1 + (count3/2) << endl;return 0; }總結
- 上一篇: 驾驶证科目一
- 下一篇: 吗咿呀嘿-用js来搞个简单的人脸识别