CF1163C1 Power Transmission (Easy Edition) 题解
前言
再没见过这么水的
附:做完这题可以去做一下 [ABC248E] K-colinear Line。
解法
首先,两条直线如果能相交,那么它们的斜率必然不相等。
所以,我们只需要枚举每两个点,然后将经过它们的直线的斜率存进一个 std::vector,最后直线两两再枚举判断斜率是否相等即可。
但是,本题需要处理三点共线。
我们首先需要一个判断三点共线的函数;利用相似三角形的原理即可。
bool pd(int a,int b,int c){
return (ay[b]-ay[a])*(ax[c]-ax[a])==(ax[b]-ax[a])*(ay[c]-ay[a]);
}
每次枚举两个点的时候,就把其他所有点都扫一遍,每遇到一个新的点,如果它与原始的两个点贡献,那么将它装入数组
放代码:
#include<bits/stdc++.h>
#define st first
#define nd second
using namespace std;
typedef pair<int,int> pii;
bool pd(pii a,pii b,pii c){
return (b.nd-a.nd)*(c.st-a.st)==(b.st-a.st)*(c.nd-a.nd);
} // 判断函数
int main(){
ios::sync_with_stdio(false);
int n,c=0; cin>>n;
vector<pii> a(n),d;
vector<vector<bool> > b(n,vector<bool>(n));
for(auto &[x,y]:a)cin>>x>>y;
for(int i=0;i<n-1;i++)
for(int j=i+1;j<n;j++){
if(b[i][j])continue;
vector<int> v={i,j};
for(int k=j+1;k<n;k++)
if(pd(a[i],a[j],a[k]))v.emplace_back(k); // 统计三点共线
for(auto &i:v)for(auto &j:v)b[i][j]=true; // 打标记
d.emplace_back(a[i].st-a[j].st,a[i].nd-a[j].nd);
}
for(auto &i:d)for(auto &j:d)
c+=(i.st*j.nd!=i.nd*j.st); // 枚举斜率不相同的直线有多少对
cout<<(c>>1)<<endl; // 每两个点统计了两遍,最终答案需要除以二
return 0;
}