zoukankan      html  css  js  c++  java
  • POJ 2002 Squares 几何, 水题 难度: 0

    题目

    http://poj.org/problem?id=2002


    题意

    已知平面内有1000个点,所有点的坐标量级小于20000,求这些点能组成多少个不同的正方形。 

    思路

    如图,将坐标按照升序排列后,首先枚举p1,p2, 并判断p2是否在p1正下方或者左上角(因为每个正方形只有一条最右边或者是右下的边),按照下图计算p3,p4,判断p3,p4是否存在即可。

    感想

    排序时要注意和左上角这个信息相符,刚写完时用的是左下角,与升序排序不符合,会遗失部分正方形。

    代码

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <iostream>
    #include <sstream>
    #include <map>
    #include <set>
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> P;
    const int maxn = 1000;
    const int base = 2e4 + 4;
    int n;
    P a[maxn];
    set<int> st;
    
    bool upperleft(P p1, P p2){
        return p1.first <= p2.first && p1.second < p2.second;
    }
    
    int adhere(P p){
        return p.first * base + p.second;
    }
    
    P othercorners(P p1, P p2){
        int deltax = p2.first - p1.first;
        int deltay = p2.second - p1.second;
        P p3(deltay, -deltax);
        P p4(deltax + deltay, deltay - deltax);
        p3.first += p1.first; p4.first += p1.first;
        p3.second += p1.second; p4.second += p1.second;
        //printf("P1 (%d, %d), P2 (%d, %d), P3 (%d, %d), P4 (%d, %d)
    ",
        //    p1.first, p1.second, p2.first, p2.second, p3.first, p3.second, p4.first, p4.second);
        return P(adhere(p3), adhere(p4));
    }
    
    int solve(){
        int cnt = 0;
        sort(a, a + n);
        st.clear();
        for(int i = 0;i < n;i++){
            st.insert(adhere(a[i]));
        }
        for(int i = 0;i < n;i++){
            for(int j = i + 1;j < n;j++){
                if(upperleft(a[i], a[j])){
                    //printf("(%d, %d) is on the upper left corner of (%d, %d)
    ", a[j].first, a[j].second, a[i].first, a[i].second);
                    P corners = othercorners(a[i], a[j]);
                    if(st.find(corners.first) != st.end() && st.find(corners.second) != st.end()){
                        cnt++;
                    }
                }
            }
        }
        return cnt;
    }
    
    int main(){
    #ifdef LOCAL
        freopen("input.txt","r",stdin);
    #endif // LOCAL
        while(scanf("%d", &n) == 1 && n){
            for(int i = 0;i < n;i++){
                scanf("%d%d", &a[i].first, &a[i].second);
            }
            int ans = solve();
            printf("%d
    ",ans);
        }
        return 0;
    }
    

     

  • 相关阅读:
    hdu1078 记忆化搜索
    AC之路开始了~
    Balanced Lineup poj3264 线段树
    Billboard 题解 hdu2795
    Count Color poj2777 线段树
    D-query SPOJ 树状数组+离线
    Poj 3468 A Simple Problem with Integers 线段树
    最小生成树两大算法总结+模板
    最短路三大算法及其优化算法大总结+模板
    POJ-1502 MPI Maelstrom 迪杰斯特拉+题解
  • 原文地址:https://www.cnblogs.com/xuesu/p/6386591.html
Copyright © 2011-2022 走看看