usaco2016open silver1 reduce

来源:互联网 发布:蒋勤勤的长相知乎 编辑:程序博客网 时间:2024/06/06 03:54

Sliver1

农夫约翰的N(5<=N<=50000)头牛被定在了平面内的不同的位置。他想用栅栏(平行于xy)围住所有的牛。他想这个栅栏尽可能小(牛在边界上也被视作围住)

他因为牛奶产量低而感到经费紧张,所以他想卖掉三头牛再围起剩下的牛。请算出栅栏围出的最小面积。

输入:

第一行输入n

剩下2-n+1行,输入每头牛的位置。

输出:
最小面积。

示例

input

6

1 1

7 8

10 9

8 12

4 100

50 7

output

12

================================================================

平面上有 n个点,给出它们的坐标,去除 3个点之后,其余(n-3)个点用一个矩形围起来,求这个矩形的最小面积.和铜牌组一样,我们从枚举入手,但容易证明的是,无论我们去除哪些点,它们都一定是最外三层的点.换言之,假如我们把所有点的 x 坐标排序后储存在 x 数组中,y 坐标也同样操作,最后去掉的三个点一定在[x1,x3],[xn-2,xn],[y1,y3][yn-2,yn]这些点中产生,这样才能使矩形面积尽可能地小,才满足题意.在这个前提条件下,我们就可以只枚举最外层的 3 个点,共只有 4^3 种情况,也就是 64 .算法主要耗时在排序上,而排序所耗的时间复杂度为O(2*nlog2n),因此程序的时间复杂度也就是 O(nlog2n)级别的(对于较小的系数,忽略不计).

#include<algorithm>
#include<climits>
#include<fstream>
#include<iostream>
using namespace std;
const int maxn = 50010;
const int inf = INT_MAX;
struct Tnode {
int x, y, id;
} a1[maxn], a2[maxn];
ifstream fin("reduce.in");
ofstream fout("reduce.out");
int n;
long long ans = inf;
bool used[maxn];
bool byX(Tnode, Tnode);
bool byY(Tnode, Tnode);
void dfs(int);
int main() {
fin >> n;//fout<<n<<endl;return 0;

for(int i = 0; i != n; ++i) {
fin >> a1[i].x >> a1[i].y;
a1[i].id = i;
a2[i] = a1[i];
}

sort(a1, a1 + n, byX);
sort(a2, a2 + n, byY);
dfs(0);
fout << ans << endl;
return 0;
}
bool byX(Tnode i, Tnode j) {
return i.x < j.x;
}
bool byY(Tnode i, Tnode j) {
return i.y < j.y;
}
void dfs(int k) {
if(k == 3) {
int maxx, maxy, minx, miny;
maxx = maxy = -inf;
minx = miny = inf;

for(int i = 0; i != n; ++i)
if(!used[a1[i].id]) {
maxx = max(maxx, a1[i].x);
maxy = max(maxy, a1[i].y);
minx = min(minx, a1[i].x);
miny = min(miny, a1[i].y);
}

ans = min(ans, (long long)(maxx - minx) * (maxy - miny));
return;
}

int i;

for(i = 0; i != n && used[a1[i].id]; ++i);

used[a1[i].id] = true;
dfs(k + 1);
used[a1[i].id] = false;

for(i = n - 1; i != -1 && used[a1[i].id]; --i);

used[a1[i].id] = true;
dfs(k + 1);
used[a1[i].id] = false;

for(i = 0; i != n && used[a2[i].id]; ++i);

used[a2[i].id] = true;
dfs(k + 1);
used[a2[i].id] = false;

for(i = n - 1; i != -1 && used[a2[i].id]; --i);

used[a2[i].id] = true;
dfs(k + 1);
used[a2[i].id] = false;
}

0 0