牛客小白月赛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;
}

posted @ 2024-11-02 17:57  xiyangdaxia  阅读(26)  评论(0)    收藏  举报