F 点与多边形 数学 + 观察

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
");
                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
");
                return;
            }
        }
    }
    assert(ans >= 0);
    printf("%d
", -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
原文地址:https://www.cnblogs.com/liuweimingcprogram/p/6161116.html