【扫描线】Gym - 100781G - Goblin Garden Guards

平面上有100000个哥布林和20000个圆,问你不在圆内的哥布林有多少个。

将每个圆从左到右切2r+1次,形成(2r+1)*2个端点,将上端点记作入点,下端点记作出点,再将这些点和那些哥布林一起排序(x第一关键字,y第二关键字,类型(入 哥布林 出)第三关键字),扫一遍就好了。

#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const double EPS=0.00000001;
struct Point{
	int x;
	double y;
	int type;
	Point(const int &x,const double &y,const int &type){
		this->x=x;
		this->y=y;
		this->type=type;
	}
	Point(){}
}p[405*20005+100005];
bool cmp(const Point &a,const Point &b){
	return a.x!=b.x ? a.x<b.x : (fabs(a.y-b.y)>=EPS ? a.y>b.y : a.type<b.type);
}
double sqr(double x){
	return x*x;
}
int n,m,e;
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;++i){
		scanf("%d%lf",&p[i].x,&p[i].y);
		p[i].type=1;
	}
	e=n;
	int x;
	double y,r;
	scanf("%d",&m);
	for(int i=1;i<=m;++i){
		scanf("%d%lf%lf",&x,&y,&r);
		for(int j=x-r;j<=x+r;++j){
			double tmp=r*r-sqr(x-(double)j);
			p[++e]=Point(j,sqrt(tmp)+y,0);
			p[++e]=Point(j,-sqrt(tmp)+y,2);
		}
	}
	sort(p+1,p+e+1,cmp);
	int in=0,ans=0;
	for(int i=1;i<=e;++i){
		if(p[i].type==0){
			++in;
		}
		else if(p[i].type==2){
			--in;
		}
		else{
			if(in==0){
				++ans;
			}
		}
	}
	printf("%d\n",ans);
	return 0;
}
时间: 2025-01-31 06:39:08

【扫描线】Gym - 100781G - Goblin Garden Guards的相关文章

Gym - 100781G Goblin Garden Guards (扫描线)

题意: n 只哥布林,每只哥布林都有一个位置坐标. m 个炮台,每个炮台都有一个位置坐标和一个攻击半径. 如果一个哥布林在任何一个炮台的攻击范围内,都会被杀死. 求最后没有被杀死的哥布林的数量. 这题暴力加一些小小的优化可以爆过去...然后场上并不敢试. 标算是扫描线.炮台攻击范围内的每个横坐标都拉一个扫描线,把线的两端的点和哥布林的点一起加进一个数组. 然后排序,就会发现能被杀死的哥布林的点在一根线的两个端点之间. 直接扫一遍统计答案就可以了.注意存点的数组要开够. 另外就是...排序的时候

Gym 100345J Zen Garden(点与圆公切线问题)

题意:一个x*y的矩形里,给了n个圆,n不超过10,保证圆与圆只有相离或外切两种关系,要求选择一个点,这个点的任意一条射线,都最多只与一个圆相交.射线与圆相交指的是射线与圆有两个交点. 链接: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=162109 (VJ) http://codeforces.com/gym/100345/ (CF J题) 解法:圆不多,暴力可解.枚举两两圆的公切线,打入一个集合L里,再打入矩形的四条

【扫描线】Gym - 101190E - Expect to Wait

假设初始人数为0, 将每个时刻在等待的人数写下来,就是求个和. 如果纵坐标看成人数,横坐标看成时间,就是求个面积. 因为初始人数不一定为零,所以离线后扫描线即可回答所有询问. #include<cstdio> #include<algorithm> using namespace std; typedef long long ll; int n,m,e; struct LINE{ int y,l,id; }ls[200010]; bool cmp(const LINE &a

Gym 100733J Summer Wars 题解:灵活运用扫描线的思想

题意: 给你n个点,m个横着的线段.你能够横移这些线段,可是这些线段的相对位置不能改变.假设一个点,在它的正上方和和正下方都有线段(包含线段的终点).则这个点被视为被"屏蔽".问通过随意平移我们能够遮住最多的点的数量. 解题思路: 首先把全部的点向右平移1000000个单位.然后那些线段位置不变,我们開始平移这些点,这样我们保证点向左移动的距离肯定是一个正数,方便处理. 这样我们仅仅要求出每一个点向左移动的距离后能够满足题目条件的集合W.然后在求出某个距离值在全部的集合中出现最多次数的

Gym 102028J 扫描线/二维差分 + 解方程

题意:有一个二维平面,以及n个操作,每个操作会选择一个矩形,使得这个二维平面的一部分被覆盖.现在你可以取消其中的2个操作,问最少有多少块地方会被覆盖? 思路:官方题解简洁明了,就不细说了:https://codeforces.com/blog/entry/63729. 此处重点记录一下两种做法的巧妙之处. 1:二维差分+解方程 二维差分:假设在矩形[(x1, y1), (x2, y2)]上加一个数,那么在(x1, y1), (x2 + 1, y2 + 1)加1, (x1, y2 + 1), (x

Security Guards (Gym - 101954B)( bfs + 打表 )

题意及思路 题目主要是讲先给出所有guard的位置,再给出所有incidents的位置,求出guard到达每个incident处最小的steps,其中guard每次可以向四周8个方向移动. 思路:对于每个guard使用bfs遍历它周围的点,算出相应的点到它的距离. AC代码 #include<bits/stdc++.h> using namespace std; int N, Q; struct Pla { int x, y; }; int dist[5000+10][5000+10]; in

ACM: Gym 100935B Weird Cryptography - 简单的字符串处理

Weird Cryptography Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Gym 100935B Description standard input/output Khaled was sitting in the garden under an apple tree, suddenly! , well... you should guess what happened, an

Codeforces Gym 100513G G. FacePalm Accounting

G. FacePalm Accounting Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100513/problem/G Description An owner of a small company FacePalm has recently learned that the city authorities plan to offer to small businesses to partic

Codeforces Gym 100513G G. FacePalm Accounting 暴力

G. FacePalm Accounting Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100513/problem/G Description An owner of a small company FacePalm has recently learned that the city authorities plan to offer to small businesses to partic