POJ 2002

/*
	此题的关键在于一个公式:
		已知正方形的两个点坐标,就可以求另外两种两个点的正方形;
		已知两点:(x1,y1)  (x2,y2);
		求一种正方形的两点: x3 = x1 + (y1-y2);
							 y3 = y1 - (x1-x2);
							 x4 = x2 + (y1-y2);
							 y4 = y2 - (x1-x2);
		求另一种正方形的两点:
							 x3 = x1 - (y1-y2);
							 y3 = y1 + (x1-x2);
							 x4 = x2 - (y1-y2);
							 y4 = y2 + (x1-x2);
		枚举二个点, 求出另外二个点,看有没有这个点,有就结果加一;因为4边,每一个边都会枚举;
		结果要除以4;					 
		
							 
		然后对点进行处理,因为不可能两点在同一个点,X 坐标乘以100000 加上Y坐标的值,每一个点,
		这样处理,并且排序, 再枚举,再进行二分查找,结果除以4,就可以了; 
*/
#include <iostream>
#include <fstream>
#include <cstring>
#include <algorithm>
#include <set>
using namespace std;
typedef struct point{
	int x,y;	
} point;
int x[1001], y[1001];
int N;
const int VAL = 100000;
int Scount;
typedef long long ll;
ll art[1001];
int Sfind(ll *array, int low, int high, ll key)  
{  
    if ( low > high )  
        return -1;  
    int mid = ( low + high )/2;  
      
    if ( array[mid] == key )  
        return mid;  
    else if ( array[mid] < key )  
        return Sfind(array, mid+1, high, key);  
    else  
        return Sfind(array, low, mid-1, key);  
} 
bool com(int a,int b){
	return a>b;
}
int main(){		
	while(1){
		Scount = 0;		
		scanf("%d", &N);
		if(N==0) return 0;
		for(int i=1; i<=N; ++i){
			scanf("%d%d", &x[i], &y[i]);			
			ll temp = ((ll)x[i]*VAL + y[i]);
			art[i] = temp;
			
		}
		sort(art+1, art+N+1,com);
		for(int i=1; i<=N; ++i){
			printf("	%4d\n", art[i]);
		}
		point p1, p2, p3, p4, p5, p6;
		for(int i=1; i<N; ++i){
			for(int j=i+1; j<=N; ++j){
				p1.x = x[i]; 
				p1.y = y[i];
				
				p2.x = x[j];
				p2.y = y[j];
				
				p3.x = p1.x + (p1.y - p2.y);
				p3.y = p1.y - (p1.x - p2.x);				
				p4.x = p2.x + (p1.y - p2.y);
				p4.y = p2.y - (p1.x - p2.x);
				ll a = p3.x * VAL + p3.y;
				ll b = p4.x * VAL + p4.y;
				if(Sfind(art, 1, N+1, a) != -1 && Sfind(art, 1, N+1, b) != -1){
					++Scount;
				}			
				p5.x = p1.x - (p1.y - p2.y);
				p5.y = p1.y + (p1.x - p2.x);
				
				p6.x = p2.x - (p1.y - p2.y);
				p6.y = p2.y + (p1.x - p2.x);				
				a = p5.x * VAL + p5.y;
				b = p6.x * VAL + p6.y;
				if(Sfind(art, 1, N+1, a) != -1 && Sfind(art, 1, N+1, b) != -1){
					++Scount;
				}
			
				
			}
		}
		printf("%d\n", Scount>>2);
		
	}
	
	return 0;
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值