【USACO】2016 Open Field Reduction 减小田地

Field Reduction 减小田地


  • Description

Farmer John’s N cows (5 ≤ N ≤ 50,000) are all located at distinct positions in his two-dimensional field. FJ wants to enclose all of the cows with a rectangular fence whose sides are parallel to the x and y axes, and he wants this fence to be as small as possible so that it contains every cow (cows on the boundary are allowed). FJ is unfortunately on a tight budget due to low milk production last quarter. He would therefore like to build an even smaller fenced enclosure if possible, and he is willing to sell up to three cows from his herd to make this possible. Please help FJ compute the smallest possible area he can enclose with his fence after removing up to three cows from his herd (and thereafter building the tightest enclosing fence for the remaining cows). For this problem, please treat cows as points and the fence as a collection of four line segments (i.e., don’t think of the cows as “unit squares”). Note that the answer can be zero, for example if all remaining cows end up standing in a common vertical or horizontal line.

  • Input Format

The first line of input contains N. The next N lines each contain two integers specifying the location of a cow. Cow locations are positive integers in the range 1 .. 40,000.

  • Output Format

Write a single integer specifying the minimum area FJ can enclose with his fence after removing up to three carefully-chosen cows from his herd.

  • Sample Input

6
1 1
7 8
10 9
8 12
4 100
50 7

  • Sample Output

12

  • Hint

【题目大意】
农夫约翰的N(5<=N<=50000)头牛被定在了平面内的不同的位置。他想用栅栏(平行于x和y轴)围住所有的牛。他想这个栅栏尽可能小(牛在边界上也被视作围住)。
他因为牛奶产量低而感到经费紧张,所以他想卖掉三头牛再围起剩下的牛。请算出栅栏围出的最小面积。


  • 分析

我们知道卖掉的奶牛一定是最外围的奶牛,如果卖掉里面的,面积还是没有减小。
我们就先分别找出上下左右最远的三头奶牛,然后从这十二头里枚举选哪三头牛,最后计算一下答案。
(我的做法是找出最远的四头奶牛,这样在最后算答案的时候可以不用再去找。)


#include <queue>
#include <stack>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int n,x[50005],y[50005],a[5][6],p[50005],ans;
void Work(){
    int xmin,xmax,ymin,ymax;
    for (xmin=1;xmin<=4;xmin++) if (!p[a[1][xmin]]) break;
    for (xmax=1;xmax<=4;xmax++) if (!p[a[2][xmax]]) break;
    for (ymin=1;ymin<=4;ymin++) if (!p[a[3][ymin]]) break;
    for (ymax=1;ymax<=4;ymax++) if (!p[a[4][ymax]]) break;
    ans=min(ans,(x[a[2][xmax]]-x[a[1][xmin]])*(y[a[4][ymax]]-y[a[3][ymin]]));
}
int main(){
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
    scanf("%d",&n); ans=(1<<30)+1e9;
    for (int i=1;i<=n;i++){
        scanf("%d%d",&x[i],&y[i]);
        a[1][5]=a[2][5]=a[3][5]=a[4][5]=i;
        for (int i=4;i;i--){
            if (a[1][i]==0 || x[a[1][i]]>x[a[1][i+1]]) swap(a[1][i],a[1][i+1]);
            if (a[2][i]==0 || x[a[2][i]]<x[a[2][i+1]]) swap(a[2][i],a[2][i+1]);
            if (a[3][i]==0 || y[a[3][i]]>y[a[3][i+1]]) swap(a[3][i],a[3][i+1]);
            if (a[4][i]==0 || y[a[4][i]]<y[a[4][i+1]]) swap(a[4][i],a[4][i+1]);
        }
    }
    for (int i=1,ii;i<=4;i++){
        for (ii=1;ii<=3;ii++)
            if (!p[a[i][ii]]){p[a[i][ii]]=1;break;}
        if (ii==4) continue;
        for (int j=1,jj;j<=4;j++){
            for (jj=1;jj<=3;jj++)
                if (!p[a[j][jj]]){p[a[j][jj]]=1;break;}
            if (jj==4) continue;
            for (int k=1,kk;k<=4;k++){              
                for (kk=1;kk<=3;kk++)
                    if (!p[a[k][kk]]){p[a[k][kk]]=1;break;}
                if (kk==4) continue;
                Work();
                p[a[k][kk]]=0;
            }
            p[a[j][jj]]=0;
        }
        p[a[i][ii]]=0;
    }
    printf("%d",ans);
    fclose(stdin); fclose(stdout);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值