题解

一道想法很简单的计算几何(由于我半平面交总是写不对,我理所当然的怀疑半平面交错了,事实上是我直线建错了)

首先我们对于两个凸包上的点设为\((x_0,y_0)\)和\((x_1,y_1)\)(逆时针)

设这个点为(x,y)我们用叉积求一下面积

可以得到

\((x_0 - x)(y_1 - y) - (x_1 - x)(y_0 - y)\)

\(x_0 y_1 - x_1 y_0 + (y_0 - y_1)x + (x_1 - x_0)y\)

然后我们可以对于每个小三角形都求一个这样的式子,我们的约束就是(x,y),P_0 P_1的三角形面积最小

最后会得到一个

\(Ax + By + C <= 0\)的式子

然后我们就可以建出直线来半平面交了,把x和C移到一边,讨论一下A是0或者B是0,然后讨论一下B的正负

半平面交求出来的凸包面积除以原凸包面积就是答案了

代码

#include <bits/stdc++.h>
#define MAXN 100005
//#define ivorysi
#define enter putchar('\n')
#define space putchar(' ')
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define eps 1e-8
#define pii pair<int,int>
using namespace std;
typedef long long int64;
typedef double db;
template<class T>
void read(T &res) {
res = 0;char c = getchar();T f = 1;
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
res = res * 10 + c - '0';
c = getchar();
}
res *= f;
}
template<class T>
void out(T x) {
if(x < 0) {putchar('-');x = -x;}
if(x >= 10) {
out(x / 10);
}
putchar('0' + x % 10);
}
bool dcmp(db a,db b) {
return fabs(a - b) < eps;
}
bool Gter(db a,db b) {
return a > b + eps;
}
int N,tot;
struct Point {
db x,y;
Point(){}
Point(db _x,db _y) {
x = _x;y = _y;
}
friend Point operator + (const Point &a,const Point &b) {
return Point(a.x + b.x,a.y + b.y);
}
friend Point operator - (const Point &a,const Point &b) {
return Point(a.x - b.x,a.y - b.y);
}
friend Point operator * (const Point &a,const db &d) {
return Point(a.x * d,a.y * d);
}
friend Point operator / (const Point &a,const db &d) {
return Point(a.x / d,a.y / d);
}
friend db operator * (const Point &a,const Point &b) {
return a.x * b.y - a.y * b.x;
}
friend db dot(const Point &a,const Point &b) {
return a.x * b.x + a.y * b.y;
}
}P[MAXN];
struct Seg {
Point a,b;
db d;
Seg(){}
Seg(Point _a,Point _b) {
a = _a;b = _b;d = atan2(b.y - a.y,b.x - a.x);
}
friend Point Cross_Point(const Seg &s,const Seg &t) {
db S1 = (s.a - t.a) * (t.b - t.a);
db S2 = (s.b - t.b) * (t.a - t.b);
return s.a + (s.b - s.a) * (S1 / (S1 + S2));
}
}S[MAXN * 4];
bool cmp(Seg s,Seg t) {
return Gter(t.d,s.d);
}
Point p[MAXN * 4];
Seg q[MAXN];
int ql,qr;
void Process() {
ql = 1,qr = 0;
for(int i = 1 ; i <= tot ; ++i) {
while(ql < qr) {
if(Gter(0.0,(S[i].b - S[i].a) * (p[qr - 1] - S[i].a))) --qr;
else break;
}
while(ql < qr) {
if(Gter(0.0,(S[i].b - S[i].a) * (p[ql] - S[i].a))) ++ql;
else break;
}
q[++qr] = S[i];
if(ql < qr) {
if(dcmp(q[qr].d,q[qr - 1].d)) {
if(Gter((q[qr].b - q[qr].a) * (q[qr - 1].a - q[qr].a),0.0)) --qr;
else q[qr - 1] = q[qr],--qr;
}
}
if(ql < qr) p[qr - 1] = Cross_Point(q[qr],q[qr - 1]);
}
while(ql < qr) {
if(Gter(0.0,(q[ql].b - q[ql].a) * (p[qr - 1] - q[ql].a))) --qr;
else break;
}
p[qr] = Cross_Point(q[qr],q[ql]);
if(qr - ql + 1 >= 3) {
db res = 0.0,s = 0.0;
p[qr + 1] = p[ql];
for(int i = ql ; i <= qr ; ++i) {
res += p[i] * p[i + 1];
}
for(int i = 0 ; i < N ; ++i) {
s += P[i] * P[i + 1];
}
printf("%.4lf\n",res / s);
}
else puts("0.0000");
}
void Solve() {
read(N);
db x,y;
for(int i = 0 ; i < N ; ++i) {
scanf("%lf%lf",&x,&y);
P[i] = Point(x,y);
}
P[N] = P[0];
for(int i = 0 ; i < N ; ++i) {
S[++tot] = Seg(P[i],P[i + 1]);
}
db C0 = P[0] * P[1],A0 = P[0].y - P[1].y,B0 = P[1].x - P[0].x;
for(int i = 1 ; i < N ; ++i) {
db A = A0 - (P[i].y - P[i + 1].y);
db B = B0 - (P[i + 1].x - P[i].x);
db C = C0 - P[i] * P[i + 1];
if(dcmp(A,0.0) && dcmp(B,0.0) && Gter(C,0.0)) {puts("0.0000");return;}
if(dcmp(A,0.0)) {
if(Gter(B,0.0)) S[++tot] = Seg(Point(10,-C / B),Point(-10,-C / B));
else S[++tot] = Seg(Point(-10,-C / B),Point(10,-C / B));
}
else if(dcmp(B,0.0)) {
if(Gter(A,0.0)) S[++tot] = Seg(Point(-C / A,-10),Point(-C / A,10));
else S[++tot] = Seg(Point(-C / A,10),Point(-C / A,-10));
}
else {
A = -A / B,C = -C / B;
if(Gter(B,0.0)) S[++tot] = Seg(Point(10,A * 10 + C),Point(-10,-A * 10 + C));
else S[++tot] = Seg(Point(-10,-A * 10 + C),Point(10,A * 10 + C));
}
}
sort(S + 1,S + tot + 1,cmp);
Process();
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Solve();
return 0;
}

