POJ 1971 Parallelogram Counting

题目链接 :  http://poj.org/problem?id=1971

题意 : 给你n(n <= 1000)个点, 问你有多少个平行四边形。

思路 : 一开始我是枚举每一条有向边, 因为两条边相等且方向一样的话就可以够成一个平行四边形,数出所有的之后减去一些三点一线的, 然后除2(一个四边形有两对平行边)就可以获得正确答案了。O(n ^ 2 * log (n ^ 2))的复杂度, 但是可能常数有点大(我实现需要两次排序, 并且还要二分查找)吧还是我写挫了, 一直TLE,后来发现其实可以用另一个判断平行四边形的方法来做这一道题目 : 平行四边形的对角连线互相平分。 这样只要枚举中点,对于中点一次排序就可以完成了, 然后就变成简单题了。


#include 
   
   
    
    
#include 
    
    
     
     
#include 
     
     
      
      

using namespace std;
typedef __int64 lld;
const int maxn = 1005;
struct Point{
    int x, y;
    Point(){}
    Point(int a, int b) : x(a), y(b){}
    bool operator < (const Point & cmp)const {
        return x < cmp.x || (x == cmp.x && y < cmp.y);
    }
}p[maxn], ss[maxn * maxn];

bool operator == (const Point &a, const Point &b){
    return a.x == b.x && a.y == b.y;
}
int n;

int main(){
    int T;
    scanf("%d", &T);
    for (int cas = 1; cas <= T; cas++){
        scanf("%d", &n);
        for (int i = 1; i <= n; i++){
            scanf("%d%d", &p[i].x, &p[i].y);
        }
        int cnt = 0, num = 1;
        lld res = 0;
        for (int i = 1; i <= n; i++){
            for (int j = i + 1; j <= n; j++){
                ss[cnt++] = Point(p[i].x + p[j].x, p[i].y + p[j].y);
            }
        }
        sort(ss, ss + cnt);
        for (int i = 1; i < cnt; i++){
            if (ss[i] == ss[i-1]){
                res += num;
                num++;
            }else {
                num = 1;
            }
        }
        printf("%I64d\n", res);
    }
    return 0;
}

     
     
    
    
   
   

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值