牛客小白月赛103 补题
D-冰冰的分界线_牛客小白月赛103
题目大意:
给你很多不同点,每两个点可以找到一个直线,这个直线上任意一点到两个点距离都相等,问存在多少个这样的直线,且不能算上重复的直线(完全覆盖)
思路:
点不多,可以暴力枚举每两个点,对于每两个点构成的‘直线’ ,只需要将它的斜率和截距算出来,在去掉里面重合的直线,算斜率的时候考虑一下存不存在斜率就行了。
AC代码:
#include <bits/stdc++.h>
#define int long long
using namespace std;
typedef pair<int,int> pri;
typedef pair<double,double> prf;
const double eps = 1e-8;
int sgn(double x){
if(fabs(x) < eps) return 0;
else return x < 0 ? -1 : 1;
}
void solve(){
int t;
cin >> t;
while (t--){
int n;
cin >> n;
vector<int> X;
set<int> noK;//斜率不存在的
vector<prf> youK;//斜率存在的
vector<pri> points;//坐标
for (int i = 0,num;i < n;i++){
cin >> num;
X.push_back(num);
}
for (int i = 0,num;i < n;i++){
cin >> num;
points.push_back(pri(X[i],num));
}
for (int i = 0;i < points.size() - 1;i++){//暴力枚举两两点
for (int j = i + 1;j < points.size();j++){
pri A,B;
A = points[i],B = points[j];
if (A.second == B.second){//如果是斜率不存在的
noK.insert(A.first + B.first);
}
else {//存在斜率
double nx = (A.first + B.first) / 2.0;
double ny = (A.second + B.second) / 2.0;
double nk = -1.0 * (B.first - A.first) / (double)(B.second - A.second);//斜率就是原来两点连线斜率的负倒数
if (A.first == B.first) nk = 0.0;//如果是斜率为0
double nd = ny - nk * nx;//y = kx + b -> b = y - kx
youK.push_back(prf(nk,nd));
}
}
}
sort(youK.begin(),youK.end());//排序方便查找
int cnt = noK.size();
if (!youK.empty()){//处理重复直线
for (int i = 0;i < (int)youK.size();i++){
int c = i;
double k = youK[i].first,d = youK[i].second;
while (c < youK.size() && sgn(youK[c].first - k) == 0 && sgn(youK[c].second - d) == 0){//近似重合的就忽略
c++;
}
cnt++;
i = c - 1;//跳到下一个与它不近似的线
}
}
cout << cnt << endl;
}
}
void o2(){ios::sync_with_stdio(false),cin.tie(0);}
signed main(){
o2();
solve();
return 0;
}