​https://biancheng.love/contest-ng/index.html#/123/problems​

做题要在纸上弄弄,才会有发现。

发现到答案只是-1和4,因为坐标都是整数。

然后就是找是否存在正方形了。

判断如下:

1、枚举任意两个点,作为正方形的一条边,那么,整个正方形就确定了,有两个方向。

因为,

设坐标为(x1, y1) & (x2, y2),所求的坐标是和x1相连,那么有方程如下。

1、垂直,向量积是0

2、边长相等,然后距离公式化简。

即可解出剩下的两个点。

然后要注意两个点要在正方形的同一侧,不然变了平行四边形了。

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <assert.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL;


#include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
struct node {
int x, y;
bool operator < (const struct node & rhs) const {
if (x != rhs.x) {
return x < rhs.x;
} else return y < rhs.y;
}
bool operator != (const struct node & rhs) const {
return !(x == rhs.x && y == rhs.y);
}
} arr[2222];
int n;
bool check(struct node t1, struct node t2, int one, int two) {
int pos = lower_bound(arr + 1, arr + 1 + n, t1) - arr;
if (pos == one || pos == two || arr[pos] != t1) return false;
pos = lower_bound(arr + 1, arr + 1 + n, t2) - arr;
if (pos == one || pos == two || arr[pos] != t2) return false;
return true;
}
void work() {
scanf("%d", &n);
for (int i = 1; i <= n; ++i) {
scanf("%d%d", &arr[i].x, &arr[i].y);
}
sort(arr + 1, arr + 1 + n);
// for (int i = 1; i <= n; ++i) {
// cout << arr[i].x << " " << arr[i].y << endl;
// }
// cout << endl;
int ans = 0;
for (int i = 1; i <= n; ++i) {
for (int j = i + 1; j <= n; ++j) {
struct node t[8];
t[0].x = arr[i].y - arr[j].y + arr[i].x;
t[0].y = arr[j].x - arr[i].x + arr[i].y;
t[1].x = arr[j].y - arr[i].y + arr[j].x;
t[1].y = arr[i].x - arr[j].x + arr[j].y;
// cout << i << " " << j << endl;
// cout << "*********" << endl;
// for (int k = 0; k <= 1; ++k) {
// cout << t[k].x << " " << t[k].y << endl;
// }
// cout << "**********" << endl;
if (t[0].x < arr[i].x || t[0].x == arr[i].x && t[0].y < arr[i].y) {
t[0].x = arr[j].y - arr[i].y + arr[i].x;
t[0].y = arr[i].x - arr[j].x + arr[i].y;
}
if (t[1].x < arr[j].x || t[1].x == arr[j].x && t[1].y < arr[j].y) {
t[1].x = arr[i].y - arr[j].y + arr[j].x;
t[1].y = arr[j].x - arr[i].x + arr[j].y;
}
// for (int k = 0; k <= 1; ++k) {
// cout << t[k].x << " " << t[k].y << endl;
// }
if (check(t[0], t[1], i, j)) {
printf("4\n");
return;
}

t[0].x = arr[i].y - arr[j].y + arr[i].x;
t[0].y = arr[j].x - arr[i].x + arr[i].y;
t[1].x = arr[j].y - arr[i].y + arr[j].x;
t[1].y = arr[i].x - arr[j].x + arr[j].y;

if (t[0].x > arr[i].x || t[0].x == arr[i].x && t[0].y > arr[i].y) {
t[0].x = arr[j].y - arr[i].y + arr[i].x;
t[0].y = arr[i].x - arr[j].x + arr[i].y;
}
if (t[1].x > arr[j].x || t[1].x == arr[j].x && t[1].y > arr[j].y) {
t[1].x = arr[i].y - arr[j].y + arr[j].x;
t[1].y = arr[j].x - arr[i].x + arr[j].y;
}
// for (int k = 0; k <= 1; ++k) {
// cout << t[k].x << " " << t[k].y << endl;
// }
// cout << endl;
if (check(t[0], t[1], i, j)) {
printf("4\n");
return;
}
}
}
assert(ans >= 0);
printf("%d\n", -1);
return;
}

int main() {
#ifdef local
freopen("data.txt", "r", stdin);
// freopen("data.txt", "w", stdout);
#endif
int t;
scanf("%d", &t);
while (t--) work();
return 0;
}

View Code