Description

给出一个N个顶点的简单多边形,对于每个顶点,假如它和原点连成的线段只在这个顶点处和多边形相交,就称为满足要求的顶点。你的任务是输出所有满足要求的顶点编号。

Input

第一行一个正整数N。下面N行每行两个不超过106的正整数,依次表示每个顶点的坐标。顶点按照输入顺序用正整数1..N编号,并且顶点保证按照顺时针或逆时针顺序给出。

Output

第一行一个正整数M,表示满足要求的顶点个数。第二行M个正整数,按照升序给出满足要求的顶点编号。
 
对所有点极角排序并离散化,特判极角相同的情况,建线段树,将所有边插到线段树上,最后查询每个点方向的射线与多边形最近的交点。
按极角做扫描线也可以在相同复杂度内实现,但细节可能更多。
#include<bits/stdc++.h>
typedef long long i64;
int min(int a,int b){return a<b?a:b;}
int max(int a,int b){return a>b?a:b;}
const int N=;
char buf[],*ptr=buf;
int _(){
int x=;
while(*ptr<)++ptr;
while(*ptr>)x=x*+*ptr++-;
return x;
}
struct pos{
double x,y;
double val()const{return x+y;}
}xs[N];
double operator*(pos a,pos b){return a.x*b.y-a.y*b.x;}
pos operator-(pos a,pos b){return (pos){a.x-b.x,a.y-b.y};}
int n;
struct vertex{
pos p;
int id,x;
bool operator<(vertex w)const{
double d=p*w.p;
return d?d<:p.val()<w.p.val();
}
}vs[N];
int ps[N],xp=;
bool un[N];
struct itv{
pos a,b;
int l,r;
double operator()(pos&w)const{
return w.val()*(b*a)/(w*(a-b));
}
}is[];
int mx;
void ins(itv&a,itv&b){
if(!a.r)a=b;
else{
int l=max(a.l,b.l),r=min(a.r,b.r);
if(a(xs[l])+a(xs[r])>b(xs[l])+b(xs[r]))a=b;
}
}
void ins(vertex a,vertex b){
itv w=(itv){a.p,b.p,a.x,b.x};
for(int l=a.x+mx-,r=b.x+mx+;r-l!=;l>>=,r>>=){
if(~l&)ins(is[l^],w);
if(r&)ins(is[r^],w);
}
}
int as[N],ap=;
int main(){
fread(buf,,sizeof(buf),stdin);
n=_();
for(mx=;mx<=n+;mx<<=);
for(int i=;i<=n;++i){
vs[i].p.x=_();
vs[i].p.y=_();
vs[i].id=i;
}
std::sort(vs+,vs+n+);
for(int i=,j=;i<=n;i=j){
for(++j;j<=n&&vs[i].p*vs[j].p==;un[vs[j].id]=,++j);
xs[++xp]=vs[i].p;
for(int k=i;k<j;++k)vs[k].x=xp;
}
for(int i=;i<=n;++i)ps[vs[i].id]=i;
ps[]=ps[n];
for(int i=;i<=n;++i){
int a=ps[i-],b=ps[i];
if(a>b)std::swap(a,b);
if(vs[a].x<vs[b].x)ins(vs[a],vs[b]);
}
for(int i=;i<=n;++i)if(!un[vs[i].id]){
for(int w=vs[i].x+mx;w;w>>=)if(is[w].r&&is[w](vs[i].p)<vs[i].p.val()-1e-){
un[vs[i].id]=;
break;
}
}
for(int i=;i<=n;++i)if(!un[i])as[ap++]=i;
printf("%d\n",ap);
for(int i=;i<ap;++i)printf("%d ",as[i]);
return ;
}

