Mow

题目链接

分析

将多边形的边向内部缩 r 个单位长度,然后这些边所围成的内部区域,就是圆心的合法范围,该范围也是一个多边形,假设面积是\(a\),周长是\(b\),那么可以知道圆可以覆盖的面积是 \(a + b * r + \pi *r^2\)。现在问题转换为了求这些边所围成的区域,这正是半平面交所要做的事情。

需要用到的知识点:

  1. 极角排序
  2. 直线平移
  3. 直线求交点
  4. 单调队列求半平面交
  5. 多边形利用三角剖分求面积,求周长

另外需要注意的是该题目精度有些卡,需要用longdouble,另外要注意一些常用函数后面加 l,比如acos要换成acosl,sqrt要换成sqrtl等。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
#define dbg(x...) do { cout << "\033[32;1m" << #x <<" -> "; err(x); } while (0)
void err() { cout << "\033[39;0m" << endl; }
template<class T, class... Ts> void err(const T& arg,const Ts&... args) { cout << arg << " "; err(args...); }
const int N = 200 + 5; typedef long double db;
const db eps = 1e-12;
const db pi = acosl(-1.0); int T, n;
db A, B, r;
int sgn(db x){
if(fabs(x) < eps) return 0;
if(x < 0) return -1;
return 1;
} inline db sqr(db x){return x * x;}
struct Point{
db x, y;
Point(){}
Point(db x, db y):x(x), y(y){}
void input(){
cin >> x >> y;
}
bool operator == (Point b) const {
return sgn(x - b.x) == 0 && sgn(y - b.y) == 0;
}
bool operator < (Point b) const{
return sgn(x - b.x) == 0 ? sgn(y - b.y) < 0 : x < b.x;
}
// 向量运算
Point operator - (const Point &b) const{
return Point(x - b.x, y - b.y);
}
Point operator + (const Point &b) const{
return Point(x + b.x, y + b.y);
}
db operator ^ (const Point &b) const{
return x * b.y - y * b.x;
}
db operator * (const Point &b) const{
return x * b.x + y * b.y;
}
// 标量运算 * /
Point operator *(const db &k) const{
return Point(x * k , y * k);
}
Point operator / (const db &k) const{
return Point(x / k, y / k);
} db len(){
return sqrtl(x * x + y * y);
}
db len2(){
return x * x + y * y;
}
db distance(Point p) {
return (*this - p).len();
} Point trunc(db r) {
db l = len();
if(sgn(l) == 0) return *this;
return Point(x * r / l, y * r / l);
}
Point rotleft(){
return Point(-y, x);
}
Point rotright(){
return Point(y, -x);
}
}p[N]; struct Line{
Point s, e;
Line(){}
Line(Point s, Point e) : s(s), e(e){}
void input(){
s.input();e.input();
}
bool operator == (Line v){
return (s == v.s) && (e == v.e);
}
db length() {
return s.distance(e);
}
bool parallel(Line v){
return sgn((e - s) ^ (v.e - v.s)) == 0;
}
Point crossPoint(Line v) {
db a1 = (v.e - v.s) ^ (s - v.s);
db a2 = (v.e - v.s) ^ (e - v.s);
db t = a2 - a1;
return Point((s.x * a2 - e.x * a1) / t, (s.y * a2 - e.y * a1) / t);
}
}l[N]; struct Polygon{
int n;
Point p[N];
Line l[N];
void input(int n) {
this->n = n;
for(int i=0;i<n;i++) p[i].input();
}
db getCircumference(){
db res = 0;
for(int i=0;i<n;i++) res += p[i].distance(p[(i+1)%n]);
return res;
}
db getArea(){
db res = 0;
for(int i=0;i<n;i++)res += (p[i] ^ p[(i+1)%n]);
return fabs(res) / 2;
}
struct cmp{
Point p;
cmp(const Point &p0) {p = p0;}
bool operator()(const Point &aa, const Point &bb) {
Point a = aa, b = bb;
int d = sgn((a - p) ^ (b - p));
if(d == 0) return sgn(a.distance(p) - b.distance(p)) < 0;
return d > 0;
}
};
void norm(){
Point mi = p[0]; for(int i=1;i<n;i++) mi = min(mi, p[i]);
sort(p, p+n, cmp(mi));
}
}lawn, poly;
void adjust(){
lawn.norm();
for(int i=0;i<n;i++){
Point a = lawn.p[i], b = lawn.p[(i+1)%n];
Point aa = a + (b - a).rotleft().trunc(r);
Point bb = b + (b - a).rotleft().trunc(r);
l[i] = Line(aa, bb);
}
}
bool getHalfPlanes(){
Line q[N];
Point t[N];
int ll = 1, rr = 0;
for(int i=0;i<n;i++){
if(l[i] == l[(i-1+n)%n] || l[i].parallel(l[(i-1+n)%n]))continue;
while(ll < rr && ((l[i].e - t[rr]) ^ (l[i].s - t[rr])) > eps) rr--;
while(ll < rr && ((l[i].e - t[ll+1]) ^ (l[i].s - t[ll+1])) > eps) ll++;
q[++rr] = l[i];
if(ll < rr) t[rr] = q[rr].crossPoint(q[rr-1]);
}
while(ll < rr && ((q[ll].e - t[rr]) ^ (q[ll].s - t[rr])) > eps) rr--;
t[rr+1] = q[ll].crossPoint(q[rr]);
++rr, ++ll;
if(rr - ll + 1 <= 2) return false;
poly.n = rr - ll + 1;
for(int i=ll;i<=rr;i++) poly.p[i-ll] = t[i];
return true;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("i.in","r",stdin);
// freopen("o.out","w",stdout);
#endif
scanf("%d", &T);
while(T--){
scanf("%d", &n);
cin >> r >> A >> B;
lawn.input(n);
adjust();
db total = lawn.getArea();
db res = total * A;
if(getHalfPlanes()) {
db area = poly.getArea();
db length = poly.getCircumference();
area = area + length * r + pi * r * r;
res = min(res, area * B + (total - area) * A);
}
cout << fixed << setprecision(20) << res << endl;
}
return 0;
}

