POj 2002 UVALive - 3047 C - Squares 【计算几何+二分求解】

20 篇文章 0 订阅
6 篇文章 0 订阅

C - Squares
Time Limit:3500MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu

Description

A square is a 4-sided polygon whose sides have equal length and adjacent sides form 90-degree angles. It is also a polygon such that rotating about its centre by 90 degrees gives the same polygon. It is not the only polygon with the latter property, however, as a regular octagon also has this property. 

So we all know what a square looks like, but can we find all possible squares that can be formed from a set of stars in a night sky? To make the problem easier, we will assume that the night sky is a 2-dimensional plane, and each star is specified by its x and y coordinates. 

Input

The input consists of a number of test cases. Each test case starts with the integer n (1 <= n <= 1000) indicating the number of points to follow. Each of the next n lines specify the x and y coordinates (two integers) of each point. You may assume that the points are distinct and the magnitudes of the coordinates are less than 20000. The input is terminated when n = 0.

Output

For each test case, print on a line the number of squares one can form from the given stars.

Sample Input

4
1 0
0 1
1 1
0 0
9
0 0
1 0
2 0
0 2
1 2
2 2
0 1
1 1
2 1
4
-2 5
3 7
0 0
5 2
0

Sample Output

1
6
1


思路:


要确定一个正方形,我们需要找出它的四个边-.-

时间复杂度C n 4----


其实,我们可以确定两个点的-.-


思考一下


我想到的是对角线上的两个点-.-


然后经过求中心点,通过这三点和全等三角形就可以求出另外的两个点------(画图理解呦)

最后二分判定这两个点存在不----完美-.-



代码;

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct node{
    double x,y;
}dian[1060];
bool cmp(node xx,node yy)
{
    if (xx.y!=yy.y)
        return xx.y<yy.y;
    return xx.x<yy.x;
}
int n;
bool pan(double x,double y)
{
    int l=0,m,r=n-1;
    int lp=-1;
    while (l<=r)
    {
        m=(l+r)/2;
        if (dian[m].y==y)
        {
            if (dian[m].x==x)
            return true;
            else if (dian[m].x>x)
                r=m-1;
            else
                l=m+1;
        }
        else if (dian[m].y>y)
        {
            r=m-1;
        }
        else
        {
            l=m+1;
        }
    }
    return false;
}
bool bo(int i,int j)
{
    double zx=(dian[i].x+dian[j].x)/2;
    double zy=(dian[i].y+dian[j].y)/2;
    double x1=(dian[i].y-zy+zx);
    double x2=(dian[j].y-zy+zx);
    double y1=zy-(dian[i].x-zx);
    double y2=zy-(dian[j].x-zx);
    if (!pan(x1,y1))
        return false;
    if (!pan(x2,y2))
        return false;
    return true;
}
void slove()
{
    for (int i=0;i<n;i++)
        scanf("%lf%lf",&dian[i].x,&dian[i].y);
    sort(dian,dian+n,cmp);
    int ans=0;
    for(int i=0;i<n-1;i++)
        for (int j=i+1;j<n;j++)
            if (bo(i,j))
            ans++;
    ans/=2;
    printf("%d\n",ans);
}
int main()
{
    while (scanf("%d",&n),n)
    slove();
    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值