G. 平行线

单点时限: 2.0 sec

内存限制: 512 MB

“大猩猩为什么不喜欢平行线?”“因为平行线没有相交”
哈哈哈哈哈哈哈哈哈


为了管理动物园不听话的大猩猩们,动物管理员Boctorio 决定去远方的ACM之城找一些平行线,当他逛到一个神奇的店铺时,他发现了一副黑色的图,上面依稀可见一些白色的点。Boctorio 询问店铺老板这幅画是什么,老板说:“天机不可泄露”。等Boctorio仔细端详了一会这幅画后,他惊讶的发现其中所蕴含的奥秘。向店铺老板道谢后,他拿着刚买的这幅画,就连忙赶回动物园。

输入格式

输入一个数 n(1n1000),表示点的个数。
接下来n行,每行两个整数 xi,yi(1xi,yi109),表示第i个点。
数据保证没有重复的点

输出格式

输出用这些点所能表示出来的平行线段的对数。(两条不同的线段重合也算为平行)

样例

input
6
0 0
1 0
1 1
3 1
3 3
5 4
output
10
#include<iostream>
#include<map>
#include<vector>
#include<algorithm>
using namespace std;
typedef long long ll;
pair<int ,int>p;
vector<pair<int,int> >ve;
map<pair<int ,int >,int>mp;//保存斜率与斜率出现的次数
map<ll,int >mp1;
map<pair<int ,int >,int>::iterator it;
int main(){    
    int n;
    int sum=0;
    cin>>n;
    for(int i=0;i<n;i++){
        cin>>p.first>>p.second;
        ve.push_back(p);//用vector保存给的数据 
    }
    int x1,a,b,x2;
    for(int i=0;i<n;i++){//第i个点 
        for(int j=i+1;j<n;j++){//第j个点
            a=ve[i].second-ve[j].second;
            b=ve[i].first-ve[j].first;
            x1=__gcd(a,b);
            a=a/x1;
            b=b/x1;
            p.first=b;
            p.second=a;
            mp[p]++;
            p.first=-b;
            p.second=-a;
            mp[p]++;//p要存两次。对于(1,3)(-1,-3)也是平行的,最后在除以2就好了 
        }
    }
    for(it=mp.begin();it!=mp.end();it++){
        sum+=it->second*(it->second-1)/2;//就是n个相等的斜率会构成n*(n-1)条平行线 
    }
    cout<<sum/2<<endl;//前边存了两次,,这里得除以二
    return 0;
}


原文地址:https://www.cnblogs.com/Accepting/p/11285554.html