codeforces contest 1163 C2. Power Transmission (Hard Edition)---计算几何

    xiaoxiao2021-04-19  248

    题目链接:https://codeforces.com/contest/1163/problem/C2

    题解:最多有n*(n-1)条直线,可以暴力的去枚举判断直线是否相交,同一平面内的两条直线不平行即相交,所以将所有的直线按斜率划分,相同斜率中去掉重复的直线,每个斜率的贡献就是:该斜率的直线数*(总的直线数(不算重合的)-该斜率的直线数)。

    感觉这道题主要是让我学了下pair和map的用法,还有代码中截距的计算,题解是整型,但我没想通,感觉应该是double才对,但不知道万一出精度锅怎么办。。

    #include<bits/stdc++.h> #define ll long long #define pr pair<ll, ll> using namespace std; const int maxn = 1e3+5; struct Point{ ll x, y; }p[maxn]; map<pr, ll>cnt; map<pair<pr, double>, bool>vis; int main(){ int n; cin >> n; for(int i = 0; i < n; i++){ cin >> p[i].x >> p[i].y; } ll m = 0; cnt.clear(); vis.clear(); for(int i = 0; i < n; i++){ for(int j = i+1; j < n; j++){ ll a = p[i].y - p[j].y; ll b = p[i].x - p[j].x; double c = 1.0*(p[i].y*p[j].x - p[i].x*p[j].y); ll d = __gcd(a, b); a /= d; b /= d; c /= d*1.0; if(a < 0 || (a == 0 && b < 0)){ a = -a, b = -b, c = -c; } pr tmp = make_pair(a, b); if(!vis[make_pair(tmp, c)]){//去掉重合的直线 vis[make_pair(tmp, c)] = true; cnt[tmp]++; m++;//统计总的直线数 } } } map<pr, ll>::iterator it; ll ans = 0; for(it = cnt.begin(); it != cnt.end(); it++){ ll tmp = cnt[it->first]; ans += tmp * (m-tmp); } ans /= 2; cout << ans << endl; }

     


    最新回复(0)