[BZOJ 3564] [SHOI2014] 信号增幅仪 【最小圆覆盖】
题目链接:BZOJ - 3564
题目分析
求最小椭圆覆盖,题目给定了椭圆的长轴与 x 轴正方向的夹角,给定了椭圆长轴与短轴的比值。
那么先将所有点旋转一个角度,使椭圆长轴与 x 轴平行,再将所有点的 x 坐标除以长轴与短轴的比值,然后就直接做最小圆覆盖了。
随机增量法,一定别忘了 random_shuffle 。
代码
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm> using namespace std; #define PI 3.14159265358979323846
#define Vector Point typedef double LF; const int MaxN = 50000 + 5; const LF Eps = 1e-9; int n; LF Alpha, SinA, CosA; struct Point
{
LF x, y; Point() {}
Point(LF a, LF b)
{
x = a; y = b;
} void Rotate(LF SinA, LF CosA)
{
LF tx, ty;
tx = CosA * x - SinA * y;
ty = SinA * x + CosA * y;
x = tx; y = ty;
}
} P[MaxN]; inline LF Sqr(LF x) {return x * x;} inline LF Dis(Point p1, Point p2)
{
return sqrt(Sqr(p1.x - p2.x) + Sqr(p1.y - p2.y));
} Point operator + (Point p1, Point p2) {return Point(p1.x + p2.x, p1.y + p2.y);}
Point operator - (Point p1, Point p2) {return Point(p1.x - p2.x, p1.y - p2.y);}
Point operator * (Point p, LF t) {return Point(p.x * t, p.y * t);}
Point operator / (Point p, LF t) {return Point(p.x / t, p.y / t);} struct Line
{
Point p;
Vector v; Line() {}
Line(Point p1, Point p2)
{
p = p1;
v = p2 - p1;
}
} L1, L2; struct Circle
{
Point o;
LF r; bool InCircle(Point p)
{
return Dis(o, p) <= r + Eps;
}
} C; inline LF Cross(Vector v1, Vector v2)
{
return v1.x * v2.y - v2.x * v1.y;
} Point Intersection(Line l1, Line l2)
{
Vector u = l2.p - l1.p;
LF t = Cross(u, l2.v) / Cross(l1.v, l2.v);
return l1.p + (l1.v * t);
} Vector Turn90(Vector v)
{
return Vector(-v.y, v.x);
} Line Verticle(Point p1, Point p2)
{
Line ret;
ret.p = (p1 + p2) / 2.0;
ret.v = Turn90(p2 - p1);
return ret;
} int main()
{
srand(51405102);
scanf("%d", &n);
int a, b;
for (int i = 1; i <= n; ++i)
{
scanf("%d%d", &a, &b);
P[i] = Point((LF)a, (LF)b);
}
random_shuffle(P + 1, P + n + 1);
int ad, p;
scanf("%d", &ad);
Alpha = (LF)(-ad) / (LF)180 * PI;
SinA = sin(Alpha); CosA = cos(Alpha);
scanf("%d", &p);
for (int i = 1; i <= n; ++i)
{
P[i].Rotate(SinA, CosA);
P[i].x /= (LF)p;
}
C.o = P[1]; C.r = 0;
for (int i = 1; i <= n; ++i)
{
if (C.InCircle(P[i])) continue;
C.o = P[i]; C.r = 0;
for (int j = 1; j < i; ++j)
{
if (C.InCircle(P[j])) continue;
C.o = (P[i] + P[j]) / 2.0;
C.r = Dis(C.o, P[j]);
for (int k = 1; k < j; ++k)
{
if (C.InCircle(P[k])) continue;
L1 = Verticle(P[i], P[k]);
L2 = Verticle(P[j], P[k]);
C.o = Intersection(L1, L2);
C.r = Dis(C.o, P[k]);
}
}
}
printf("%.3lf\n", C.r);
return 0;
}
[BZOJ 3564] [SHOI2014] 信号增幅仪 【最小圆覆盖】的更多相关文章
- BZOJ 3564: [SHOI2014]信号增幅仪 最小圆覆盖
3564: [SHOI2014]信号增幅仪 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=3564 Description 无线网络基站在 ...
- BZOJ 3564: [SHOI2014]信号增幅仪(随机增量法)
如果是个圆的话好办,如果是拉成椭圆呢?直接压回去!!! 然后随机增量法就行了 CODE: #include<cstdio> #include<iostream> #includ ...
- 2018.10.15 bzoj3564: [SHOI2014]信号增幅仪(坐标处理+最小圆覆盖)
传送门 省选考最小圆覆盖? 亦可赛艇(你们什么都没看见) 在大佬的引领下成功做了出来. 就是旋转坐标使椭圆的横轴跟xxx轴平行. 然后压缩横坐标使得其变成一个圆. 然后跑最小覆盖圆就可以了. 注意题目 ...
- 【bzoj3564】 [SHOI2014]信号增幅仪
题目描述: 无线网络基站在理想状况下有效信号覆盖范围是个圆形.而无线基站的功耗与圆的半径的平方成正比. 现给出平面上若干网络用户的位置,请你选择一个合适的位置建设无线基站.... 就在你拿起键盘准备开 ...
- BZOJ3564 : [SHOI2014]信号增幅仪
先把所有点绕原点逆时针旋转(360-a)度,再把所有点横坐标除以放大倍数p,最后用随机增量法求最小圆覆盖即可. 时间复杂度期望$O(n)$ #include<cstdio> #includ ...
- [SHOI2014]信号增幅仪
题目大意: 平面直角坐标系中散落着n个点,一个椭圆的长半轴在对于x轴逆时针旋转α度的角度上,且长半轴是短半轴的k倍. 问短半轴至少要多长才能覆盖所有的点? 思路: 首先把坐标顺时针旋转α度,然后把所有 ...
- 洛谷P4288||bzoj3564 [SHOI2014]信号增幅仪
bzoj3564 洛谷P4288 可以旋转一下坐标轴使得x轴与长轴方向对齐,然后将所有的横坐标变为自身除以放大倍数,然后就做一个最小圆覆盖 #include<cstdio> #includ ...
- 2018.07.04 BZOJ 2823: AHOI2012信号塔(最小圆覆盖)
2823: [AHOI2012]信号塔 Time Limit: 10 Sec Memory Limit: 128 MB Description 在野外训练中,为了确保每位参加集训的成员安全,实时的掌握 ...
- [LOJ 2190] 「SHOI2014」信号增幅仪
[LOJ 2190] 「SHOI2014」信号增幅仪 链接 链接 题解 坐标系直到 \(x\) 轴与椭圆长轴平行 点的坐标变换用旋转公式就可以了 因为是椭圆,所以所有点横坐标除以 \(p\) 然后最小 ...
随机推荐
- 一个类似于QQ语音聊天时的拖拽移动悬浮小球
闲来无事,分享一个最近在某个地方借鉴的一个demo(原谅我真的忘了在哪里看到的了,不然也就贴地址了)这个demo的逻辑思路并不是很难,推敲一下,很快就能理解,只是觉得这样的一个组合控件用起来蛮能增色自 ...
- Linux删除文件Argument list too long问题的解决方案
方法一:使用find find . -name 文件 | xargs rm -f 但文件数量过多,find命令也会出现问题: -bash: /bin/find: Argument list too l ...
- linux下的oracle数据库和表空间的导入导出
由于oracle是安装在linux上面,因此需要oracle的导入导出都是使用命令进行操作.oracle允许整个数据库导入导出和表空间的导入导出. 数据库导入导出 以下操作是在操作系统控制台命令中执行 ...
- (转)C# 中的委托和事件
来源:http://www.tracefact.net/CSharp-Programming/Delegates-and-Events-In-CSharp.aspx 引言 委托 和 事件在 .Net ...
- ASP.NET程序如何更新发布
ASP.NET程序如何更新发布 一.首先右键项目,点击“发布” 然后,新建名称.类型选择文件,然后点击下一步: 点击发布即可! 二.
- HTML基础(1) 全局架构标签,特殊字符
最基本的网页文件组成部分 其中 <head></head> 这个标签对中内容不会显示在网页中 <body></body> 中的内容可以显示在网页中. b ...
- tomcat的server.xml详解
Tomcat服务器是由一系列可配置的组件构成,其核心组件是Catalina Servlet容器,它是所有其他Tomcat组件的顶层容器.Tomcat的组件可以在<CATALINA_HOME& ...
- C# 控制台程序 托盘图标 事件响应
static void Main(string[] args) { NotifyIconHelper ni = new NotifyIconHelper(); NotifyIconHelper.Sho ...
- 比较ArrayList和LinkedList
比较一:添加内容 涉及方法:add public void add_test(){ List<Person> addlist = new ArrayList<Person>() ...
- 说说http请求
为什么做web前端要了解http标准?因为浏览器要从服务端获取网页,网页也可能将信息再提交给服务器,这其中都有http的连接.web系统既然和http链接有瓜葛,你就必须去了解它.我将从一下几个方面讲 ...