半平面交+数组模拟双端队列

人生第一次代码过两百行啊...加油加油

#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<iomanip> #define ld long double
using namespace std; const int maxn = 1e3;
const ld pi = acosl(-);
const ld eps = 1e-;//控制精度 int n;
int head, tail;
ld r, cost1, cost2; typedef struct Grid
{//棋盘
ld x,y;
Grid(double a = , double b = ){x = a, y = b;}//构造函数,结构体对象创建时执行
} point , Vector ;//point:类型为Grid的数据类型;Vector与point结构相同,数据类型名称不同 typedef struct Net
{
point a,b;
Net() {}//重载构造函数,目的是以形如line x;的方式定义直线,避免定义时确定参数的复杂性
Net(point i, point j){a = i, b = j;}
} line ; point node[maxn], p[maxn];
line l[maxn], L[maxn], q[maxn]; Vector operator - (point a, point b) // V需大写,避免与vector混淆
{
return Vector(b.x - a.x, b.y - a.y);
}//矢量定义 double operator * (Vector a, Vector b)
{
return (a.x * b.y - a.y * b.x);
}//叉乘 ld getangle(Vector t)
{
return atan2(t.y, t.x);//返回一个(-pi,pi]的角度
}//获得某个矢量的极角 ld getangle(line t)
{
return atan2(t.b.y - t.a.y, t.b.x - t.a.x);
}//获得某条直线的极角 bool cmp(line a, line b)
{
Vector v1 = (a.b - a.a), v2 = (b.b - b.a);
ld A = getangle(v1), B = getangle(v2);
if(fabs(A - B) < eps){
return (v1 * (b.b - a.a) >= );//靠左边的丢在后面,方便双端队列去重
}
return A < B;
}//决定根据极角排序的直线的优先级 bool check()
{
ld ans = ;
for(int i = ; i < n- ; i++){
ans += (node[i] - node[]) * (node[i+] - node[]);
}
if(ans < ) return false;
return true;
}//检查point输入顺序进行调整 true为逆时针 point getnode(line a, line b)//求两直线(线段)交点,一般式三参数暴力求解
{
ld a1 = a.b.y - a.a.y, b1 = a.a.x - a.b.x, c1 = a.b.x * a.a.y - a.a.x * a.b.y;
ld a2 = b.b.y - b.a.y, b2 = b.a.x - b.b.x, c2 = b.b.x * b.a.y - b.a.x * b.b.y;
ld D = a1 * b2 - a2 * b1;
//Dx/D,Dy/D,注意c1、c2移至右侧变号
return point((c2 * b1 - b2 * c1) / D, (c1 * a2 - a1 * c2) / D);
} bool on_right(line a, line b, line c)//观察a、b交点与c的关系
{
point n = getnode(a, b);
if((c.b - c.a) * (n - c.a) < ){//交点在右侧/下方
return true;
}
return false;
} line narrow_line(line x)//实现直线平移,勾画出圆心轨迹
{
ld dx = x.b.x - x.a.x, dy = x.b.y - x.a.y;
Vector turnv;//旋转矢量
turnv.x = -dy, turnv.y = dx; ld m = sqrtl(dx * dx + dy * dy);
turnv.x = turnv.x / m * r;
turnv.y = turnv.y / m * r;
//求对应坐标
x.b.x += turnv.x;
x.b.y += turnv.y;
x.a.x += turnv.x;
x.a.y += turnv.y;
return x;
} void narrow_polygon()//模拟圆心轨迹
{
for(int i = ; i <= n- ; i++){
L[i] = narrow_line(l[i]);
}
} bool HPI()
{
sort(L,L+n,cmp);//按极角排序
head = , tail = ;
int cnt = ;
for(int i = ; i < n- ; i++){
Vector v1 = L[i].b - L[i].a, v2 = L[i+].b - L[i+].a;//?
if(fabs(getangle(v1) - getangle(v2)) < eps){
continue;
}
L[cnt++] = L[i];
}
L[cnt++] = L[n-]; /////正片开始
for(int i = ; i < cnt ; i++){//注意下标
while(tail - head > && on_right(q[tail-], q[tail-], L[i])) tail--;//符合onright规则,删去上一条直线
while(tail - head > && on_right(q[head], q[head+], L[i])) head++;//头部同理
q[tail++] = L[i];
}
//换个角度看世界,最后检验q[head]以及q[tail-1],q[tail]实际为空
while(tail - head > && on_right(q[tail-], q[tail-], q[head])) tail--;
while(tail - head > && on_right(q[head], q[head+], q[tail-])) head++; if((tail - head) >= ) return true;
return false;
} ld get_S()//求初始面积
{
ld ans = ;
for(int i = ; i < n ; i++){
ans += fabs((node[i] - node[]) * (node[(i+)%n] - node[]));
}
return ans / ;
} ld dis(point a, point b)
{
ld dx = b.x - a.x, dy = b.y - a.y;
return sqrtl(dx * dx + dy * dy);
}//两点间距离 ld get_inS()//内部半平面交 面积
{
ld res = ;
int tot = ;
for(int i = head ; i < tail- ; i++){
p[tot++] = getnode(q[i], q[i+]);
}
p[tot++] = getnode(q[tail-], q[head]); for(int i = ; i < tot- ; i++){
res += fabs((p[i] - p[]) * (p[i+] - p[]));
}
res /= ; for(int i = ; i < tot- ; i++){
res += dis(p[i], p[i+]) * r;
}// c * r
res += dis(p[], p[tot - ]) * r; return res + r * r * pi;
} int main(){
//freopen("mow.in","r",stdin);
int T;cin >> T;
while( T-- )
{
cin >> n >> r >> cost1 >> cost2;
for(int i = n- ; i >= ; i--){
cin >> node[i].x >> node[i].y;
}//本题中为顺时针方向,因而逆序存点,以确保直线左侧为内侧 if(check()){//逆
for(int i = ; i < n- ; i++){//
l[i] = line(node[i], node[i+]);
}
l[n-] = line(node[n-], node[]);
}else{//顺
for(int i = ; i < n- ; i++){
l[i] = line(node[i+],node[i]);
}
l[n-] = line(node[], node[n-]);
}//0 ~ n-1 narrow_polygon(); ld s = get_S();//草坪面积
ld ans = s * cost1;//手动割草费用 if(HPI()){
ld mowable = get_inS();//机器割草面积
ans = min(ans, mowable * cost2 + (s - mowable) * cost1);
}
cout << fixed << setprecision() << ans << "\n"; } return ;
}
//实现直线平移,勾画出圆心轨迹

