In the first sample, the distance between watchman 1 and watchman 2 is equal to |1 - 7| + |1 - 5| = 10 for Doctor Manhattan and for Daniel. For pairs (1, 1), (1, 5) and (7, 5), (1, 5) Doctor Manhattan and Daniel will calculate the same distances.
代码:
#include<stdio.h>#include<iostream>#include<algorithm>using namespace std;struct st{long long x;long long y;}a[200001];bool cmp(st q,st w){return q.x<w.x; } bool cmo(st q,st w) { return q.y<w.y; } bool cmi(st q,st w) { if(q.x==w.x) return q.y<w.y; return q.x<w.x; }int main(){ long long n; while(scanf("%lld",&n)!=EOF) { long long i,j,sum=1,ans=0; for(i=0;i<n;i++) { scanf("%lld %lld",&a[i].x,&a[i].y); } sort(a,a+n,cmp); for(i=1;i<n;i++) { if(a[i].x==a[i-1].x) sum++; else { ans=ans+sum*(sum-1)/2; sum=1; } } ans=ans+sum*(sum-1)/2; sum=1; sort(a,a+n,cmo); for(i=1;i<n;i++) { if(a[i].y==a[i-1].y) { sum++; } else { ans=ans+sum*(sum-1)/2; sum=1; } } ans=ans+sum*(sum-1)/2; sum=1; sort(a,a+n,cmi); for(i=1;i<n;i++) { if(a[i].y==a[i-1].y&&a[i].x==a[i-1].x) { sum++; } else { ans-=sum*(sum-1)/2; sum=1; } } ans-=sum*(sum-1)/2; printf("%lld\n",ans); }return 0;}
题意:给你一些点,让你判断分别用两种公式计算两点之间距离结果一样的有多少个。
思路:直接用题意所给的公式肯定会超时的啦!(然而傻傻的我开始时还是直接用了)!将两个公式列出来会发现当x1=x2,或者y1=y2时计算结果就会一样。如果这时你就傻傻得以为直接一个冒泡判断就ac的话还是太年轻,会超时的。(我还是犯这个错了!)所以要想如何简化判断过程。这世界就要用到快排了,先对x坐标快排判断有多少个点x坐标一样,再用公式x*(x-1)/2得到x坐标一样得点相同有多少个。同理y也是这样。不过这样做会有重复的,那就是x和y都一样的点会多计算。这时在快排一次
bool cmi(st q,st w) { if(q.x==w.x) return q.y<w.y; return q.x<w.x; }
判断xy都一样的再减去就得到最后结果了。