AtCoder Beginner Contest 220 G - Isosceles Trapezium(计算几何+map)

传送门

题意

给N个点,每一个点有一个权值,找一个顶点权值和最大的等腰梯形。(\(1\leq N\leq 1000\)

做法

非常巧妙地运用了等腰梯形的一个性质:上底的中垂线与下底的中垂线重合,于是可以枚举出任意两点的中垂线,然后找中垂线上权值最大的两个点。

比较好写的写法就是map套map,但我自己写了半天都在报错,最后就抄网上的大佬写的。

代码

 /*************************************************************************
> File Name: 1.cpp
> Author: Knowledge_llz
> Mail: 925538513@qq.com
> Blog: https://www.cnblogs.com/Knowledge-Pig/ 
> Created Time: 2021/9/15 18:40:30
************************************************************************/

#include<bits/stdc++.h>
#define For(i,a,b) for(int i=(a);i<=(b);++i)
#define LL long long
#define pb push_back
#define pr pair<LL, LL>
#define endl '\n'
using namespace std;
LL n, ans = -1, x[1005], y[1005], c[1005];
map<tuple<LL, LL, LL>, map<pair<LL, LL>, LL>> M;
int main(){
    ios::sync_with_stdio(false); cin.tie(0);
#ifndef ONLINE_JUDGE
    freopen("input.in", "r", stdin);
    freopen("output.out","w", stdout);
#endif
    cin >> n;
    for(int i = 1; i <= n; ++i) cin >> x[i] >> y[i] >> c[i];
    for(int i = 1; i <= n; ++i)
        for(int j = i + 1; j <= n; ++j){
            LL px = x[j] - x[i], py = y[j] - y[i], midx = x[j] + x[i], midy = y[j] + y[i];
            LL g = __gcd(px, py);
            px /= g; py /= g;
            if(px < 0 || (!px && py < 0)) px = -px, py = -py;
            auto &line = M[{px, py, midx * px + midy * py}];
            line[pr(midx, midy)] = max(line[pr(midx, midy)], c[i] + c[j]);
        }
    for(auto line : M){
        pr tmp(0, 0);
        for(auto point : line.second){
            if(tmp.first > tmp.second) tmp.second = max(tmp.second, point.second);
            else tmp.first = max(tmp.first, point.second);
        }
        if(tmp.first > 0 && tmp.second > 0) ans = max(ans, tmp.first + tmp.second);
    }
    cout << ans << endl;
return 0;
}  
posted @ 2021-09-27 21:12  Knowledge-Pig  阅读(11)  评论(0)    收藏  举报