1. 程式人生 > >1013 C. Photo of The Sky

1013 C. Photo of The Sky

names long pro sizeof 如果 [1] pre syn ace

傳送門

[http://codeforces.com/contest/1013/problem/C]

題意

輸入一個n代表n顆星星,輸入2n個數,其中任意兩個數代表一顆行星的坐標,問你把n個星星圍起來的最小矩形面積。

思路

先對2n 個數小到大排序,因為矩形是要求把這n個點框住的,所以稍微想一下不難得到:S=(max(x)?min(x))?(max(y)?min(y))
於是我們將原問題這樣轉化:

給你2n個數,把這2n個數放在兩個集合當中,每個集合的元素個數為n,設這兩個集合分別為X,Y,
求min((Xmax?Xmin)?(Ymax?Ymin))
接下來我們來討論,如何分放集合。

考慮如果最大數a2n與最小數a1如果在同一個集合X,那麽現在我們要求min(Ymax?Ymin)。

考慮一下怎樣的情況才會有min(Ymax?Ymin)的情況出現。假設Ymin在a中為ai,那麽Ymax在a中一定為ai+n?1,為什麽呢?

如果Ymax在ai+1?>ai+n?2之間,那麽Y集合裏面的元素個數就沒有要求的n個了,不滿足。

如果Ymax在ai+n?>a2n?1之間,那麽顯然可以在滿足元素個數為n的情況下使Ymax最小。

所以在最大數a2n與最小數a1如果在同一個集合X時,答案的值為:
Ans=min(a[2n]?a[1])?(a[i+n?1]?a[i])2≤i≤n
那麽還有一種情況就是最大數a2n與最小數a1不在同一個集合當中,與上面類似的討論不難得到最後的結果唯一:
Ans=(a[2n]?a[n+1])?(a[n]?a[1])
所以我們最後的結果在上面兩者之間取最小即可。

代碼

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=200010;
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    //freopen("in.txt","r",stdin);
    int n,i;
     ll a[maxn];
    while(cin>>n){
        memset(a,0,sizeof(a));
        for(i=1;i<=2*n;i++)
        cin>>a[i];
        sort(a+1,a+2*n+1);
        ll ans=(a[2*n]-a[n+1])*(a[n]-a[1]);
        for(i=2;i<=n;i++)
        ans=min(ans,(a[2*n]-a[1])*(a[n+i-1]-a[i]));
        cout<<ans<<endl;
    }
    return 0;
}

1013 C. Photo of The Sky