您的位置:首页 > 其它

Codeforces Round #345 (Div. 2) C. Watchmen

2016-03-08 19:54 309 查看
题目链接:http://codeforces.com/contest/651/problem/C

题目大意:给出n个坐标,求存在(xi,yi),(xj, yj) 使|xi-xj|+|yi-yj| = sqrt((xi-xj)*(xi-xj)+(yi-yj)*(yi-yj))的组数

方法:等式两边平方,化简得只要两个点存在同一列或同一行就可以符合上述等式

#include <bits/stdc++.h>

using namespace std;
const int maxn = 200010;
struct node
{
long long x, y;
bool operator <(const node &a)const
{
return x < a.x || (x == a.x && y < a.y);
}
} Point[maxn];
map<node, int> M;
bool cmp(node a, node b)
{
if(a.y == b.y)
return a.x < b.x;
return a.y < b.y;
}
int main()
{
int n;
scanf("%d",&n);
for(int i=0; i<n; i++)
{
cin>>Point[i].x>>Point[i].y;
++M[Point[i]];
}
Point
.x = Point
.y = 0x3f3f3f3f;
sort(Point, Point+n);
long long  ans = 0;
long long tmp = 1;
for(int i=1; i<=n; i++)
{
if(Point[i].x == Point[i-1].x)
++tmp;
else
{
ans += tmp*(tmp-1)/2;
tmp = 1;
}
}
sort(Point, Point+n, cmp);
tmp = 1;
for(int i=1; i<=n; i++)
{
if(Point[i].y == Point[i-1].y)
++tmp;
else
{
ans += tmp*(tmp-1)/2;
tmp = 1;
}
}
for(int i=1; i<=n; i++)
{
long long t = M[Point[i-1]];
if(t > 1 && (Point[i-1].x != Point[i].x || Point[i-1].y != Point[i].y))
ans -= t*(t-1)/2;
}
cout<<ans<<endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: