P3744 李彬的几何

题目

  • 给定一个凸多边形,每个点最大可以移动的距离为 d d d,让他变得不“凸”,求解最小d

算法思路

  • 实际上,就是求解一个点到,他相邻两个点直线的距离的一半
  • 点移动 0.5 h 0.5h 0.5h,直线移动 0.5 h 0.5h 0.5h,然后这样就是水平的了
  • 做一个无穷小的偏移量,他就是凹的了
  • 最后需要实现的就是点到直线的距离了
  • 叉积/模长即可求得结果

代码实现

//#pragma GCC optimize("O3")
#include <bits/stdc++.h>
#include <unordered_map>
#include <unordered_set>
using namespace std;

#define debug(x) cerr << #x << ": " << x << '\n'
#define bd cerr << "----------------------" << el
#define el '\n'
#define cl putchar('\n')
#define pb push_back
#define eb emplace_back
#define x first
#define y second
#define rep(i, a, b) for (int i = (a); i <= (b); i++)
#define loop(i, a, b) for (int i = (a); i < (b); i++)
#define dwn(i, a, b) for (int i = (a); i >= (b); i--)
#define ceil(a, b) (a + (b - 1)) / b
#define ms(a, x) memset(a, x, sizeof(a))
#define inf 0x3f3f3f3f
#define db double

typedef long long LL;
typedef long double LD;
typedef pair<int, int> PII;
typedef pair<db, db> PDD;
typedef vector<int> vci;
typedef map<int, int> mii;
typedef mii::iterator mii_it;

const int N = 1e5 + 10, M = 2e6 + 10, E = 1e3 + 10, md = 1e9 + 7;
const double PI = acos(-1), eps = 1e-8;

int T, n, m;
PDD p[N];

PDD operator- (PDD a, PDD b)
{
    return {a.x - b.x, a.y - b.y};
}

db operator* (PDD a, PDD b)
{
    return a.x * b.y - a.y * b.x;
}

db operator& (PDD a, PDD b)
{
    return a.x * b.x + a.y * b.y;
}

db get_len(PDD a)
{
    return sqrt(a & a);
}

db calc(int i)
{
    return fabs((p[i + 1] - p[i]) * (p[i + 2] - p[i])
     / get_len(p[i + 2] - p[i]))  / 2;
    //面积/底边==高
    //点移动0.5h,直线移动0.5h,然后这样就是水平的了,做一个无穷小的偏移量
}
db ans = 1e12;
int main()
{
    cin.tie(0);
    cout.tie(0);
    cin >> n;
    dwn (i, n - 1, 0)//逆序的话就就是逆时针了,不过因为取了绝对值,其实没差别
    {
        cin >> p[i].x >> p[i].y;
    }
    p[n] = p[0], p[n + 1] = p[1];//这样后面就不需要取模
    loop(i, 0, n)
    {
        ans = min(ans, calc(i));
    }
    printf("%.9lf\n",ans);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值