[Codeforces] 1012A. Photo of The Sky

.題目URL: http://codeforces.com/problemset/problem/1012/A
.有些的小技巧要注意,可先畫個座標去發現構成最小面積矩形的approach,即是左右與上下之距離最小、其他點包含在矩形內、最外圍的兩端點為邊界的最大與最小。當然,最initial的想法一定是對半剖分、其一reverse後的首與尾差積括號絕對值(25~27行ans=xx*yy;)
.(這題我看其他電神用sort就可以過,但我還用priority_queue,取兩端) 因為我最一開始以為可能性O(n^2)的內建sort會吃TLE,可能此題可以壓線過,相對性的,我怕這件事發生(因為是比賽)所以我用空間換取時間 。
.但是,直到目前的說法依舊是有缺陷的,如果一個特測是: 1 1 2 3 3 3 4 11 那麼我的答案是16,可是答案是10。
.接著停下來想一想,如果我將x軸以最小與最大的典固定,此時,我無論y軸的兩個數字為何,兩陣列各取一數字所組成的一個點「必定」至少一種方式使每一點坐落於矩形內(?),此時全部暴搜一遍即可(O(n^2)),結果會吃TLE~~QQ(而且很不幸的有些會WA)
.再停下來想一下,固定的部分以直覺上與經驗上的method貌似沒錯,但:
    .(a)如何優化那看似擾人的暴搜?
    .(b)如何判斷真的是「至少一個必定」且最小?
.以特測 1 1 2 3 3 3 4 11 判斷,如果以暴搜會得到(1,3) (11,3),答案是0,但有一個地方出錯了,會有一點(1,4)會超過原定矩形範圍
    .如何結合(a)與(b)?
. 先解決最小的問題,就用min去跑兩陣列除了首點之點兩個相減最小。然後兩陣列的兩數由小跑到大,就能維持上下的範圍且當狀態的最小。

#include<bits/stdc++.h>
using namespace std;
map<long long int,long long int> str1,str2,str;
main()
{
    long long int ans;
    priority_queue<long long int,vector<long long int>> maxpq;
    priority_queue<long long int,vector<long long int>,greater<long long int>> minpq;
    long long int num;
    cin >> num;
    for(long long int i=0;i<num*2;i++)
    {
        cin >> str[i];
        minpq.push(str[i]);
        maxpq.push(str[i]);
    }
    for(long long int i=0;i<num;i++)
    {
        str1[i]=minpq.top();
        minpq.pop();
    str2[i]=maxpq.top();
    maxpq.pop();
    }
    long long int xx,yy;
    xx=abs(str1[0]-str1[num-1]);
    yy=abs(str2[0]-str2[num-1]);
    ans=xx*yy;
    for(long long int i=1;i<num;i++)
        ans=min(ans,abs(str1[0]-str2[0])*abs(str1[i]-str2[num-i]));
    cout << ans << endl;
    return 0;
}


留言

這個網誌中的熱門文章

[ZJ] b229: TOI 2009 第一題:路徑問題

交大資工(APCS組)(面試&心得)

滿是挫傷的ION CAMP