在地图上散落着 n 个车轮,小 J 想用它们造一辆车。要求如下:
-
一辆车需要四个车轮,且四个车轮构成一个正方形
-
车轮不能移动你需要计算有多少种造车的方案(两个方案不同当且仅当所用车轮不全相同,坐标相同的两个车轮视为不同车轮)。
30%的数据保证 n ≤ 30
100%的数据保证 1 ≤ n ≤ 1000; |x|, |y| < 20000
枚举两个点,计算出另外两个点,用二分求出另外两个点的方案数,用乘法原理乘起来,最终要除以2
Code:
#include <bits/stdc++.h>
#define maxn 1010
#define LL long long
using namespace std;
struct node{
int x, y;
}a[maxn];
int n;
LL ans;
inline int read(){
int s = 0, w = 1;
char c = getchar();
for (; !isdigit(c); c = getchar()) if (c == '-') w = -1;
for (; isdigit(c); c = getchar()) s = (s << 1) + (s << 3) + (c ^ 48);
return s * w;
}
bool cmp(node x, node y){ return x.x == y.x ? x.y < y.y : x.x < y.x; }
LL check(int x, int y){
int l = 1, r = n, ansl = 0, ansr = 0;
while (l <= r){
int mid = (l + r) >> 1;
if (a[mid].x < x) l = mid + 1;
else if (a[mid].x > x) r = mid - 1;
else if (a[mid].y > y) r = mid - 1;
else if (a[mid].y < y) l = mid + 1;
else ansl = mid, r = mid - 1;
}
l = 1, r = n;
while (l <= r){
int mid = (l + r) >> 1;
if (a[mid].x < x) l = mid + 1;
else if (a[mid].x > x) r = mid - 1;
else if (a[mid].y > y) r = mid - 1;
else if (a[mid].y < y) l = mid + 1;
else ansr = mid, l = mid + 1;
}
if (!ansl || !ansr) return 0; else return ansr - ansl + 1;
}
int main(){
freopen("car.in", "r", stdin);
freopen("car.out", "w", stdout);
n = read();
for (int i = 1; i <= n; ++i) a[i].x = read(), a[i].y = read();
sort(a + 1, a + 1 + n, cmp);
for (int i = 1; i <= n; ++i)
for (int j = i + 1; j <= n; ++j){
node x = a[i], y = a[j];
if (a[i].x == a[j].x && a[i].y == a[j].y) continue;
node tx = (node){x.x + y.y - x.y, x.x + x.y - y.x};
node ty = (node){tx.x + y.x - x.x, tx.y + y.y - x.y};
LL ansx = check(tx.x, tx.y), ansy = check(ty.x, ty.y);
if (ansx && ansy) ans += ansx * ansy;
// printf("(%d,%d),(%d,%d),(%d,%d),(%d,%d)\n", x.x, x.y, y.x, y.y, tx.x, tx.y, ty.x, ty.y);
}
printf("%lld\n", ans >> 1);
}