Time Limit:1000ms
Memory Limit:65535K
Description
Input
输入第一行包含一个整数 N,
表示二维空间中点的数目。
接下来包含 N 行,第行包含两个整数,
表示一个点对的 X 坐标和 Y 坐标。
Output
输出一行,包含一个整数,
表示距离与p 无关的点对数目。
Sample Input
3
0 1
1 0
1 1
Sample Output
2
Hint
Solution
题目要求找出几对点之间的明式距离与
p
p
p 无关。
观察以下明式距离公式:
(
∣
x
1
−
x
2
∣
p
+
∣
y
1
−
y
2
∣
p
)
1
p
(\left | x_1 - x_2 \right |^p + \left | y_1 - y_2 \right |^p)^\frac{1}{p}
(∣x1−x2∣p+∣y1−y2∣p)p1
可以发现使
p
p
p 无关有两种情况:
∣
x
1
−
x
2
∣
=
0
|x_1-x_2|=0
∣x1−x2∣=0 或
∣
y
1
−
y
2
∣
=
0
|y_1-y_2|=0
∣y1−y2∣=0
所以可将所有点分别对横坐标和纵坐标进行排序,找出具有相同横(纵)坐标 点的数量
n
n
n
最终答案即为
∑
C
n
2
=
∑
n
(
n
−
1
)
2
\sum C_n^2=\sum\frac{n(n-1)}{2}
∑Cn2=∑2n(n−1)
注:代码中 auto 部分是测试 C++11 用的,比较函数正常写在外面就行。
Code
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
pair<int,int> p[100000];
int main()
{
int n;
cin>>n;
for(int i=0;i<n;i++) cin>>p[i].first>>p[i].second;
auto cmp1=[](pair<int,int> p1,pair<int,int> p2) {
return p1.first<p2.first;
};
auto cmp2=[](pair<int,int> p1,pair<int,int> p2) {
return p1.second<p2.second;
};
sort(p,p+n,cmp1);
ll ans=0,cnt=0;
int last=1e9+1;
for(int i=0;i<n;i++)
{
if(p[i].first==last) cnt++;
else
{
ans+=cnt*(cnt-1)/2;
cnt=1;
last=p[i].first;
}
}
ans+=cnt*(cnt-1)/2;
sort(p,p+n,cmp2);
cnt=0;
last=1e9+1;
for(int i=0;i<n;i++)
{
if(p[i].second==last) cnt++;
else
{
ans+=cnt*(cnt-1)/2;
cnt=1;
last=p[i].second;
}
}
ans+=cnt*(cnt-1)/2;
cout<<ans;
return 0;
}