首页 > 其他分享 >P4288 [SHOI2014]信号增幅仪 题解

P4288 [SHOI2014]信号增幅仪 题解

时间:2023-05-25 22:14:14浏览次数:48  
标签:ch int 题解 long 椭圆 double SHOI2014 P4288 define

感谢审核人

Description

给定 \(n\) 个点,椭圆长轴的方向 \(a\) 和放大倍数 \(p\),求覆盖全部点的最小椭圆的半短轴长度。

Solution

让我们求最小覆盖椭圆,但是椭圆不具有什么好的性质,我们可以把椭圆转化成圆来做,这样,题目就转化成了最小覆盖圆,这个用随机增量法来做就可以了。

接下来我们考虑如何转化成圆。

首先从长轴方向 \(a\) 入手,因为斜着求椭圆显然很麻烦,我们可以把它旋转到 \(x\) 轴的方向,将 \(x\) 轴逆时针旋转 \(a\) 度与长轴重合显然也很麻烦,我们考虑等价操作:逆时针旋转坐标轴 \(a\) 度,就等于顺时针旋转每个点 \(a\) 度,因为本题只考虑半短轴的长度,所以坐标位置不用考虑,因此这两个操作等价。

接下来考虑怎么把椭圆转换成圆,这个相对来说好想一点,因为题目中扩大了 \(x\) 坐标 \(p\) 倍,所以说我们只需要把每个点的横坐标变成原来的 \(\frac{1}{p}\) 即可,这样我们就把一个椭圆转化成圆了。

最后套一个随机增量法求最小圆覆盖即可。不会的可以看看这一道题

Code

#include<bits/stdc++.h>
//#define int long long
#define ll long long
#define next nxt
#define re register
#define il inline
const int N = 5e4 + 5;
const double eps = 1e-6;
const double Pi = acos(-1.0);
using namespace std;

struct Point{
	double x,y;
}p[N];
struct Circle{
	Point p; double r;
}C;
struct Line{
	Point s,t;
}u,v;
int n; double a,b;

il int read()
{
	int f=0,s=0;
	char ch=getchar();
	for(;!isdigit(ch);ch=getchar()) f |= (ch=='-');
	for(; isdigit(ch);ch=getchar()) s = (s<<1) + (s<<3) + (ch^48);
	return f ? -s : s;
}

Point operator +(Point a,Point b) { return Point{a.x+b.x,a.y+b.y}; }//加

Point operator -(Point a,Point b) { return Point{a.x-b.x,a.y-b.y}; }//减

Point operator *(Point a,double t) { return Point{t * a.x,t * a.y}; }//数乘

Point operator /(Point a,double t) { return Point{a.x / t,a.y / t}; }//数除

il double operator *(Point a,Point b) { return a.x*b.y - a.y*b.x; }//叉积

il double operator &(Point a,Point b) { return a.x*b.x + a.y*b.y; }//点积

il double dis(Point a,Point b) { return sqrt((b-a)&(b-a)); }

Point GetNode(Point a,Point u,Point b,Point v)//求交点
{
	double t = (a-b)*v / (v*u);
	return a + u*t;
}

Point rotate(Point a,double b) { return Point{a.x*cos(b)-a.y*sin(b),a.y*cos(b)+a.x*sin(b)}; }

Line Midperp(Point a,Point b) { return Line{(a+b)/2,rotate(b-a,Pi/2)}; }//找中垂线

Circle cover(Point a,Point b) { return Circle{(a+b)/2,dis(a,b)/2}; }//覆盖两个点的最小圆就在他俩中点上

Circle cover(Point a,Point b,Point c)//三个点的圆,找中垂线的交点,即为答案
{
	u = Midperp(a,b) , v = Midperp(a,c);
	Point p = GetNode(u.s,u.t,v.s,v.t);
	return Circle{p,dis(p,a)};
}

il void Random_Increment()
{
	C = {p[1] , 0};
	for(re int i=2;i<=n;i++)
	{
		if(C.r < dis(C.p,p[i]))
		{
			C = {p[i] , 0};//一点圆
			for(re int j=1;j<i;j++)
			{
				if(C.r < dis(C.p,p[j]))//两点圆
				{
					C = cover(p[i],p[j]);
					for(re int k=1;k<j;k++)
					{
						if(C.r < dis(C.p,p[k]))//三点确定一个圆,可以证明这个复杂度是均摊O(n)的
							C = cover(p[i],p[j],p[k]);
					}
				}
			}
		}
	}
}