hdu6755 Mow的更多相关文章

  1. HDU 6762 Mow (2020 Multi-University Training Contest 1 1012) 半平面交

    Mow 题目链接 分析 将多边形的边向内部缩 r 个单位长度,然后这些边所围成的内部区域,就是圆心的合法范围,该范围也是一个多边形,假设面积是\(a\),周长是\(b\),那么可以知道圆可以覆盖的面积 ...

  2. java中获取路径的几种基本的方法

    package com.ygh.blog.realpath; import java.io.File; import java.io.IOException; import java.io.Input ...

  3. TPC-H生成.tbl文件导入postgresql数据库的坑

    数据库project好好的不用主流的MySQL和Microsoft server而要求用听都没听过的postgresql (当然,可能你三个都没听过) 这里的坑主要是把生成的那八张.tbl的表导入pg ...

  4. js实现多张图片每隔一秒换一张图片

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAlkAAAHWCAIAAADLlAuAAAAgAElEQVR4nOzd5XNc157w+/l7bt2n6t

  5. mysql触发器,答题记录表同步教学跟踪(用户列表)

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAABVQAAAOOCAIAAABgEw4AAAAgAElEQVR4nOy92VcT27r/zX+xLtflvt

  6. java调用sqlldr导入csv文件数据到临时表

    package cn.com.file;import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.File; ...

  7. CSS布局(二)

    本节内容:position.float.clear.浮动布局例子.百分比宽度 position CSS中的position属性设置元素的位置.属性值:static.relative.fixed.abs ...

  8. 这些HTML、CSS知识点,面试和平时开发都需要 No5-No7

    系列知识点汇总 这些HTML.CSS知识点,面试和平时开发都需要 No1-No4(知识点:HTML.CSS.盒子模型.内容布局) 这些HTML.CSS知识点,面试和平时开发都需要 No5-No7(知识 ...

  9. C#基础整理参数

    基本概念 把数据传入方法中,可以使方法有多个返回值. 参数的传递 值参数,通过将实参的值复制到形参的方式传递数据.值参数的实参可以是变量或者是表达式

随机推荐

  1. 学习Java的Day02

    知识点 数组: 一维数组   声明: 类型[] 数组名;([] 在前后没有影响,一般写在名称前.) 创建数组  数组名 =  new 类型[数组长度]. 数组索引从0开始.获取数组长度:数组名.len ...

  2. vue全家桶(3.2)

    4.5.创建实例 可以创建一个自定义实例应用于多个请求接口 <template> <div class="page"> </div> </ ...

  3. 注解式HTTP请求Feign (F版)

    Spring Cloud 为开发者提供了在分布式系统中的一些常用的组件(例如配置管理,服务发现,断路器,智能路由,微代理,控制总线,一次性令牌,全局锁定,决策竞选,分布式会话集群状态).使用Sprin ...

  4. pdfjs优化,实现按需加载,节省流量和内存

    1 问题 当使用pdfjs来实现预览功能的时候,遇到了2个问题: 一是带宽占用过大,会下载整个pdf文件,这对部署在公网的应用来说,成本压力很大,因为云服务带宽是很贵的. 二是内存占用过大,一个80M ...

  5. 小白入门NAS—快速搭建私有云教程系列(一)

    什么是NAS 在日常的工作生活中,我们有大量的资料.文件需要存储在电脑或者其他终端设备中,但是这种方式需要电脑配备高容量的硬盘,而且需要随时随地的带着,这样是不是很麻烦? 那么,今天,我来介绍一种家庭 ...

  6. PHP用PHPExcel导出有多个工作表的Excel表格(thinkPHP3.2.3)

    直接上代码: //导出excel public function excel() { //引入相关文件 import("Org.Util.PHPExcel"); import(&q ...

  7. Tomcat的启停脚本源码解析

    Tomcat是一款我们平时开发过程中最常用到的Servlet容器.本系列博客会记录Tomcat的整体架构.主要组件.IO线程模型.请求在Tomcat内部的流转过程以及一些Tomcat调优的相关知识. ...

  8. 浏览器的回流与重绘 (Reflow & Repaint)

    写在前面 在讨论回流与重绘之前,我们要知道: 浏览器使用流式布局模型 (Flow Based Layout). 浏览器会把HTML解析成DOM,把CSS解析成CSSOM,DOM和CSSOM合并就产生了 ...

  9. request.headers.get头部获取内容的缺失

    1.说明 今天遇到了一个小坑,在做权限控制的时候,用头部传递了参数取名为table_privilege_id, 在本地测试的时候是可以接到这个参数的,但是通过ngxin转发之后,奇怪了,怎么也拿不到这 ...

  10. 反转链表(剑指offer-15)

    方法1:递归 /* public class ListNode { int val; ListNode next = null; ListNode(int val) { this.val = val; ...