bzoj2856: [ceoi2012]Printed Circuit Board的更多相关文章

  1. Printed Circuit Board (board)

    Printed Circuit Board (board) 题目描述 给出一个N个顶点的简单多边形,对于每个顶点,假如它和原点连成的线段只在这个顶点处和多边形相交,就称为满足要求的顶点.你的任务是输出 ...

  2. ZOJ1648 Circuit Board 2017-04-18 20:31 34人阅读 评论(0) 收藏

    Circuit Board Time Limit: 2 Seconds      Memory Limit: 65536 KB On the circuit board, there are lots ...

  3. ZOJ 1648 Circuit Board(计算几何)

    Circuit Board Time Limit: 2 Seconds Memory Limit: 65536 KB On the circuit board, there are lots of c ...

  4. ZOJ1648 Circuit Board(线段相交)

    裸的判断线段相交

  5. kickstart2019 round_C B. Circuit Board

    思路: 这题应该不止一种解法,其中的一种可以看作是leetcode85https://www.cnblogs.com/wangyiming/p/11059176.html的加强版: 首先对于每一行,分 ...

  6. zoj 1648 Circuit Board

    题目:意思就是推断给定的几条线段是否有相交的. 方法:模版吧,有空在来细细学习. 代码: #include <iostream> #include <cstdio> using ...

  7. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  8. COB(Chip On Board) 工艺技术

    COX(Chip On X) •X 基板:  PCB (Printed circuit board)  FPC (Flexible Printed Circuit)  Glass •导线焊接 球形焊接 ...

  9. 特邀美国EMC实战专家Mark来华授课

    “轻松搞定EMC-PCB和系统设计”课程介绍 本次课程特邀美国EMC领域权威专家Mark Montrose主讲,将涵盖满足产品电磁兼容性和信号完整性的基本原理.课程涉及多个领域,不仅仅针对PCB设计, ...

随机推荐

  1. PTA——念数字

    PTA 7-30 念数字 #include<stdio.h> #include<stdlib.h> #define N 50 int main() { ] = {"l ...

  2. mysql 查询进程和关闭进程

    1.查询某一进程PID号 tasklist |findstr mysqld 2.关闭某一进程 taskkill /F /PID XXXX 3.制作 windows + r键输入services.msc ...

  3. Python学习-终端字体高亮显示1

    Python学习-终端字体高亮显示   1.采用原生转义字符序列,对Windows有的版本不支持(比如win7),完美支持Linux 实现过程: 终端的字符颜色是用转义序列控制的,是文本模式下的系统显 ...

  4. Python下载与安装配置

    最近想学习Python那就开始吧 首先就是下载安装了 Python最新源码,二进制文档,新闻资讯等可以在Python的官网查看到: Python官网:https://www.python.org/ 你 ...

  5. Liunx----vi编辑器

    关于vi编辑器基本的用法总结如下: vi是linux下的一款文编编辑器. 进入vi的方法:在系统启动起来后,直接键入vi或vi 文件名: 进去后输入内容方法:输入a或i,切换到编辑模式: 退出编辑模式 ...

  6. Linux----版本选择

    此文摘自老男孩老师课堂: 下载地址:http://man.linuxde.net/download/

  7. MYSQL 常用函数大全

    1. 数学函数 greatest(x1,x2,...,xn)返回集合中最大的值 least(x1,x2,...,xn) 返回集合中最小的值 rand()返回0到1内的随机值,可以通过提供一个参数(种子 ...

  8. 【BZOJ2154】Crash的数字表格

    算是学会反演了……(其实挺好学的一天就能学会…… 原题: 今天的数学课上,Crash小朋友学习了最小公倍数(Least Common Multiple).对于两个正整数a和b,LCM(a, b)表示能 ...

  9. centos7安装的mysql无法启动(mysql daemon failed to start)

    不知道是什么原因,启动mysql时一直报这个错误,卸载重装mysql也没用 后来看到网上有人说,执行命令mysql_install_db就可以了 一试还真的行

  10. lnmp安装总结

    1.安装准备 建一个目录用于存放各软件包的压缩文件, 如我把我的源码文件都放在了 /software目录下 切换到/software目录下,执行 wget http://dev.mysql.com/g ...