signed main()
{
	n = read();
	for(re int i=1;i<=n;i++) scanf("%lf%lf",&p[i].x,&p[i].y);
	scanf("%lf%lf",&a,&b);
	for(re int i=1;i<=n;i++)
	{
		p[i] = rotate(p[i],-a/180*Pi);
		p[i].x /= b;
	}
	random_shuffle(p+1,p+n+1);//随机打乱,保证复杂度
	Random_Increment();
	printf("%.3lf",C.r);
	return 0;
}

复杂度 \(O(n)\),可以通过本题。

标签:ch,int,题解,long,椭圆,double,SHOI2014,P4288,define
From: https://www.cnblogs.com/bloodstalk/p/17433100.html

相关文章

  • UVA10902 Pick-up Sticks 题解
    Description按顺序给出\(n\)个棍子两个端点的坐标。如果后来的棍子与前边的棍子相交,则说后面的把前面的挡住了。问最后有多少个棍子没被挡住。\(n\leq10^5\),且答案不超过\(1000\)。Solution叉积基本运用。定义:\(\overrightarrow{a}\times\overrightarrow{b}=|\over......
  • SP898 Transmitters 题解
    Description给定\(n\)个点的坐标、半圆的半径以及坐标。问半圆怎么放能覆盖最多的点,输出最多个数。Solution计算几何入门题。首先显然距离圆心超过半径的点是一定不会被覆盖的,舍去。再者我们考虑,半圆的放法是有无限多种的,我们要考虑哪些是有用的。我们可以想到,最优的半圆一......
  • P8943 Deception Point 题解
    Description题目给的很详细了。Solution首先\(n\)个点\(n\)条边,我们很容易就想到基环树(比正常的树多了一条边,形成了一个环),不会也没关系,这题跟基环树其实关系不大。首先,我们可以发现题目中说明了这个环不是一个四元及以下的环,这代表着如果\(A\)提前进入了这个环,那么他......
  • [ABC287D] Match or Not 题解
    Description翻译给的很明白了,就是让你判断\(S\)串的前\(x(0\leqx\leq|T|)\)个字符和后\(|T|-x\)个字符组成的字符串和\(T\)串是否相等,其中问号能代替所有字母。Solution很有意思的一道题。首先我们可以知道,如果前\(i-1\)位不能匹配的话,那么第\(i\)位不管它本......
  • P5446 [THUPC2018]绿绿和串串 题解
    Description给定一个串\(S\),要求串\(S\)是串\(R\)经过多次翻转后的前缀。问有多少种初始长度的串\(R\)。串\(R\)翻转的定义是将前\(|R|-1\)个字符倒序排列后,插入到串的最后。如\(\mathrm{aaa}\)翻转后得到\(\mathrm{abcdcba}\)。Solution我们先设以\(i\)为......
  • CF1139E Maximize Mex 题解
    Description\(n\)个学生,\(m\)个社团。每个学生有一个能力值,且仅属于一个社团。这\(d\)天内,每天从\(m\)个社团中选人,使得选出的人的能力值的\(\text{mex}\)最大。每天会有一个人在选人之前退团。\(d,m\leqn\leq5000\)Solution巧妙建图题。首先,我们可以很显然的......
  • P8081 [COCI2011-2012#4] ZIMA 题解
    题意给定一个长度为\(n\)的序列。当连续\(T\)天温度都小于\(0\)时,则称这\(T\)天为一个冰期,冰期来临之前的\(2T\)天都被标记为警示状态.特殊地,如果一个冰期最长,那么它的前\(3T\)天会被标记为警示状态。如果有多个冰期最长,选一个。思路模拟预处理出每个冰期的长......
  • AT2395 [ARC071C] TrBBnsformBBtion 题解
    题目大意有两个只包含\(A\)和\(B\)的字符串,给出两种操作A可以变为BB,B可以变为A;AAA可以消去,BBB也可以消去。思路找规律。这里我们以A为主,将B全部变为A。因为可以无限次操作,那么就代表如果两个字符串可以相等,那么他们就一定能够经过转化后变成同一个字......
  • CF714B Filya and Homework 题解
    题意给定一个长度为\(n\)的数组。我们可以给一些数加上一个\(x\),也可以减去一个\(x\),也可以不加也不减。问:是否存在一个数\(x\),使得这个数组里各个数都相等。思路一道思维题首先考虑,在这个数组中,相同的元素,我们一定是给它做相同的操作,否则一定不相等,根据这个思想,......
  • UVA1514 Piece it together 题解
    图论题还是在于建图题意给定一个长度为\(n\timesm\)的网格图,有的地方是白方块,有的是黑方块,有的啥也没用。给你如下四种\(L\)形方块,询问是否存在方法,让这些方块正好就是给出的图的形状。$L$形方块如下思路二分图首先我们要想,为什么需要二分图:若能拼成,那么就说......