BZOJ 4581: [Usaco2016 Open]Field Reduction

Description

有 \(n\) 个点,删掉三个点后,求最小能围住的面积.

Sol

搜索.

找出 左边/右边/上边/下边 的几个点枚举就可以了.

我找了 12 个点,统计一下坐标的个数,然后找到最大最小坐标.

PS:md.Cena 好像对 STL 不太友好啊,用 map 居然T了???exm???

昨天用 map 离散化就T的飞起.md..mama我再也不用 map 离散化了...以后用lower_bound()好了...

一开始写了个DFS来枚举...发现不是很好...又删掉变成三维循环枚举...代码奇丑无比...

Code

/**************************************************************
    Problem: 4581
    User: BeiYu
    Language: C++
    Result: Accepted
    Time:440 ms
    Memory:5168 kb
****************************************************************/

#include <cstdio>
#include <map>
#include <utility>
#include <algorithm>
#include <iostream>
using namespace std;

typedef long long LL;
const int N = 50050;
const int M = 15;
int C = 12;

struct P{ int x,y,id; };
bool operator < (const P &a,const P &b){ return a.x==b.x?a.y<b.y:a.x<b.x; }
bool operator == (const P &a,const P &b){ return (a.x==b.x) && (a.y==b.y); }

int n;LL ans;
int b[N],xx[N],yy[N],cx[N],cy[N];
P a[N],p[N];
P mxx[M],mxy[M],mix[M],miy[M];
P del[M];

map< int,int > mpx,mpy;

