您的位置:首页 > 其它

zoj 2347 || poj 2002 Squares

2011-07-09 10:25 417 查看
给你1000个点,判断这些点最多能组成多少个正方形。
以前没仔细想就放过去了(题意记下来了。。。)。回顾不会做的题的时候看到了,想了下,想了个N^2LOGN的算法。准确的是n^2/2*logn,可以承受,就写了下。
就是枚举对角线,然后判断另一条对角线的俩点存在不。查找用二分查找。手写的二分查找有问题- - 。。。原来我的二分一直都有问题啊 = = 。。今天才发现。改了下 - - 悲剧。
zoj上基本是险过,交了多次才擦边过一次。。。其他都是TLE,poj的话还好,都过了。
后来看poj的discuss,发现我枚举对角线有点多余,枚举边长就可以了,少一次计算等于,呵呵,改成枚举边长了,旋转的时候要旋转90度和270度了,zoj不再TLE了 = =。。
貌似查找还可以用hash,可惜我不会哎。用c++的binary_search一直不知道那个比较函数怎么写,看了人家的,原来比较函数就是和排序的一样啊,郁闷。改了改,结果zoj时间提升了,poj过不去了,一直TLE,神呐。。。

贴的是我手写的二分。。。
#include <queue>
#include <stack>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <limits.h>
#include <string.h>
#include <string>
#include <algorithm>

using namespace std;

const int MAX = 1010;
struct point { double x,y;};
point p[MAX];
const double eps = 1e-6;
bool dy(double x,double y)	{	return x > y + eps;}	// x > y 
bool xy(double x,double y)	{	return x < y - eps;}	// x < y 
bool dyd(double x,double y)	{ 	return x > y - eps;}	// x >= y 
bool xyd(double x,double y)	{	return x < y + eps;} 	// x <= y 
bool dd(double x,double y) 	{	return fabs( x - y ) < eps;}  // x == y
bool bsearch(point a,int n)
{
	int begin = 0,end = n-1;
	while( begin <= end )
	{
		int mid = ( begin + end )/2;
		if( dd(a.x,p[mid].x) && dd(a.y,p[mid].y) )	return true;
		if( dy(a.x,p[mid].x) || dd(a.x,p[mid].x) && dy(a.y,p[mid].y) )
			begin = mid + 1;
		else
			end = mid - 1;
	}
	return false;
}
point Whirl(double cosl, double sinl, point a, point b)
{    
       b.x -= a.x; b.y -= a.y;
       point c;
       c.x = b.x * cosl - b.y * sinl + a.x;
       c.y = b.x * sinl + b.y * cosl + a.y;
       return c;
}
bool check(point a,point b,int n)
{
	point t = Whirl(0.0,1.0,a,b);
	if( !bsearch(t,n) ) return false;
	t = Whirl(0.0,-1.0,b,a);
	if( !bsearch(t,n) ) return false;
	return true;
}
int solve(point p[],int n)
{
	int sum = 0;
	for(int i=0; i<n; i++)
		for(int k=i+1; k<n; k++)
			if( i != k && check(p[i],p[k],n) )
				sum++;
	return sum;
}
bool cmp(point a,point b)
{
	if( dd(a.x,b.x) )
		return xy(a.y,b.y);
	return xy(a.x,b.x);
}
int main()
{
	int ncases,n;
	
	scanf("%d",&ncases);
	
	while( ncases-- )
	{
		while( scanf("%d",&n) && n )
		{
			for(int i=0; i<n; i++)
				scanf("%lf%lf",&p[i].x,&p[i].y);
			
			sort(p,p+n,cmp);
			
			int ans = solve(p,n);
			printf("%d\n",ans/2);
		}
		if( ncases )
			printf("\n");
	}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: