Codeforces 1012A Photo of The Sky
阿新 • • 發佈:2018-07-31
++ main line name get out for mat 接下來
作為一個蒟蒻,\(\tt{CF}\)止步\(Div.2\;C\)
這個題主要考察思維,正解代碼炒雞短……
以下大部分搬運自官方題解
題目大意:
給你一段長度為\(2n\)的數列,將這個數列分為兩個可重集,每個集合有\(n\)個元素,使得這兩個集合的極差之積最小,輸出這個最小值
題解:
假設輸入的數組為\(a[2n]\),為了方便,我們把要分成的兩個可重集叫做\(X\)和\(Y\)
首先肯定要先\(sort\)一下,使得數組有序,方便操作(下文提到的數組都是有序的)
接下來就是分類討論了:
第一種情況:數組a的最大值和最小值都在\(X\)裏。那麽\(X\)的極差就是\(a[2n]-a[1]\)
答案為 \(\min((a[i+n-1]-a[i])\cdot(a[2n]-a[1]))\;i\in [2,n+1]\)第二種情況:最大值和最小值分別在\(X\)和\(Y\)裏。這樣我們就要使\(X\)的最大值最小,\(Y\)的最大值最大,那麽\(X\)
答案為 \((a[n]-a[1])\cdot (a[2n]-a[n+1])\)
最終的答案從這兩種情況中取一個最小值就好了。
時間復雜度\(O(nlogn)\)(也就是排序的復雜度)
最後提醒一句:別忘了開\(\mathfrak{long\;long}\)
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define ll long long using namespace std; int read(){ int k=0; char c=getchar(); for(;c<'0'||c>'9';) c=getchar(); for(;c>='0'&&c<='9';c=getchar()) k=(k<<3)+(k<<1)+c-48; return k; } ll a[100010<<1],ans; int main(){ int n=read(); for(int i=1;i<=n<<1;i++) a[i]=read(); sort(a+1,a+(n<<1)+1); ans=(a[n]-a[1])*(a[n<<1]-a[n+1]); //第二種情況 for(int i=2;i<=n+1;i++) //第一種情況 ans=min((a[n<<1]-a[1])*(a[i+n-1]-a[i]),ans); cout<<ans; return 0; }
Codeforces 1012A Photo of The Sky