CF682E 计算几何,对称

题目大意:

n ( ≤ 5000 ) n(\le 5000) n(5000)个点,任意三个点构成的三角形面积不会超过 S ( ≤ 1 0 18 ) S(\le 10^{18}) S(1018)

寻找一个顶点都为整点的三角形包含所有顶点,面积不超过 4 S 4S 4S

解题思路:

  • 先任意找给定 n n n个点中的三个点 a , b , c a,b,c a,b,c,对于线段 a b ab ab,倘若有其他点 i i i,构成的三角形 △ a b i \triangle abi abi面积大于 △ a b c \triangle abc abc,则将 c c c替换,对于其他边同理(这个算法并不是求点集中最大三角形的算法)

  • 得到的三角形 △ a b c \triangle abc abc,最后答案输出 a a a关于 b c bc bc中点对称的点,其余同理,下面初略解释下

  • 对于 a , b , c a,b,c a,b,c以外所有的点都会在如下黑线的区域中:

![](https://img-blog.csdnimg.cn/3a05a82b456b4073b0069fa2e792cc36.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5ZGD5ZGDLi4u,size_18,color_FFFFFF,t_70,g_se,x_16)

  • 然后我们可以发现这个大区域是个三角形,且可以用4个与 △ a b c \triangle abc abc全等的小三角形构成
  • 且最终大三角形得到的点,都是上面描述的对称点

AC代码:

#include <bits/stdc++.h>
#define ft first
#define sd second
#define pb push_back
#define IOS ios::sync_with_stdio(false), cin.tie(0), cout.tie(0) //不能跟puts混用
#define seteps(N) fixed << setprecision(N)
#define endl "\n"
const int maxn = 5e3 + 10;
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int, int> pii;
const ll mod = 1e9 + 7;
int n;
ll s;
struct Point {
    ll x, y;
    ll operator ^ (Point p) {return x * p.y - y * p.x;}
    Point operator - (Point p) {return {x - p.x, y - p.y};}
} p[maxn];
ll getarea(int i, int j, int k) {
    return abs((p[j] - p[i]) ^ (p[k] - p[i]));
}
int main() {
    cin >> n >> s;
    for (int i = 1; i <= n; i++) cin >> p[i].x >> p[i].y;
    int a = 1, b = 2, c = 3;
    bool ok = true;
    while (ok) {
        ok = false;
        s = getarea(a, b, c);
        for (int i = 1; i <= n; i++) {
            if (s < getarea(i, a, b)) ok = true, s = getarea(i, a, b), c = i;
            else if (s < getarea(i, b, c)) ok = true, s = getarea(i, b, c), a = i;
            else if (s < getarea(i, c, a)) ok = true, s = getarea(i, c, a), b = i;
        }
    }
    cout << p[a].x + p[b].x - p[c].x << " " << p[a].y + p[b].y - p[c].y << endl;
    cout << p[b].x + p[c].x - p[a].x << " " << p[b].y + p[c].y - p[a].y << endl;
    cout << p[a].x + p[c].x - p[b].x << " " << p[a].y + p[c].y - p[b].y << endl;
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值