CodeForces 660D - Number of Parallelograms ( 模拟 )

题意

给出n个点, 输入保证没有重复点, 且不会有三点共线, 求这些点能够构成的平行四边形的个数

思路

最后B题还有半个来小时没考虑全瞎瘠薄写没过
赛后补B题发现人家全用向量做的
我居然用的长度和斜率跑了2000+ms真的是太傻逼了

大概就是用n*n跑一遍点, 枚举出所有可能组成的边(以向量形式存储), 若有两个向量完全相同则他们能构成一个平行四边形.
自己写的时候傻逼了, 用的线段长度+斜率模拟的

AC代码

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <map>
#define mst(a) memset(a, 0, sizeof a)
using namespace std;
const int maxn = 2000+5;
const int INF = 0x3f3f3f3f;

struct point{
    int x, y;
}p[maxn];

double getk(int x, int y){
    if( x == 0 ) return 1;
    return (double)y/(double)x;
}

int getall(int n){
    int sum = 0;
    for( int i = 1; i < n; i++ )
        sum += i;
    //printf("%d %d\n",n , sum);
    return sum;
}

struct lines{
    double len;
    double kk;
    bool operator <( const struct lines& l ) const{
        if( kk == l.kk )
            return len < l.len;
        return kk < l.kk;
    }
};

map<lines, int> mp;

double getlen( int x1, int y1, int x2, int y2 ){
    double xx = abs(x1-x2); xx = xx * xx;
    double yy = abs(y1-y2); yy = yy * yy;
    return sqrt(xx+yy);
}

int main()
{
    int n;
    scanf("%d",&n);
    for( int i = 0; i < n; i++ )
        scanf("%d%d", &p[i].x, &p[i].y);
    int m = 0;
    for( int i = 0; i < n; i++ ){
        for( int j = i+1; j < n; j++ ){
            int xx = p[i].x-p[j].x, yy = p[i].y-p[j].y;
            double kkk = getk(xx, yy);
            double l = getlen(p[i].x, p[i].y, p[j].x, p[j].y);
            lines q;
            q.kk = kkk, q.len = l;
            mp[q]++;
        }
    }
    int ans = 0;
    map<lines, int>::iterator it = mp.begin();
    for( ; it != mp.end(); it++ )
        ans += getall(it->second);
    printf("%d\n",ans/2);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/jinxisui/article/details/80099441