计算几何 点对处理 #345 (Div. 2) C. Watchmen

题目:给你n(<=2*1e5)个点,求其中有多少个点对之间的连线向量平行坐标轴;

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <algorithm>
#include <set>
using namespace std;
typedef long long ll;
typedef unsigned long long Ull;
#define MM(a,b) memset(a,b,sizeof(a));
const double eps = 1e-10;
const int inf = 0x3f3f3f3f;
const double pi=acos(-1);
const int mod=100000000;
ll max(ll a,ll b)
{return a>b?a:b;};
int min(int a,int b)
{return a<b?a:b;};

struct node{
   int x,y;
}ne[200005];

bool cmpx(node a,node b)
{
    if(a.x==b.x) return a.y<b.y;
    else return a.x<b.x;
}

bool cmpy(node a,node b)
{
    if(a.y==b.y) return a.x<b.x;
    else return a.y<b.y;
}

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

int main()
{
    int n,m;
    while(~scanf("%d",&m))
    {
        for(int i=0;i<m;i++)  scanf("%d %d",&ne[i].x,&ne[i].y);

        ll ans=0;
        sort(ne,ne+m,cmpx);
        for(int i=0;i<m-1;i++)
             {
                 int cur=i;
                 while(ne[i+1].x==ne[cur].x&&(i+1)<m) i++;
                 ll k=i-cur+1;ans+=(k-1)*k/2;//注意k要ll型,不然k*k的时候会爆int
             }
        
sort(ne,ne+m,cmpy); for(int i=0;i<m-1;i++) { int cur=i; while(ne[i+1].y==ne[cur].y&&(i+1)<m) i++; ll k=i-cur+1;ans+=(k-1)*k/2; }
for(int i=0;i<m;i++) { int cur=i; while(ne[i]==ne[i+1]&&(i+1)<m) i++; ll k=i-cur+1;ans-=k*(k-1)/2; }//去重操作
printf("%lld\n",ans); } return 0; }

  分析:刚开始只考虑到只有一个点的重合,用了unique果断错,,,后来发现只要x和y两个方向

枚举。然后再去重减去相同的点之间的就可以了

posted @ 2016-04-11 16:40  快点说我帅  阅读(151)  评论(0编辑  收藏  举报