题目描述
平面上给定N个两两不同的整点,统计以给定的点为顶点,且直角边平行于坐标轴的直角三角形数。
输入输出格式
输入格式:输入文件right.in第一行为一个整数N。
以下N行,每行给出一个点的坐标。
输出格式:输出文件名为right.out。输出一个整数表示统计结果。
输入输出样例
输入样例#1:
4
0 0
0 1
1 0
1 1
输出样例#1:
4
说明
30%的数据满足 N ≤ 100;
50%的数据满足 N ≤ 1000;
100%的数据满足0 < N ≤100000,所有坐标不超过32位整数范围。
分析
纯模拟题 真的很简单 但是我只得了90分 有一个点WA了 现在还不知道为什么……
说一下思路:
对于每一个点 一个与它横坐标相同的点与一个与它纵坐标相同的点能与它形成一个满足题意的三角形
所以对于这一个点来说 我们可以将与它横坐标相同的点的个数与纵坐标相同的点的个数相乘,即使这个点构成的三角形个数
将每个点的这样的个数相加 最后的和即是我们要求得的答案
然而每个点每个点暴力去找与它横坐标或纵坐标相同的点……当然会很慢
所以我们先sort一下再进行计算
#include<algorithm>
#include<iostream>
#include<cstdio>
#define MAXN 100005
using namespace std;
struct Point
{
int x;
int y;
int ansx,ansy;//ansx ansy记录与这个点横坐标或纵坐标相同的点的个数
} p[MAXN];
bool cmp1(const Point &a,const Point &b)//对点的横坐标排序
{
return a.x<b.x;
}
bool cmp2(const Point &a,const Point &b)//对点的纵坐标排序
{
return a.y<b.y;
}
int n,t;
long long ans;
int main()
{
//freopen("right.in","r",stdin);
//freopen("right.out","w",stdout);
scanf("%d",&n);
for(int i=1; i<=n; i++)
scanf("%d%d",&p[i].x,&p[i].y);
sort(p+1,p+1+n,cmp1);//将点的横坐标从小到大排序
t=1;
while(t<=n)//从左往右循环
{
int s=0,r=0;//当前查找坐标为r s为查找的起点
if(t==n) break;
int cnt=0;//cnt记录与之坐标相同的点的个数
s=t;//将起点设为上一次查找的终点
r=p[t].x;
while(p[t].x==r)//当当前点的坐标等于正在寻找的坐标时 t++ cnt++
{
t++;
cnt++;
}
for(int i=s; i<=t; i++)//与之相同的点的个数为cnt-1
p[i].ansx=cnt-1;
}
sort(p+1,p+1+n,cmp2);//对于纵坐标 与横坐标同理
t=1;
while(t<=n)
{
int s=0,r=0;
if(t==n) break;
int cnt=0;
s=t;
r=p[t].y;
while(p[t].y==r)
{
t++;
cnt++;
}
for(int i=s; i<=t; i++)
p[i].ansy=cnt-1;
}
for(int i=1; i<=n; i++)
ans+=p[i].ansx*p[i].ansy;//答案等于每个点的ansx*ansy的总和
printf("%d",ans);
return 0;
}