【LOJ】 #2008. 「SCOI2015」小凸想跑步的更多相关文章

  1. loj #2008. 「SCOI2015」小凸想跑步

    #2008. 「SCOI2015」小凸想跑步   题目描述 小凸晚上喜欢到操场跑步,今天他跑完两圈之后,他玩起了这样一个游戏. 操场是个凸 n nn 边形,N NN 个顶点按照逆时针从 0∼n−1 0 ...

  2. 「SCOI2015」小凸想跑步 解题报告

    「SCOI2015」小凸想跑步 最开始以为和多边形的重心有关,后来发现多边形的重心没啥好玩的性质 实际上你把面积小于的不等式列出来,发现是一次的,那么就可以半平面交了 Code: #include & ...

  3. loj#2009.「SCOI2015」小凸玩密室

    题目链接 loj#2009. 「SCOI2015」小凸玩密室 题解 树高不会很高<=20 点亮灯泡x,点亮x的一个子树,再点亮x另外的子树, 然后回到x的父节点,点亮父节点之后再点亮父节点的其他 ...

  4. loj #2006. 「SCOI2015」小凸玩矩阵

    #2006. 「SCOI2015」小凸玩矩阵   题目描述 小凸和小方是好朋友,小方给小凸一个 N×M N \times MN×M(N≤M N \leq MN≤M)的矩阵 A AA,要求小凸从其中选出 ...

  5. LibreOJ #2006. 「SCOI2015」小凸玩矩阵 二分答案+二分匹配

    #2006. 「SCOI2015」小凸玩矩阵 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据   题目描述 ...

  6. 「SCOI2015」小凸解密码 解题报告

    「SCOI2015」小凸解密码 题意:给一个环,定义一段连续的极长\(0\)串为\(0\)区间,定义一个位置的离一个\(0\)区间的距离为这个位置离这个区间中\(0\)的距离的最小值,每次询问一个位置 ...

  7. 「SCOI2015」小凸玩矩阵 解题报告

    「SCOI2015」小凸玩矩阵 我好沙茶啊 把点当边连接行和列,在外面二分答案跑图的匹配就行了 我最开始二分方向搞反了,样例没过. 脑袋一抽,这绝壁要费用流,连忙打了个KM 然后wa了,一想这个不是完 ...

  8. 「SCOI2015」小凸玩密室 解题报告

    「SCOI2015」小凸玩密室 虽然有心里在想一些奇奇怪怪的事情的原因,不过还是写太久了.. 不过这个题本身也挺厉害的 注意第一个被点亮的是任意选的,我最开始压根没注意到 \(dp_{i,j}\)代表 ...

  9. AC日记——「SCOI2015」小凸玩矩阵 LiBreOJ 2006

    「SCOI2015」小凸玩矩阵 思路: 二分+最大流: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 300 ...

随机推荐

  1. 微信小程序语音识别

    语音识别现在已经发展的很成熟了,经过比对发现百度对开发者比较友好,提供很多种语言的SDK,对python来说直接安装 pip install baidu-aip 文档写的也不错  具体参考:http: ...

  2. react UI组件库 Salt UI

    https://salt-ui.github.io/?spm=a219a.7629140.0.0.JWztQO

  3. ⑦ 设计模式的艺术-13.代理(Proxy)模式

    为什么需要代理模式 中介隔离作用:在某些情况下,一个客户类不想或者不能直接引用一个委托对象,而代理类对象可以在客户类和委托对象之间起到中介的作用,其特征是代理类和委托类实现相同的接口. 开闭原则,增加 ...

  4. Map集合的两种取出方式

    Map集合有两种取出方式, 1.keySet:将Map中的键存入Set集合,利用set的迭代器来处理所有的键 举例代码如下: import java.util.*; class Test { publ ...

  5. 集合框架小结-List

    List集合存储的元素是有序的,可重复的,有索引 List特有方法: 增加 add(index, element); addAll(index, Collection); 删除 remove(inde ...

  6. 【Codeforces811E】Vladik and Entertaining Flags [线段树][并查集]

    Vladik and Entertaining Flags Time Limit: 20 Sec  Memory Limit: 512 MB Description n * m的矩形,每个格子上有一个 ...

  7. 去除IE10+上文本框巨丑无比的删除图标以及显示密码图标

    去除IE10+上文本框巨丑无比的删除图标以及显示密码图标 IE浏览器总是让人喜欢让人厌,在最新的IE浏览器(IE10+)上使用表单时,文本框内后面会出现很巨丑无比的“删除图标”以及“显示密码图标”,如 ...

  8. jQuery()方法的第二个参数详解

    关于jQuery()方法的第二个参数,有下面这几种用法: 1.jQuery(selector, [context]) 这种用法,相当于 $(context).find(selector) 或者 con ...

  9. MacOS Safari 中 button 不能使用 text-gradient

    @mixin text-gradient ($deg: 90deg, $from: $gradientFrom, $to: $gradientEnd) { background-image: line ...

  10. 用ELK搭建简单的日志收集分析系统【转】

    缘起 在微服务开发过程中,一般都会利用多台服务器做分布式部署,如何能够把分散在各个服务器中的日志归集起来做分析处理,是一个微服务服务需要考虑的一个因素. 搭建一个日志系统 搭建一个日志系统需要考虑一下 ...