inline int in(int x=0){ scanf("%d",&x);return x; }
/*
LL calc(){
//  cout<<"--------------"<<endl;
//  for(int i=1;i<=3;i++) cout<<del[i].x<<" "<<del[i].y<<endl;
    int minx=1,maxx=n,miny=1,maxy=n;
    for(int i=3;i>=1;i--){
        if(del[i].x == xx[minx]) minx++;
        if(del[i].x == xx[maxx]) maxx--;
        if(del[i].y == yy[miny]) miny++;
        if(del[i].y == yy[maxy]) maxy--;
    }
    for(int i=3;i>=1;i--){
        if(del[i].x == xx[minx]) minx++;
        if(del[i].x == xx[maxx]) maxx--;
        if(del[i].y == yy[miny]) miny++;
        if(del[i].y == yy[maxy]) maxy--;
    }
    for(int i=3;i>=1;i--){
        if(del[i].x == xx[minx]) minx++;
        if(del[i].x == xx[maxx]) maxx--;
        if(del[i].y == yy[miny]) miny++;
        if(del[i].y == yy[maxy]) maxy--;
    }
//  cout<<xx[maxx]<<" "<<xx[minx]<<" "<<yy[maxy]<<" "<<yy[miny]<<endl;
//  cout<<1LL*(xx[maxx]-xx[minx])*(yy[maxy]-yy[miny])<<endl;
    return 1LL*(xx[maxx]-xx[minx])*(yy[maxy]-yy[miny]);
}
void DFS(int w,int d){
    if(w==4 || d==0){ if(!d) ans=min(ans,calc());return; }
    int c=0;
    DFS(w+1,d);
    int tmp[M];
    switch(w){
        case 0:
            for(int i=1;i<=C;i++){
                if(c>d) break;
                if(!b[mix[i].id]) tmp[++c]=mix[i].id,del[d-c+1]=mix[i],b[mix[i].id]=1,DFS(w+1,d-c);
            }break;
        case 1:
            for(int i=1;i<=C;i++){
                if(c>d) break;
                if(!b[mxx[i].id]) tmp[++c]=mxx[i].id,del[d-c+1]=mxx[i],b[mxx[i].id]=1,DFS(w+1,d-c);
            }break;
        case 2:
            for(int i=1;i<=C;i++){
                if(c>d) break;
                if(!b[miy[i].id]) tmp[++c]=miy[i].id,del[d-c+1]=miy[i],b[miy[i].id]=1,DFS(w+1,d-c);
            }break;
        case 3:
            for(int i=1;i<=C;i++){
                if(c>d) break;
                if(!b[mxy[i].id]) tmp[++c]=mxy[i].id,del[d-c+1]=mxy[i],b[mxy[i].id]=1,DFS(w+1,d-c);
            }break;
    }
    for(int i=1;i<=c;i++) b[tmp[i]]=0;
    return;
}*/
int main(){ n=in();C=min(C,n),ans=1e18;
    for(int i=1;i<=n;i++) a[i].x=in(),a[i].y=in(),a[i].id=i;

    for(int i=1;i<=n;i++) xx[i]=a[i].x,yy[i]=a[i].y;
    sort(xx+1,xx+n+1),sort(yy+1,yy+n+1);
    cx[0]=unique(xx+1,xx+n+1)-(xx+1),cy[0]=unique(yy+1,yy+n+1)-(yy+1);
    for(int i=1;i<=cx[0];i++) mpx[xx[i]]=i;
    for(int i=1;i<=cy[0];i++) mpy[yy[i]]=i;
    for(int i=1;i<=n;i++) cx[mpx[a[i].x]]++,cy[mpy[a[i].y]]++;

    int cnt=0;
    sort(a+1,a+n+1);
    for(int i=1;i<=C;i++) p[++cnt]=a[i];

    for(int i=1;i<=n;i++) a[i].x=-a[i].x;
    sort(a+1,a+n+1);
    for(int i=1;i<=C;i++) p[++cnt]=a[i],p[cnt].x=-p[cnt].x;

    for(int i=1;i<=n;i++) a[i].x=-a[i].x,swap(a[i].x,a[i].y);
    sort(a+1,a+n+1);
    for(int i=1;i<=C;i++) p[++cnt]=a[i],swap(p[cnt].x,p[cnt].y);

    for(int i=1;i<=n;i++) a[i].x=-a[i].x;
    sort(a+1,a+n+1);
    for(int i=1;i<=C;i++) p[++cnt]=a[i],p[cnt].x=-p[cnt].x,swap(p[cnt].x,p[cnt].y);

    sort(p+1,p+cnt+1);
//  for(int i=1;i<=cnt;i++) cout<<p[i].x<<" "<<p[i].y<<endl;
    cnt=unique(p+1,p+cnt+1)-(p+1);

//  for(int i=1;i<=cnt;i++) cout<<p[i].x<<" "<<p[i].y<<endl;

    for(int i=1;i<=cnt;i++) for(int j=i+1;j<=cnt;j++) for(int k=j+1;k<=cnt;k++){
        cx[mpx[p[i].x]]--,cx[mpx[p[j].x]]--,cx[mpx[p[k].x]]--;
        cy[mpy[p[i].y]]--,cy[mpy[p[j].y]]--,cy[mpy[p[k].y]]--;

        int minx=1,maxx=cx[0],miny=1,maxy=cy[0];
        while(!cx[minx]) minx++;
        while(!cx[maxx]) maxx--;
        while(!cy[miny]) miny++;
        while(!cy[maxy]) maxy--;
        ans=min(ans,1LL*(xx[maxx]-xx[minx])*(yy[maxy]-yy[miny]));

        cx[mpx[p[i].x]]++,cx[mpx[p[j].x]]++,cx[mpx[p[k].x]]++;
        cy[mpy[p[i].y]]++,cy[mpy[p[j].y]]++,cy[mpy[p[k].y]]++;
    }

//  for(int i=1;i<=n;i++) cout<<xx[i]<<" ";cout<<endl;
//  for(int i=1;i<=n;i++) cout<<yy[i]<<" ";cout<<endl;

//  sort(a+1,a+n+1);
//  for(int i=1;i<=C;i++) mix[i]=a[i];
//
//  for(int i=1;i<=n;i++) a[i].x=-a[i].x;
//  sort(a+1,a+n+1);
//  for(int i=1;i<=C;i++) mxx[i]=a[i],mxx[i].x=-mxx[i].x;
//
//  for(int i=1;i<=n;i++) a[i].x=-a[i].x,swap(a[i].x,a[i].y);
//  sort(a+1,a+n+1);
//  for(int i=1;i<=C;i++) miy[i]=a[i],swap(miy[i].x,miy[i].y);
//
//  for(int i=1;i<=n;i++) a[i].x=-a[i].x;
//  sort(a+1,a+n+1);
//  for(int i=1;i<=C;i++) mxy[i]=a[i],mxy[i].x=-mxy[i].x,swap(mxy[i].x,mxy[i].y);

//  cout<<"--------------"<<endl;
//  for(int i=1;i<=C;i++) cout<<mix[i].x<<" "<<mix[i].y<<endl;
//  cout<<"--------------"<<endl;
//  for(int i=1;i<=C;i++) cout<<mxx[i].x<<" "<<mxx[i].y<<endl;
//  cout<<"--------------"<<endl;
//  for(int i=1;i<=C;i++) cout<<miy[i].x<<" "<<miy[i].y<<endl;
//  cout<<"--------------"<<endl;
//  for(int i=1;i<=C;i++) cout<<mxy[i].x<<" "<<mxy[i].y<<endl;
//  cout<<"--------------"<<endl;

//  DFS(0,3);

    cout<<ans<<endl;
    return 0;
}

  

