BZOJ 3564: [SHOI2014]信号增幅仪 最小圆覆盖
3564: [SHOI2014]信号增幅仪
题目连接:
http://www.lydsy.com/JudgeOnline/problem.php?id=3564
Description
无线网络基站在理想状况下有效信号覆盖范围是个圆形。而无线基站的功耗与圆的半径的平方成正比。
现给出平面上若干网络用户的位置,请你选择一个合适的位置建设无线基站....
就在你拿起键盘准备开始敲代码的时候,你的好朋友发明家 SHTSC 突然出现了。SHTSC 刚刚完成了他的新发明——无线信号增幅仪。增幅仪能够在不增加无线基站功耗的前提下,使得有效信号的覆盖范围在某一特定方向上伸长若干倍。即:使用了增幅仪的无线基站覆盖范围是个椭圆,其功耗正比于半短轴长的平方。现给出平面上若干网络用户的位置,请你选择一个合适的位置建设无线基站,并在增幅仪的帮助下使所有的用户都能接收到信号,且无线基站的功耗最小。
注意:由于SHTSC 增幅仪的工作原理依赖地磁场,增幅的方向是恒定的。
Input
第一行一个整数:n。平面内的用户个数。
之后的 n 行每行两个整数 x, y,表示一个用户的位置。
第 n+2 行一个整数:a。表示增幅仪的增幅方向,单位是度。表示增幅仪的方向是从 x 正方向逆时针转 a 度。
第 n+3 行一个整数:p。表示增幅仪的放大倍数。
Output
输出一行一个实数,为能够覆盖所有用户的最小椭圆的半短轴长,四舍五入到三位小数。
Sample Input
样例一:
2
1 0
-1 0
0
2
样例二:
3
1 1
-1 -1
0 0
4 5
7
Sample Output
样例一:
0.500
样例二:
0.202
Hint
对于 100%的数据,n≤50000,0≤a<180,1≤p≤100,|x|,|y|≤2×10^8。
题意
题解:
椭圆的话,先把所有点都旋转一下,使得椭圆的长轴在x轴上面。
然后再让所有点都缩小放大的倍数,那么这道题就可以转化为最小圆覆盖了。
然后跑随机增量法就好了。
代码
#include<bits/stdc++.h>
using namespace std;
const int maxn = 50005;
const double pi = acos(-1.0);
const double EP = 1E-6;
struct POINT
{
double x;
double y;
POINT(double a=0, double b=0) { x=a; y=b;} //constructor
};
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);
}
double operator *(POINT p1,POINT p2){
return p1.x*p2.y-p1.y*p2.x;
}
POINT operator /(POINT p1,double x){
return POINT(p1.x/x,p1.y/x);
}
POINT operator *(POINT p,double x){
return POINT(p.x*x,p.y*x);
}
struct LINESEG
{
POINT s;
POINT e;
LINESEG(POINT a, POINT b) { s=a; e=b;}
LINESEG() { }
};
struct LINE // 直线的解析方程 a*x+b*y+c=0 为统一表示,约定 a >= 0
{
double a;
double b;
double c;
LINE(double d1=1, double d2=-1, double d3=0) {a=d1; b=d2; c=d3;}
};
// 返回点p以点o为圆心逆时针旋转alpha(单位:弧度)后所在的位置
POINT rotate(POINT o,double alpha,POINT p)
{
POINT tp;
p.x-=o.x;
p.y-=o.y;
tp.x=p.x*cos(alpha)-p.y*sin(alpha)+o.x;
tp.y=p.y*cos(alpha)+p.x*sin(alpha)+o.y;
return tp;
}
int n;
POINT po[maxn],O;
double r;
double dis(POINT A,POINT B){
return sqrt((A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y));
}
POINT circumcenter(const POINT &a,const POINT &b,const POINT &c)
{ //返回三角形的外心
POINT ret;
double a1=b.x-a.x,b1=b.y-a.y,c1=(a1*a1+b1*b1)/2.0;
double a2=c.x-a.x,b2=c.y-a.y,c2=(a2*a2+b2*b2)/2.0;
double d=a1*b2-a2*b1;
ret.x=a.x+(c1*b2-c2*b1)/d;
ret.y=a.y+(a1*c2-a2*c1)/d;
return ret;
}
void min_cover_circle(POINT *p,int n,POINT &c,double &r){ //c为圆心,r为半径
random_shuffle(p,p+n); //
c=p[0]; r=0;
for(int i=1;i<n;i++)
{
if(dis(p[i],c)>r+EP) //第一个点
{
c=p[i]; r=0;
for(int j=0;j<i;j++)
if(dis(p[j],c)>r+EP) //第二个点
{
c.x=(p[i].x+p[j].x)/2;
c.y=(p[i].y+p[j].y)/2;
r=dis(p[j],c);
for(int k=0;k<j;k++)
if(dis(p[k],c)>r+EP) //第三个点
{//求外接圆圆心,三点必不共线
c=circumcenter(p[i],p[j],p[k]);
r=dis(p[i],c);
}
}
}
}
}
int main(){
srand(772002);
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%lf%lf",&po[i].x,&po[i].y);
}
double a,p;
scanf("%lf%lf",&a,&p);
double ang=-a/180.0*pi;
for(int i=0;i<n;i++){
po[i]=rotate(POINT(0,0),ang,po[i]);
po[i].x/=p;
}
min_cover_circle(po,n,O,r);
printf("%.3f\n",r);
}
BZOJ 3564: [SHOI2014]信号增幅仪 最小圆覆盖的更多相关文章
- [BZOJ 3564] [SHOI2014] 信号增幅仪 【最小圆覆盖】
题目链接:BZOJ - 3564 题目分析 求最小椭圆覆盖,题目给定了椭圆的长轴与 x 轴正方向的夹角,给定了椭圆长轴与短轴的比值. 那么先将所有点旋转一个角度,使椭圆长轴与 x 轴平行,再将所有点的 ...
- 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\) 然后最小 ...
随机推荐
- Spring Tool Suite 创建 SpringMVC+Maven 项目(一)!
使用Spring Tool Suite 创建 SpringMVC Web 项目,使用Maven来管理依赖! 首先对环境进行必要的配置 1. 配置必要的Java JDK版本! (菜单栏-窗口-首选项.) ...
- [机器学习&数据挖掘]朴素贝叶斯数学原理
1.准备: (1)先验概率:根据以往经验和分析得到的概率,也就是通常的概率,在全概率公式中表现是“由因求果”的果 (2)后验概率:指在得到“结果”的信息后重新修正的概率,通常为条件概率(但条件概率不全 ...
- Newtonsoft 反序列化字符串
string json=“[{“name”:”zhangsan”,”age”:”12”},{“name”:”zhangsan”,”age”:”12”}]” 方法1: JArray arr = (JAr ...
- Java 基本语法---Java方法
Java 基本语法---Java方法 0.概述 方法:就是用来解决一类问题的代码的有序组合,是一个功能模块: 在方法部分,只使用对象名词调用方法: Scanner sc = new Scanner(S ...
- nio--自己总结
阻塞/非阻塞 + 同步/异步 其实,这两者存在本质的区别,面向的对象是不同的. 阻塞/非阻塞:进程/线程需要操作的数据如果尚未就绪,是否妨碍了当前进程/线程的后续操作. 同步/异步:数据如果尚未就 ...
- Python 协程检测Kubernetes服务端口
一.需求分析 在上一篇文章,链接如下: https://www.cnblogs.com/xiao987334176/p/10237551.html 已经得到了需要的数据,现在需要对这些端口做检测,判断 ...
- KnockoutJs学习笔记(七)
if binding与visible binding类似.不同之处在于,包含visible binding的元素会在DOM中一直保存,并且该元素相应的data-bind属性会一直保持,visible ...
- 基于nopCommerce的开发框架(附源码)
.NET的开发人员应该都知道这个大名鼎鼎的高质量b2c开源项目-nopCommerce,基于EntityFramework和MVC开发,拥有透明且结构良好的解决方案,同时结合了开源和商业软件的最佳特性 ...
- 【AtCoder】ARC088
C - Multiple Gift 题解 首项是X,每次乘个2,暴力统计 代码 #include <bits/stdc++.h> #define fi first #define se s ...
- vs2010 打包安装
https://jingyan.baidu.com/article/b7001fe184e4e50e7382dd4e.html 1 建立安装项目2 要安装的文件都添加到应用程序文件夹3 在应用程序文件 ...