• POJ2002 Squares Hash表+正方形顶点计算


    该题的思路就是枚举所有的点,当然这么枚举要做到不能够重复和遗漏,所以我们约定值枚举对角线的两个点,最后将最终的结果除以2来计算。

    由于每次通过枚举对角线的两个点,我们还要计算出另外两个顶点的坐标,所以这里用了一个很牛的公式,直接作加减法就能够出来了,判定下是否为整数。理论上我们马上要到点集中去寻找有没有这两个点,显然这种做法的效率很低,所以这里要用hash表,将顶点的信息的查询优化到接近O(1)。

    这里把正方形计算另外两个顶点的公式记录如下(已知x1, x2, y1, y2, 求x3, y3, x4, y4):

      x1 + x2 = x3 + x4;

      y2 -  y1 = x4 -  x3;

      y1 + y2 = y3 + y4;

      x2 -  x1 = y3 -  y4;

    代码如下:

    #include <cstdlib>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #define MAXN 30001
    #define MOD 30001
    using namespace std;
    
    int N, head[MAXN], idx;
    
    struct Point
    {
        int x, y;
    }p[10005];
    
    struct Node
    {
        int x, y, next;
    }e[10005];
    
    void Hash(int x, int y)
    {
        int key = abs(x * y) % MOD;
        ++idx;
        e[idx].x = x, e[idx].y = y;
        e[idx].next = head[key];
        head[key] = idx;
    }
    
    bool find(int x, int y)
    {
        int key = abs(x * y) % MOD, ans = 0;
        for (int i = head[key]; i != -1; i = e[i].next) {
            if (e[i].x == x && e[i].y == y) {
                return true;
            }
        } 
        return false;
    }
    
    int main()
    {
        int ans;
        while (scanf("%d", &N), N) {
            memset(head, 0xff, sizeof (head));
            idx = -1;
            ans = 0;
            for (int i = 0; i < N; ++i) {
                scanf("%d %d", &p[i].x, &p[i].y);    
                Hash(p[i].x, p[i].y);
            }
            double x1, y1, x2, y2;
            for (int i = 0; i < N; ++i) {
                for (int j = i+1; j < N; ++j) {
                    x1 = ( (p[i].x + p[j].x) + (p[j].y - p[i].y) ) / 2.;
                    x2 = ( (p[i].x + p[j].x) - (p[j].y - p[i].y) ) / 2.;
                    y1 = ( (p[j].y + p[i].y) - (p[j].x - p[i].x) ) / 2.;
                    y2 = ( (p[j].y + p[i].y) + (p[j].x - p[i].x) ) / 2.;
                    if (x1 == floor(x1) && x2 == floor(x2) && y1 == floor(y1) && y2 == floor(y2)) {
                        if (find(x1, y1) && find(x2, y2)) {
                            ++ans;
                        } 
                    }
                }
            }
            printf("%d\n", ans >> 1);
        }
        return 0;
    }
  • 相关阅读:
    如何解决MathPage.wll或MathType.dll文件找不到问题
    2-构建模型
    R语言 ur.df函数(2)
    平稳过程趋势项变点的 CUSUV 检验 秦瑞兵,郭娟
    时间序列的弱相依与强相依
    Cent OS|使用httpd发布网页
    C++练习 | 基于栈的中缀算术表达式求值(double类型
    C++练习 | 不使用头插法逆转单链表
    C++练习 | 单链表的创建与输出(结构体格式)
    C++练习 | 最长公共字符串(DP)
  • 原文地址:https://www.cnblogs.com/Lyush/p/2587759.html
Copyright © 2020-2023  润新知