【UOJ#242】【UR#16】破坏蛋糕(计算几何)
【UOJ#242】【UR#16】破坏蛋糕(计算几何)
题面
题解
为了方便,我们假定最后一条直线是从上往下穿过来的,比如说把它当成坐标系的\(y\)轴。
于是我们可以处理出所有交点,然后把它们从上往下排序。
相邻的两个点就构成了一个相交的平面(可以认为正无穷和负无穷位置还有一个点)
那么,这个区间是有限的,当且仅当过这个两点的直线在左侧都还能找到一个交点,在右侧也还能找到一个交点。
于是考虑怎么找交点,两侧基本等价,所以拆开考虑,比如考虑右侧。
我们从上往下依次扫每一个过每一个交点的直线,如果在这条直线上方存在一条直线,满足斜率小于这条直线,那么就会和这条直线有交,于是我们可以维护一些斜率的单调栈,每次二分一段区间,找到最靠上的那个,那么这一段区间内的所有点的右侧都是封闭的,差分一下就可以知道所有点的情况;左侧的情况是类似的。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;
#define ll long long
#define MAX 100100
const double Pi=acos(-1),eps=1e-7;
inline int read()
{
int x=0;bool t=false;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
struct Node{double x,y;}G[MAX];
double Len(Node a){return sqrt(a.x*a.x+a.y*a.y);}
Node operator+(Node a,Node b){return (Node){a.x+b.x,a.y+b.y};}
Node operator-(Node a,Node b){return (Node){a.x-b.x,a.y-b.y};}
Node operator*(Node a,double b){return (Node){a.x*b,a.y*b};}
double Cross(Node a,Node b){return a.x*b.y-a.y*b.x;}
struct Line{Node p,v;}L[MAX],pL[MAX];
Node Intersection(Line a,Line b)
{
Node c=b.p-a.p;
double t=Cross(b.v,c)/Cross(b.v,a.v);
return a.p+a.v*t;
}
bool Parallel(Line a,Line b){return fabs(Cross(a.v,b.v))<1e-9;}
Node Turn(Node a,double alp){return (Node){a.x*cos(alp)-a.y*sin(alp),a.x*sin(alp)+a.y*cos(alp)};}
int n,id[MAX];double K[MAX];
bool cmpid(int a,int b){return G[a].y>G[b].y;}
int St[MAX],cl[MAX],cr[MAX];
double ang[MAX];
int main()
{
n=read();
for(int i=1;i<=n+1;++i)
{
double x1=read(),y1=read(),x2=read(),y2=read();
L[i].p=(Node){x1,y1};L[i].v=(Node){x2,y2};
L[i].v=L[i].v-L[i].p;pL[i]=L[i];
}
double alpha=Pi/2-atan2(L[n+1].v.y,L[n+1].v.x);
for(int i=1;i<=n+1;++i)L[i].p=Turn(L[i].p,alpha);
for(int i=1;i<=n+1;++i)L[i].v=Turn(L[i].v,alpha);
for(int i=1;i<=n+1;++i)L[i].p=L[i].p-L[n+1].p;
for(int i=1;i<=n;++i)K[i]=L[i].v.y/L[i].v.x;
for(int i=1;i<=n;++i)G[i]=(Node){0,L[i].p.y-K[i]*L[i].p.x};
for(int i=1;i<=n;++i)id[i]=i;
sort(&id[1],&id[n+1],cmpid);
for(int i=1,top=0;i<=n;++i)
{
int x=id[i],l=1,r=top,ret=0;
while(l<=r)
{
int mid=(l+r)>>1;
if(K[x]>K[id[St[mid]]]&&!Parallel(pL[x],pL[id[St[mid]]]))ret=mid,r=mid-1;
else l=mid+1;
}
if(ret)cl[St[ret]]++,cl[i]--;
else St[++top]=i;
}
for(int i=1,top=0;i<=n;++i)
{
int x=id[i],l=1,r=top,ret=0;
while(l<=r)
{
int mid=(l+r)>>1;
if(K[x]<K[id[St[mid]]]&&!Parallel(pL[x],pL[id[St[mid]]]))ret=mid,r=mid-1;
else l=mid+1;
}
if(ret)cr[St[ret]]++,cr[i]--;
else St[++top]=i;
}
for(int i=1;i<=n;++i)cl[i]+=cl[i-1],cr[i]+=cr[i-1];cl[n+1]=cr[n+1]=0;
for(int i=n;~i;--i)
if(cl[i]&&cr[i])putchar(49);
else putchar(48);
return 0;
}
【UOJ#242】【UR#16】破坏蛋糕(计算几何)的更多相关文章
- [UOJ UR#16]破坏发射台
来自FallDream的博客,未经允许,请勿转载,谢谢. 传送门 先考虑n是奇数的情况,很容易想到一个dp,f[i][0/1]表示转移到第i个数,第i个数是不是第一个数的方案数,然后用矩阵乘法优化一下 ...
- UOJ 241. 【UR #16】破坏发射台 [矩阵乘法]
UOJ 241. [UR #16]破坏发射台 题意:长度为 n 的环,每个点染色,有 m 种颜色,要求相邻相对不能同色,求方案数.(定义两个点相对为去掉这两个点后环能被分成相同大小的两段) 只想到一个 ...
- uoj #242【UR #16】破坏蛋糕
uoj 考虑把那最后一条直线拎出来,并且旋转到和\(y\)轴平行(其他直线同时一起旋转),然后它和其他直线相交形成\(n+1\)个区间,现在要知道这些区间是否处在一个面积有限的区域 可以发现一段在有限 ...
- A. 【UR #16】破坏发射台
题解: 首先看n是偶数的 那么就是不需要满足对面这个性质的 这样就可以dp了 f[i][0/1]表示dp到第i位,当前数等于或不等于第一位的方案数 然后显然可以用矩阵优化 再考虑n为奇数 用一样的思路 ...
- UOJ #277 BZOJ 4739 定向越野 (计算几何、最短路)
手动博客搬家: 本文发表于20181208 14:39:01, 原地址https://blog.csdn.net/suncongbo/article/details/84891710 哇它居然显示出图 ...
- UOJ 【UR #5】怎样跑得更快
[UOJ#62]怎样跑得更快 题面 这个题让人有高斯消元的冲动,但肯定是不行的. 这个题算是莫比乌斯反演的一个非常巧妙的应用(不看题解不会做). 套路1: 因为\(b(i)\)能表达成一系列\(x(i ...
- UOJ #22 UR #1 外星人
LINK:#22. UR #1 外星人 给出n个正整数数 一个初值x x要逐个对这些数字取模 问怎样排列使得最终结果最大 使结果最大的方案数又多少种? n<=1000,x<=5000. 考 ...
- UOJ.52.[UR #4]元旦激光炮(交互 思路)
题目链接 \(Description\) 交互库中有三个排好序的,长度分别为\(n_a,n_b,n_c\)的数组\(a,b,c\).你需要求出所有元素中第\(k\)小的数.你可以调用至多\(100\) ...
- UOJ【UR #12】实验室外的攻防战
题意: 给出一个排列$A$,问是否能够经过以下若干次变换变为排列$B$ 变换:若${A_i> A_i+1}$,可以${swap(A_i,A_i+1)}$ 考虑一个数字从A排列到B排列连出来的路径 ...
随机推荐
- JS原型链与instanceof底层原理
一.问题: instanceof 可以判断一个引用是否属于某构造函数: 另外,还可以在继承关系中用来判断一个实例是否属于它的父类型. 老师说:instanceof的判断逻辑是: 从当前引用的proto ...
- docker工具之基本命令
docker工具之基本命令 1.docker服务的启动.停止.重启 systemctl start docker #启动docker服务 systemctl daemon-reload #守护进程重启 ...
- 菜鸟刷面试题(三、Redis篇)
目录: redis是什么?都有哪些使用场景? redis有哪些功能? redis和memecache有什么区别? redis为什么是单线程的? 什么是缓存穿透?怎么解决? redis支持的数据类型有哪 ...
- 【使用篇二】SpringBoot使用Druid作为数据源(19)
Druid是一个关系型数据库连接池,它是阿里巴巴的一个开源项目.Druid支持所有JDBC兼容数据库,包括了Oracle.MySQL.PostgreSQL.SQL Server.H2等.Druid在监 ...
- UDP组播
多播(组播) 组播组可以是永久的也可以是临时的.组播组地址中,有一部分由官方分配的,称为永久组播组.永久组播组保持不变的是它的ip地址,组中的成员构成可以发生变化.永久组播组中成员的数量都可以是任意的 ...
- IDEA生成可执行的jar文件
场景 用IDEA开发一个Java控制台程序,项目完成后,打包给客户使用. 做法 首先用IDEA打开要生成jar的项目,打开后选择File->Project Structure... 选择Arti ...
- .NET Core 数据结构与算法 1-1
.NET Core 数据结构与算法 1-1 本节内容为顺序表 简介 线性表是简单.基本.常用的数据结构.线性表是线性结构的抽象 (Abstract),线性结构的特点是结构中的数据元素之间存在一对一的线 ...
- PHP http_response_code 网络函数
定义和用法 http_response_code - 获取/设置响应的 HTTP 状态码 版本支持 PHP4 PHP5 PHP7 不支持 支持 支持 语法 http_response_code ([ ...
- canvas实现七巧板图案和粒子时钟
canvas实现七巧板 <canvas id="canvas" width="800" height="800"></ ...
- Vue的MVVM框架理解
图示 只上图,请不要怪楼主懒. 这是楼主梳理后画的,因为毕竟自己画的印象深刻,更觉得香啊. 黄线: 表示View->Model, 红线: 表示Model->View 具体代码,请查看Vue ...