ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【YBT2022寒假Day10 A】圆与连线(平面几何)(树状数组)

2022-02-17 08:32:08  阅读:183  来源: 互联网

标签:平面几何 include int YBT2022 5001 second Day10 Pi first


圆与连线

题目链接:YBT2022寒假Day10 A

题目大意

二维平面上有个圆心在原点的圆,然后有一些在原外的点。
然后问你最多能选多少个点使得两两之间的连边与圆不相交,保证两两连边不会与圆相切。

思路

你考虑对于一个点,那些点跟它相连不会有交。

你画图会发现,做这个点到圆的两个切线,在切线里面的是不行的,在外面的是可以的。

那可以看出那个不可以的部分是两个区间。
看看那个地方的点也做切线,会发现它们两个的区间要么是包含,好么是相离。

那我们就就是要找不是这些的,那就是相交。
那我们发现复杂度是 \(O(n^2)\),那就好搞了,我们枚举一个点作为最左的区间,然后我们找到右边跟它有交的,然后把这些跑一个 LIS 就是它的答案。

然后所有的取最大值在就行了。

代码

#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define INF 0x3f3f3f3f3f3f3f3f

using namespace std;

struct node {
	int x, y;
}f[5001];
pair <double, double> b[5001];
int n, ans, m, x, y;
double r, s[5001];
const double Pi = acos(-1.0);
const double eps = 1e-6;

int g[5001];

void insert(int x, int va) {
	for (; x <= m; x += x & (-x))
		g[x] = max(g[x], va);
}

int query(int x) {
	int re = 0;
	for (; x; x -= x & (-x))
		re = max(re, g[x]);
	return re;
}

int work(int s, int t) {
	memset(g, 0, sizeof(g));
	int re = 0;
	for (int i = s + 1; i <= t; i++) {
		if (f[i].y < f[s].y) continue;
		int x = query(f[i].y - 1) + 1;
		re = max(re, x);
		insert(f[i].y, x);
	}
	return re + 1;
}

int main() {
//	freopen("circle.in", "r", stdin);
//	freopen("circle.out", "w", stdout);
	
	scanf("%d %lf", &n, &r);
	for (int i = 1; i <= n; i++) {
		scanf("%d %d", &x, &y);
		double g = atan2(y, x);
		double d = acos(r / sqrt(x * x + y * y));
		b[i].first = g - d; b[i].second = g + d;
		if (b[i].first < -Pi) b[i].first += 2 * Pi; if (b[i].first >= Pi) b[i].first -= 2 * Pi;
		if (b[i].second < -Pi) b[i].second += 2 * Pi; if (b[i].second >= Pi) b[i].second -= 2 * Pi;
		if (b[i].first > b[i].second) swap(b[i].first, b[i].second);
		s[++m] = b[i].first; s[++m] = b[i].second;
	}
	
	sort(b + 1, b + n + 1);
	sort(s + 1, s + m + 1);
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= m; j++) {
			if (fabs(b[i].first - s[j]) < eps) f[i].x = j;
			if (fabs(b[i].second - s[j]) < eps) f[i].y = j;
		}
	
	for (int i = 1; i <= n; i++) {
		int j = i;
		while (j < n && f[j + 1].x <= f[i].y)
			j++;
		ans = max(ans, work(i, j)); 
	}
	printf("%d", ans);
	
	return 0;
} 

标签:平面几何,include,int,YBT2022,5001,second,Day10,Pi,first
来源: https://www.cnblogs.com/Sakura-TJH/p/YBT2022Day10_A.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有