【UOJ#242】【UR#16】破坏蛋糕(计算几何)

题面

UOJ

题解

为了方便,我们假定最后一条直线是从上往下穿过来的,比如说把它当成坐标系的\(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】破坏蛋糕(计算几何)的更多相关文章

  1. [UOJ UR#16]破坏发射台

    来自FallDream的博客,未经允许,请勿转载,谢谢. 传送门 先考虑n是奇数的情况,很容易想到一个dp,f[i][0/1]表示转移到第i个数,第i个数是不是第一个数的方案数,然后用矩阵乘法优化一下 ...

  2. UOJ 241. 【UR #16】破坏发射台 [矩阵乘法]

    UOJ 241. [UR #16]破坏发射台 题意:长度为 n 的环,每个点染色,有 m 种颜色,要求相邻相对不能同色,求方案数.(定义两个点相对为去掉这两个点后环能被分成相同大小的两段) 只想到一个 ...

  3. uoj #242【UR #16】破坏蛋糕

    uoj 考虑把那最后一条直线拎出来,并且旋转到和\(y\)轴平行(其他直线同时一起旋转),然后它和其他直线相交形成\(n+1\)个区间,现在要知道这些区间是否处在一个面积有限的区域 可以发现一段在有限 ...

  4. A. 【UR #16】破坏发射台

    题解: 首先看n是偶数的 那么就是不需要满足对面这个性质的 这样就可以dp了 f[i][0/1]表示dp到第i位,当前数等于或不等于第一位的方案数 然后显然可以用矩阵优化 再考虑n为奇数 用一样的思路 ...

  5. UOJ #277 BZOJ 4739 定向越野 (计算几何、最短路)

    手动博客搬家: 本文发表于20181208 14:39:01, 原地址https://blog.csdn.net/suncongbo/article/details/84891710 哇它居然显示出图 ...

  6. UOJ 【UR #5】怎样跑得更快

    [UOJ#62]怎样跑得更快 题面 这个题让人有高斯消元的冲动,但肯定是不行的. 这个题算是莫比乌斯反演的一个非常巧妙的应用(不看题解不会做). 套路1: 因为\(b(i)\)能表达成一系列\(x(i ...

  7. UOJ #22 UR #1 外星人

    LINK:#22. UR #1 外星人 给出n个正整数数 一个初值x x要逐个对这些数字取模 问怎样排列使得最终结果最大 使结果最大的方案数又多少种? n<=1000,x<=5000. 考 ...

  8. UOJ.52.[UR #4]元旦激光炮(交互 思路)

    题目链接 \(Description\) 交互库中有三个排好序的,长度分别为\(n_a,n_b,n_c\)的数组\(a,b,c\).你需要求出所有元素中第\(k\)小的数.你可以调用至多\(100\) ...

  9. UOJ【UR #12】实验室外的攻防战

    题意: 给出一个排列$A$,问是否能够经过以下若干次变换变为排列$B$ 变换:若${A_i> A_i+1}$,可以${swap(A_i,A_i+1)}$ 考虑一个数字从A排列到B排列连出来的路径 ...

随机推荐

  1. Flask的session

    ### session:1. session的基本概念:session和cookie的作用有点类似,都是为了存储用户相关的信息.不同的是,cookie是存储在本地浏览器,session是一个思路.一个 ...

  2. ASP.NET Core on K8S深入学习(6)Health Check

    本篇已加入<.NET Core on K8S学习实践系列文章索引>,可以点击查看更多容器化技术相关系列文章. 一.关于K8S中的Health Check 所谓Health Check,就是 ...

  3. C语言结构选择语句

    总结一下常用的if else与switch,其中switch中的break知识点是笔试题经常考到的内容. if else与else if 在C语言中,经常使用if else选择语句,来实现很多对应的功 ...

  4. idea实战技巧

    一.背景 为什么想写这个,因为编码一线更多的是实战,实战中,可能一个快捷键,一个小技巧,就能省很多时间. 本文会持续记录,持续更新. 二.技巧 1.全局替换(带正则) 场景是: 多profile的情况 ...

  5. java架构之路(Sharding JDBC)mysql5.7yum安装和主从

    安装mysql5.7单机 1.获取安装yum包 [root@iZm5e7sz135n16ua2rmbk6Z local]# wget http://dev.mysql.com/get/mysql57- ...

  6. 什么是BGP协议

    Border Gateway Protocol,边界网关协议,简称BGP,主要用于互联网AS(自治系统)之间的互联. Linux内核原生支持的.专门用在大规模数据中心维护不同的"自治系统&q ...

  7. java基础(5):流程控制语句(switch)、数组

    1. 流程控制语句(续) 1.1 选择结构switch switch 条件语句也是一种很常用的选择语句,它和if条件语句不同,它只能针对某个表达式的值作出判断,从而决定程序执行哪一段代码.例如,在程序 ...

  8. 用 Python 实现植物大战僵尸代码!

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者: marble_xu GitHub地址:https://github ...

  9. 最小割最大流定理&残量网络的性质

    最小割最大流定理的内容: 对于一个网络流图 $G=(V,E)$,其中有源点和汇点,那么下面三个条件是等价的: 流$f$是图$G$的最大流 残量网络$G_f$不存在增广路 对于$G$的某一个割$(S,T ...

  10. volatile简记

    volatile指出变量随时可能发生变化,与该变量有关的运算,不要进行编译优化,以免出错,也就是在使用变量时必须从它的地址中重新读取.