/*
此题的关键在于一个公式:
已知正方形的两个点坐标,就可以求另外两种两个点的正方形;
已知两点:(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;
}
POJ 2002
最新推荐文章于 2021-10-05 21:17:08 发布