题解 P6355 【[COCI2007-2008#3] DEJAVU】

SingularPoint

2020-10-11 20:29:35

Solution

### 题目大意 给出坐标系中的$n$个点,求以不同的三个点组成的 **直角边与坐标轴平行的直角三角形**个数。 ### 分析 由题意可以知道:如果我们设符合要求的三角形直角顶点坐标为$A(x_1,y_1)$,那么剩下两点坐标一定为$B(x_1,y_i)$、$C(x_j,y_1)$。所以,如果我们确定一个点为直角顶点,那么可以与之配合成为目标三角形的只有是横、纵坐标都与之相同的点。 由此,我们可以考虑用两个数组$sumx$、$sumy$来记录一个横坐标或纵坐标上的点的个数,明显的,当直角顶点为$A(x_1,y_1)$时,可以组成的目标三角形个数为 >$(sumx(x_1)-1)\times(sumy(y_1)-1)$ (注:-1是减去当前所在的点) 由此,我们可以枚举每个点,取出它所在的横、纵坐标,用上面的公式计算出在这个点可以组成的目标三角形个数,累加起来,就是答案啦~ 分析结束,上代码! ### Code **P.S.:$3\leq n<10^5$,日常爆int,不开long long两行泪。** ```cpp #include<bits/stdc++.h> #define ll long long using namespace std; const int M=100005; struct node{ ll x,y; }p[M]; int n; ll sx[M],sy[M]; ll ans=0; int main() { scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%lld%lld",&p[i].x,&p[i].y); sx[p[i].x]++; sy[p[i].y]++; } for(int i=1;i<=n;i++) ans+=(sx[p[i].x]-1)*(sy[p[i].y]-1); printf("%lld",ans); return 0; } ``` 完结撒fa~