HDU 6762 Mow (2020 Multi-University Training Contest 1 1012) 半平面交的更多相关文章

  1. hdu 4930 Fighting the Landlords--2014 Multi-University Training Contest 6

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4930 Fighting the Landlords Time Limit: 2000/1000 MS ...

  2. HDU 6143 - Killer Names | 2017 Multi-University Training Contest 8

    /* HDU 6143 - Killer Names [ DP ] | 2017 Multi-University Training Contest 8 题意: m个字母组成两个长为n的序列,两序列中 ...

  3. HDU 6074 - Phone Call | 2017 Multi-University Training Contest 4

    看标程的代码这么短,看我的.... 难道是静态LCA模板太长了? /* HDU 6074 - Phone Call [ LCA,并查集 ] | 2017 Multi-University Traini ...

  4. HDU 6068 - Classic Quotation | 2017 Multi-University Training Contest 4

    /* HDU 6068 - Classic Quotation [ KMP,DP ] | 2017 Multi-University Training Contest 4 题意: 给出两个字符串 S[ ...

  5. HDU 6076 - Security Check | 2017 Multi-University Training Contest 4

    /* HDU 6076 - Security Check [ DP,二分 ] | 2017 Multi-University Training Contest 4 题意: 给出两个检票序列 A[N], ...

  6. HDU 6071 - Lazy Running | 2017 Multi-University Training Contest 4

    /* HDU 6071 - Lazy Running [ 建模,最短路 ] | 2017 Multi-University Training Contest 4 题意: 四个点的环,给定相邻两点距离, ...

  7. HDU 6078 - Wavel Sequence | 2017 Multi-University Training Contest 4

    /* HDU 6078 - Wavel Sequence [ DP ] | 2017 Multi-University Training Contest 4 题意: 给定 a[N], b[M] 要求满 ...

  8. HDU 6070 - Dirt Ratio | 2017 Multi-University Training Contest 4

    比赛时会错题意+不知道怎么线段树维护分数- - 思路来自题解 /* HDU 6070 - Dirt Ratio [ 二分,线段树 ] | 2017 Multi-University Training ...

  9. HDU 6036 - Division Game | 2017 Multi-University Training Contest 1

    /* HDU 6036 - Division Game [ 组合数学,NTT ] | 2017 Multi-University Training Contest 1 题意: k堆石子围成一个圈,数量 ...

随机推荐

  1. ORA-28001: the password has expired解决方法

    Oracle提示错误消息ORA-28001: the password has expired,是由于Oracle11G的新特性所致, Oracle11G创建用户时缺省密码过期限制是180天(即6个月 ...

  2. vue 深度作用选择器

    使用 scoped 后,父组件的样式将不会渗透到子组件中 如果想在使用scoped,不污染全局的情况下,依然可以修改子组件样式,可以使用深度作用选择器 .tree{ width: 100%; floa ...

  3. 剑指offer 面试题0:扎实的基础:即编程语言、数据结构和算法

    编程语言: Q:如果写的函数需要传入一个指针,则是否需要为该指针加上const?把const加在指针不同的位置是否有区别? A:const是用来声明一个常量的,如果不想让一个值改变就应该加上const ...

  4. js的函数-function

    function函数 function的英文是[功能],[数] 函数:职责:盛大的集会的意思 在js里,就是函数的意思.在Java里叫做方法. 定义函数 function fun(参数){ //函数体 ...

  5. 【译】Async/Await(二)——Futures

    原文标题:Async/Await 原文链接:https://os.phil-opp.com/async-await/#multitasking 公众号: Rust 碎碎念 翻译 by: Praying ...

  6. 【win10】win10下两个显示器不同桌面壁纸

    win10系统下,双屏显示为不同的桌面壁纸 操作: 1.鼠标右键点击个性化 2.点击背景选项 3.在图片上右键选择要添加为背景的图片 同理,将另一个屏幕壁纸设为监视器1 最后效果为两个分屏为不同桌面壁 ...

  7. 【译】Async/Await(三)——Aysnc/Await模式

    原文标题:Async/Await 原文链接:https://os.phil-opp.com/async-await/#multitasking 公众号: Rust 碎碎念 翻译 by: Praying ...

  8. Centos7.4 小白式安装(初学)

    虚拟机安装Centos7.4系统 适用人群(初学者) 下载Centos7.4镜像 https://pan.baidu.com/s/1NtjfdHV3OWAvfDj5vrR7HQ  提取码:hzzw 虚 ...

  9. Spider爬虫基础

    get获取某个网站的html代码,post访问网站获取网站返回的信息 import urllib.request import urllib.parse #使用get请求 def start1(): ...

  10. 2020 CSP&NOIP 游记

    CSP初赛 CSP初赛 Day -1 早上打了模拟赛,T2寒假正好做过,然而还是还是被踩Orz,郑外NB!.中午出校吃了大盘鸡和拉面,还带回来了三瓶可乐. 初赛知识点看了两页不(看)想(不)看(懂)了 ...