\(\color{#0066ff}{ 题目描述 }\)

兔子们决定在自己的城堡里安排一些士兵进行防守。

给出 n 个点的坐标,和城堡里一个圆心在原点的圆形的障碍,兔子们希望从中选出 k 个兔子,使得它们两两所在的直线都不与圆相交。

兔子们希望知道最多能选出多少兔子。

\(\color{#0066ff}{输入格式}\)

第一行两个整数 N 和 R, 表示兔子的个数和圆的半径接下来 N 行,每行两个整数 xi 和 yi ,表示第 i 只兔子的坐标

保证每只兔子都严格在障碍外部,且两两的所在的直线不与圆相切。

\(\color{#0066ff}{输出格式}\)

输出一行一个整数, 表示最多能选出多少兔子

\(\color{#0066ff}{输入样例}\)

6 3
0 6
-7 -4
-3 -2
7 -5
-2 3
8 -3

\(\color{#0066ff}{输出样例}\)

4

\(\color{#0066ff}{数据范围与提示}\)

选择第 1, 2, 6, 4 只兔子即可。

  • 对于 10% 的测试数据, 1 ≤ n ≤ 20.
  • 对于 30% 的测试数据, 1 ≤ n ≤ 100.
  • 对于 100% 的测试数据, 1 ≤ n ≤ 2000; 1 ≤ R; xi; yi ≤ 5000.

\(\color{#0066ff}{ 题解 }\)

过每一个点做圆的两条切线,每个点占据了圆上的一段劣弧

不难发现,两个点的连线与圆有交,当且仅当两段劣弧不相离且互补包含,即普通的相交

于是我们开始想办法获得这个劣弧

我们该怎么存储这种东西呢

考虑把环断开,以极角作为链上的数值,强制让线段范围为\([-\pi,\pi]\),对于不在这个范围上的端点,可以直接\(+-2\pi\),显然没影响

那么怎么获得这两个端点值(角度)呢

∠AOB=∠AOC, 因此只要让极角∠AOD加减∠AOB即可获得端点值

然后我们把所有区间按左端点排序

然后枚举每个区间作为选择的起始区间,枚举之后选择的区间,那之后选择的区间要满足左端点小于起始区间右端点,右端点大于起始区间右端点,这样才是相交

我们把这些区间放在数组里,左端点是递增的且一定小于起始区间右端点

那么可以发现,最多选择的数量就是这些区间右端点的最长上升子序列!

于是\(O(n^2logn)\)即可解决本题

#include<bits/stdc++.h>
#define LL long long
LL in() {
char ch; LL x = 0, f = 1;
while(!isdigit(ch = getchar()))(ch == '-') && (f = -f);
for(x = ch ^ 48; isdigit(ch = getchar()); x = (x << 1) + (x << 3) + (ch ^ 48));
return x * f;
}
const int maxn = 2050;
const double pi = acos(-1);
using std::pair;
using std::make_pair;
int n;
double R;
pair<double, double> e[maxn];
int num, ans;
double f[maxn], t[maxn];
int query() {
int len;
if(!num) return 0;
f[len = 1] = t[1];
for(int i = 2; i <= num; i++) {
if(t[i] > f[len]) f[++len] = t[i];
else *std::upper_bound(f + 1, f + len + 1, t[i]) = t[i];
}
return len;
}
int main() {
n = in(), R = in();
double x, y;
for(int i = 1; i <= n; i++) {
x = in(), y = in();
double bt = atan2(y, x);
double len = sqrt(x * x + y * y);
double af = acos(R / len);
x = bt - af, y = bt + af;
while(x <= -pi) x += 2.0 * pi;
while(y > pi) y -= 2.0 * pi;
if(x > y) std::swap(x, y);
e[i] = make_pair(x, y);
}
std::sort(e + 1, e + n + 1);
for(int i = 1; i <= n; i++) {
num = 0;
for(int j = i + 1; j <= n; j++)
if(e[j].first <= e[i].second && e[j].second >= e[i].second)
t[++num] = e[j].second;
ans = std::max(ans, query());
}
printf("%d", ans + 1);
return 0;
}

P3897 [湖南集训]Crazy Rabbit的更多相关文章

  1. 主席树 || 可持久化线段树 || BZOJ 3653: 谈笑风生 || Luogu P3899 [湖南集训]谈笑风生

    题面:P3899 [湖南集训]谈笑风生 题解: 我很喜欢这道题. 因为A是给定的,所以实质是求二元组的个数.我们以A(即给定的P)作为基点寻找答案,那么情况分两类.一种是B为A的父亲,另一种是A为B的 ...

  2. P3900 [湖南集训]图样图森破

    P3900 [湖南集训]图样图森破 链接 分析: 感觉像个暴力. 可以枚举回文串的回文中心,即枚举一个串,枚举一个串的位置作为回文中心,然后求出这个串内的回文串的长度. 此时如果回文串两端都没有到这个 ...

  3. 【BZOJ4660】Crazy Rabbit 结论+DP

    [BZOJ4660]Crazy Rabbit Description 兔子们决定在自己的城堡里安排一些士兵进行防守.给出 n 个点的坐标,和城堡里一个圆心在原点的圆形的障碍,兔子们希望从中选出 k 个 ...

  4. 三倍经验——bzoj3663、4660、4206 Crazy Rabbit/最大团

    题目描述: 3663 4660 4206 题解: 第一眼:不成立的互相连边,然后用网络流求解无向图最小点覆盖! 好吧我不会. 正解: 每个点对应圆上的一段圆弧,长这样: 设对应圆弧$(l,r)$. 若 ...

  5. bzoj 3653 [湖南集训]谈笑风生

    题目描述 设 T 为一棵有根树,我们做如下的定义: • 设 a 和 b 为 T 中的两个不同节点.如果 a 是 b 的祖先,那么称"a 比 b 不知道高明到哪里去了". • 设 a ...

  6. luogu P3899 [湖南集训]谈笑风生

    传送门 nmyzd,mgdhls,bnmbzdgdnlql,a,wgttxfs 对于一个点\(a\),点\(b\)只有可能是他的祖先或者在\(a\)子树里 如果点\(b\)是\(a\)祖先,那么答案为 ...

  7. 洛谷P3899 [湖南集训]谈笑风生(线段树合并)

    题意 题目链接 Sol 线段树合并板子题,目前我看到两种写法,分别是这样的. 前一种每次需要新建一个节点,空间是\(O(4nlogn)\) 后者不需要新建,空间是\(O(nlogn)\)(面向数据算空 ...

  8. P3899 [湖南集训]谈笑风生

    题目链接 https://www.lydsy.com/JudgeOnline/problem.php?id=3653 https://www.luogu.org/problemnew/show/P38 ...

  9. bzoj 4660 Crazy Rabbit——LIS解决“相交”限制的思想

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4660 想到一个点可以用它与圆的两个切点表示.并想到可以把切点极角排序,那么就变成环上的一些区 ...

随机推荐

  1. mycat 新增分片和字符集

    执行 select * from travelrecord ,分析Debug日志,说明整个执行逻辑,包括连接获取,连接同步信息,数据合并,数据返回,连接释放 新增一个分片表 T_VOTE (ID,PR ...

  2. MySQL binlog 自动备份脚本

    MySQL binlog 自动备份脚本 1 利用shell进行备份 #!/bin/sh #mysql binlog backup script /usr/local/mysql/bin/mysqlad ...

  3. c语言-单链表(二)

    继续复习链表知识点,本章包含单链表的增加,删除,判断是否为空,和链表长度,以及链表的排序 几个知识点 1.链表的判断是否为空 //1.判断链表是否为空 bool isempty_list(PNODE ...

  4. 2015.3.31不使用debug/X86文件夹方式解决64/32位问题

    传统方法:在解决方案-配置管理器-新建X86平台可以解决32位兼容问题,但是Debug目录下会多出X86文件夹.不方便 另一种方法:在项目名称-属性-生成-目标平台-x86也能解决问题,而且不出现X8 ...

  5. FFmpeg结构体:AVInputFormat

    1.描述 AVInputFormat 是类似COM 接口的数据结构,表示输入文件容器格式,着重于功能函数,一种文件容器格式对应一个AVInputFormat 结构,在程序运行时有多个实例,位于avof ...

  6. oracle 启动停止过程

    oracle 主要由两部分组成:instance和database .instance是指一组后台进程/线程和一块共享内存区域,而database是指存储在磁盘上的一组物理文件. 数据库启动包括三个步 ...

  7. doker 笔记(1) 架构

    Docker 的核心组件包括: Docker 客户端 - Client Docker 服务器 - Docker daemon Docker 镜像 - Image Registry Docker 容器 ...

  8. solr的copyFeild用法(改变各个feild的权重,修改打分结果)-注意!

    copyField的dest字段all本身有分析器处理:假设为mmseg4j name,title,description三个字段都复制到all字段上:其中title和description都是mms ...

  9. day17 10.jdbc的crud操作

    每次都是注册驱动,获取连接,然后执行.每次都写很累,肯定能抽取出来一些东西.Java里面是这样的,相同的东西可以抽取做成一个方法.用的时候调这方法就OK了.这方法抽取到什么程度呢? package c ...

  10. css3(border-radius)边框圆角详解(转)

    css3(border-radius)边框圆角详解 (2014-05-19 16:16:29) 转载▼ 标签: divcss html it css3 分类: 网页技术 传统的圆角生成方案,必须使用多 ...