时间: 2024-10-23 14:15:52

BZOJ 4581: [Usaco2016 Open]Field Reduction的相关文章

BZOJ 4576: [Usaco2016 Open]262144

Description 一个序列,每次可以将两个相同的数合成一个数,价值+1,求最后最大价值 \(n \leqslant 262144\) Sol DP. 这道题是 BZOJ 4580: [Usaco2016 Open]248 加强版. 做248的那个区间DP其实很多方案都是0,而且一个区间中只有一个合法的数字. 然后就是 一个区间合成一个数的方案的这个数字是固定的. \(f[i][j]\) 表示以 \(i\) 结尾是否能合成 \(j\),同时记录一下转移位置,每次向前找前一个指针就可以了. 复

BZOJ 4742: [Usaco2016 Dec]Team Building

4742: [Usaco2016 Dec]Team Building Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 21  Solved: 16[Submit][Status][Discuss] Description Every year, Farmer John brings his NN cows to compete for "best in show" at the state fair. His arch -rival, F

bzoj 4412: [Usaco2016 Feb]Circular Barn

4412: [Usaco2016 Feb]Circular Barn Description 有一个N个点的环,相邻两个点距离是1.点顺时针标号为1..N.每一个点有ci头牛,保证∑ci=N.每头牛都可以顺时针走.设一头牛走了d个单位停下了,将耗费d^2的能量.请设计一种牛的走法,使得每一个点上都正好有一头牛,且最小化耗费的能量. Input 第一行一个数N.N <= 100000接下来N行,每行一个数ci. Output 输出一个数表示耗费能量的最小值 Sample Input 10 1 0

bzoj 4506: [Usaco2016 Jan]Fort Moo

4506: [Usaco2016 Jan]Fort Moo Description Bessie is building a fort with her friend Elsie. Like any good fort, this one needs to start with a sturdy frame. Bessie wants to build a frame in the shape of a one-meter-wide rectangular outline, atop which

Bzoj 4582 [Usaco2016 Open] Diamond Collector 题解

4582: [Usaco2016 Open]Diamond Collector Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 204  Solved: 136[Submit][Status][Discuss] Description Bessie the cow, always a fan of shiny objects, has taken up a hobby of mining diamonds in her spare time! Sh

BZOJ 4579: [Usaco2016 Open]Closing the Farm

Description 依次删去一个点和它的边,问当前图是否连通. Sol 并查集. 倒着做就可以了. 每次将一个点及其的边加入,如果当前集合个数大于 1,那么就不连通. Code /************************************************************** Problem: 4579 User: BeiYu Language: C++ Result: Accepted Time:2196 ms Memory:10328 kb *********

BZOJ 4580: [Usaco2016 Open]248

Description 一个序列,每次可以把相邻的两个数合为一个,价值+1,求最后的最大价值. Sol 区间DP. \(f[i][j]\) 表示 \(i-j\) 中合成一个数字为多少,转移就是枚举断点,断点两边的价值一样,就合并. 复杂度 \(O(n^3)\) Code /************************************************************** Problem: 4580 User: BeiYu Language: C++ Result: Ac

BZOJ 4582: [Usaco2016 Open]Diamond Collector

Descrirption 给你一个长度为 \(n\) 的序列,求将它分成两个序列后最多个数,每个序列最大值最小值不能超过 \(k\) Sol 二分+DP. 排一下序,找出以这个点结尾和开始的位置. 这个玩意可以二分也可以用单调队列,随便搞啊... 然后统计答案就是枚举第二个序列的起点,然后往后扫的时候统计一下,第一个序列的最大长度就可以了. Code /************************************************************** Problem:

bzoj4578: [Usaco2016 OPen]Splitting the Field

bzoj4578: [Usaco2016 OPen]Splitting the Field Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 56  Solved: 15[Submit][Status][Discuss] Description Farmer John's N cows (3≤N≤50,000) are all located at distinct positions in his two-dimensional fie ld. F