codeforces 595E(思維暴力)

題意:給你平面上n個點,刪除小於等於k(k<=10)個點使得能用一個最小的平行於座標系的矩陣覆蓋所有點
題解:顯然,一定是刪除“最外面”的點是最優的。
那麼對所有點分別以x、y排序,枚舉上下左右邊界,判斷最小面積。


這個思路第一次見,很神奇


#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#include <cstdio>
#include <string>
#include <cstring>
#include <vector>
#include <set>
#include <map>
#include <sstream>
#include <cmath>
#define LL long long
#define mod 1000000007
using namespace std;
const int maxn = 500000 + 5;
const LL INF = 1e18 + 5;
struct Point{
    double x,y;
    int id;
}p0[maxn],p1[maxn];
bool cmp1(Point p, Point q){
    return p.x < q.x;
}
bool cmp2(Point p, Point q){
    return p.y < q.y;
}
bool judge(int i0, int i1, int i2, int i3, int n, int k){
    LL L0 = p0[i0].x;
    LL R0 = p0[n-1-i1].x;
    LL L1 = p1[i2].y;
    LL R1 = p1[n-1-i3].y;
    if(L0 > R0 || L1 > R1) return false;
    set<int> del;
    for(int i=0; i<i0; i++)
        del.insert(p0[i].id);
    for(int i=n-i1; i<n; i++)
        del.insert(p0[i].id);
    for(int i=0; i<i2; i++)
        del.insert(p1[i].id);
    for(int i=n-i3; i<n; i++)
        del.insert(p1[i].id);
    if(del.size() <= k) return true;
    return false;
}
int main(){
    int n,k;
    scanf("%d%d",&n,&k);
    k = min(n-1,k);
    for(int i=0; i<n; i++){
        double x1,y1,x2,y2;
        scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
        p0[i].x = p1[i].x = (x1 + x2) / 2;
        p0[i].y = p1[i].y = (y1 + y2) / 2;
        p0[i].id = p1[i].id = i;
    }
    LL ans = INF;
    sort(p0,p0+n,cmp1);
    sort(p1,p1+n,cmp2);
    for(int i=0; i<=k; i++){
        for(int j=0; j<=k; j++){
            for(int p=0; p<=k; p++){
                for(int q=0; q<=k; q++){
                    if(judge(i,j,p,q,n,k)){
                        double l0 = p0[i].x;
                        double r0 = p0[n-1-j].x;
                        double l1 = p1[p].y;
                        double r1 = p1[n-1-q].y;
                        LL l = (LL)(r0-l0+0.5);
                        LL r = (LL)(r1-l1+0.5);
                        if(l == 0) l = 1;
                        if(r == 0) r = 1;
                        ans = min(ans, l*r);
                    }
                }
            }
        }
    }
    printf("%lld\n",ans);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章