1. 程式人生 > >hiho219 Smallest Rectangle

hiho219 Smallest Rectangle

目錄

題意分析:

ac程式碼

時間限制:10000ms

單點時限:1000ms

記憶體限制:256MB

描述

You are given N 2D points P1, P2, ... PN. If there is a rectangle satisfying that its 4 vertices are in the given point set and its 4 sides are parallel to the axis we say the rectange exists.

Find the smallest exsisting rectange and output its area.

輸入

The first line contains an integer N. (1 <= N <= 1000)

The following N lines each contain 2 integers Xi and Yi denoting a point (Xi, Yi). (0 <= Xi, Yi <= 1000000)

輸出

Output the smallest area. If no rectangle exsists output -1.

樣例輸入

9  
0 0  
0 1   
0 4  
1 0  
1 1  
1 4  
4 0  
4 1  
4 4

樣例輸出

1

題意分析:

1.題是什麼?

    給你n個座標點,要你選其中四個組成一個平行x軸y軸的矩形,要求輸出最小的矩形面積.

2.解題思路

    n大小為1000,選4個,對資料敏感的我瞬間想到折半列舉,然後這道題被我以折半列舉n*n*logn的複雜度搞定了,肯定還可以優化,我的解法會在後續進行優化,現在的ac是沒問題的.

    看了看討論...對的,開始的折半列舉毫無問題,不過後面兩個是否存在的驗證那裡用雜湊表可以以O(1)完成驗證,不必我這麼麻煩,待新增解法2.

ac程式碼

1.折半列舉+二分查值

#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <math.h>
using namespace std;

typedef pair<int,int> pa;
typedef long long ll; 
const ll inf=1000000000001;
const int maxn=1001;
const int maxm=10000001;
pa a[maxn];
ll myfabs(ll a){ return a<0?-a:a; }
bool comp(const pa &a,const pa &b){
	if(a.first<b.first) return true;
	else if(a.first>b.first) return false;
	return a.second<b.second;
}

bool search(pa *a,int l,int r,pa point1,pa point2){
	if(*lower_bound(a+l,a+r,point1,comp)==point1&&*lower_bound(a+l,a+r,point2,comp)==point2) return true;
	return false;
}

void solve(){
	int n;
	scanf("%d",&n);
	for(int i=0;i<n;i++) scanf("%d%d",&a[i].first,&a[i].second);
	sort(a,a+n,comp);
	ll ans=inf;
	for(int i=0;i<n-1;i++){
		for(int j=i+1;j<n;j++){
			ll x1=a[i].first,y1=a[i].second,x2=a[j].first,y2=a[j].second;
			ll area=myfabs(x2-x1)*myfabs(y2-y1);
			if(area&&area<ans&&search(a,0,n,make_pair(x1,y2),make_pair(x2,y1))) ans=area; 
		}
	}
	if(ans==inf) printf("-1\n");
	else printf("%lld\n",ans);
}

int main(){
	solve();
	return 0;
}

2.折半列舉+雜湊表(待新增)