日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

2018百度之星程序设计大赛初赛B——1004p1m2

發(fā)布時(shí)間:2023/12/9 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 2018百度之星程序设计大赛初赛B——1004p1m2 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

HDU-6383

題目:

度度熊很喜歡數(shù)組!!

我們稱一個(gè)整數(shù)數(shù)組為穩(wěn)定的,若且唯若其同時(shí)符合以下兩個(gè)條件:

1. 數(shù)組里面的元素都是非負(fù)整數(shù)。
2. 數(shù)組里面最大的元素跟最小的元素的差值不超過?1。

舉例而言,[1,2,1,2]?是穩(wěn)定的,而?[?1,0,?1]?跟?[1,2,3]?都不是。

現(xiàn)在,定義一個(gè)在整數(shù)數(shù)組進(jìn)行的操作:

* 選擇數(shù)組中兩個(gè)不同的元素?a?以及?b,將?a?減去?2,以及將?b?加上?1。

舉例而言,[1,2,3]?經(jīng)過一次操作后,有可能變?yōu)?[?1,2,4]?或?[2,2,1]。

現(xiàn)在給定一個(gè)整數(shù)數(shù)組,在任意進(jìn)行操作后,請問在所有可能達(dá)到的穩(wěn)定數(shù)組中,擁有最大的『數(shù)組中的最小值』的那些數(shù)組,此值是多少呢?

?

?

Input

輸入的第一行有一個(gè)正整數(shù)?T,代表接下來有幾組測試數(shù)據(jù)。

對于每組測試數(shù)據(jù):
第一行有一個(gè)正整數(shù)?N。
接下來的一行有?N?個(gè)非負(fù)整數(shù)?xi,代表給定的數(shù)組。

*?1≤N≤3×105
*?0≤xi≤108
*?1≤T≤18
* 至多?1?組測試數(shù)據(jù)中的?N>30000

?

?

Output

對于每一組測試數(shù)據(jù),請依序各自在一行內(nèi)輸出一個(gè)整數(shù),代表可能到達(dá)的平衡狀態(tài)中最大的『數(shù)組中的最小值』,如果無法達(dá)成平衡狀態(tài),則輸出??1。

?

?

Sample Input

?

2 3 1 2 4 2 0 100000000

?

?

Sample Output

?

2 33333333

?

?

A為原數(shù)列,A*為由A變化成的穩(wěn)定數(shù)列,那么題目所求的就是 所有A*中的最小值最大的一個(gè),把這個(gè)值記為ans

首先可以先考慮能不能直接暴力枚舉所有A*,然后求解......?很明顯是不符合實(shí)際的。

換種想法,能不能讓ans從無窮大遍歷到0,暴力枚舉所有ans,然后判斷這個(gè)ans是否可以構(gòu)成A*。

那么要先解決判斷的問題。

題目要求的是:* 選擇數(shù)組中兩個(gè)不同的元素?a?以及?b,將?a?減去?2,以及將?b?加上?1。(這里“不同”指的是下標(biāo)不同)

也就是進(jìn)行一次減法(-2),必須要進(jìn)行一次加法(+1),兩種操作的次數(shù)要相等。那么可以分開操作,然后再來看兩種操作的次數(shù)。

我們先對原數(shù)列A中所有小于ans的數(shù)A[i],做加法,num_p += ans - A[i]

然后對原數(shù)列A中所有大于ans+1的數(shù)A[i],做減法,num_m += (A[i] - ans) / 2

這里可能會(huì)出現(xiàn)A[i] - ans 是奇數(shù)的情況,如:(A[i] - ans) / 2 = 3 /?2 = 1,那么其實(shí)這時(shí)候,A[i]做完減法后得到的數(shù)應(yīng)該是ans+1,它可以作為這個(gè)數(shù)列A*的最大值,使得數(shù)列A*仍然滿足 “穩(wěn)定” 的條件。(min:ans,max:ans+1)

接下來要對num_p(進(jìn)行加法的次數(shù))和 num_m(進(jìn)行減法的次數(shù))做比較:

num_p =?num_m 的情況:說明這個(gè)ans可以作為穩(wěn)定數(shù)列A*的最小值。
num_p !=?num_m 的情況:

首先要了解的一點(diǎn)是:

對于一個(gè)數(shù)列A,如果它的最小值為min(A),那么它可以通過題目所述的兩種操作,來得到一個(gè)穩(wěn)定數(shù)組A*,其最小值仍為min(A)。具體做法是:我們更新數(shù)組A,將A中最小值+1,最大值-2,不斷重復(fù)這個(gè)過程。由于減掉的比加上的多,最終數(shù)組A中的最大最小值會(huì)不斷地相互逼近,直到最小值為min(A)。

那么對于num_p < num_m:此時(shí)當(dāng)加法減法配對后,仍有一些數(shù)需要進(jìn)行減法操作,也就是說,此時(shí)的數(shù)列A最小值已經(jīng)是ans了,存在一些數(shù)大于ans+1,那么根據(jù)上面的結(jié)論,這個(gè)數(shù)列A是可以得到穩(wěn)定數(shù)組的,所以這個(gè)ans合法。

對于num_p > num_m :此時(shí)當(dāng)加法減法配對后,仍有一些數(shù)需要進(jìn)行加法操作,由于我們進(jìn)行的是-2,+1,也就是總的來說肯定是朝減少的方向進(jìn)行,既然出現(xiàn)還要加上的操作,只能說明這個(gè)ans還太大了,滿足不了,得不到穩(wěn)定數(shù)組。

?

解決完判斷的問題,剩下的就是對ans的范圍從原先的 0~∞ 進(jìn)一步縮減。

很明顯的上界應(yīng)當(dāng)為數(shù)列A的最大值max(A):倘若大于max(A)的話,那么A中所有的數(shù)都要往上加才行,由于有減法操作,實(shí)現(xiàn)不了;

下界應(yīng)當(dāng)為數(shù)列A的最小值min(A):在前面紅色的結(jié)論已經(jīng)說明了,ans至少會(huì)等于min(A)。

那么可以看出采用的算法應(yīng)該是二分法,邊界:min(A)~ max(A)

代碼:

// // main.cpp // 初賽B1004 // // Created by jinyu on 2018/8/13. // Copyright ? 2018年 jinyu. All rights reserved. //#include <iostream> #include <cstdio> #include <algorithm> using namespace std;typedef long long LL; const int MAXN = 3e5+7; const long long INF = 0x3f3f3f3f3f3f;long long A[MAXN]; int N;bool judge(LL ans){LL num_p = 0;LL num_m = 0;for(int i = 0;i<N;++i){if(ans > A[i])num_p += ans-A[i];else if(ans+1 < A[i])num_m += (A[i]-ans)/2;}return num_m>=num_p; }int main(){int T;scanf("%d",&T);while (T--) {scanf("%d",&N);LL R = -1;LL L = INF;for(int i = 0;i<N;++i)scanf("%lld",&A[i]);sort(A,A+N);L = A[0];R = A[N-1];LL ans = -1;while(L<=R){LL mid = (L+R)/2;if(judge(mid)){L = mid + 1;ans = mid;}elseR = mid - 1;}printf("%lld\n",ans);}return 0; }

?

總結(jié)

以上是生活随笔為你收集整理的2018百度之星程序设计大赛初赛B——1004p1m2的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。