去年 上海X湖北 省选题。(去年高一还是太年轻了,椭圆什么的都不知道,直接看傻眼了) 思路还算简单,但小数不好好对待就会爆掉。。。。。。
由于是椭圆,不好求,然后又告诉了你长轴是短轴的p倍(增幅仪),长轴是个歪的,反正正面强攻是不可能的,于是要将其转化为圆来求。先转换坐标系,公式自己推一下,可能你推的和别人的不一样,比如我推出来的是y1=y*cos(a)-x*sin(a) x1=y*sin(a)+x*cos(a),我用的tan推的。。。。。然后长轴和x轴平行了,于是把长轴缩短p倍即可,最后再求一个最小圆覆盖即可。 需要注意的是数据类型小数用long double ,输出的时候要强制转换为double,注意在求外接圆圆心时可能方法不同,数据会爆掉。。。。。。(b站样例二 45中有个坑爹的空格) 3564: [SHOI2014]信号增幅仪Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 350 Solved: 134 [ Submit][ Status][ Discuss] Description 无线网络基站在理想状况下有效信号覆盖范围是个圆形。而无线基站的功耗与圆的半径的平方成正比。 Input 第一行一个整数:n。平面内的用户个数。 Output 输出一行一个实数,为能够覆盖所有用户的最小椭圆的半短轴长,四舍五入到三位小数。 Sample Input
样例一:
2 1 0 -1 0 0 2 样例二: 3 1 1 -1 -1 0 0 45 7 c++
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<cstring>
#include<cmath>
using namespace std;
const double eps=1e-8;
const long double pi=acos(-1);
struct Point{
long double x,y;
Point(long double x = 0, long double y = 0) : x(x), y(y) {}
};
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 * (long double k, Point a) {
return Point(a.x * k, a.y * k);
}
Point operator / (Point a, long double k) {
return Point(a.x / k, a.y / k);
}
long double dot (Point a, Point b) {
return a.x * b.x + a.y * b.y;
}
long double det (Point a, Point b) {
return a.x * b.y - a.y * b.x;
}
int n,a4,p1;
Point d[510000],c;
long double a,p,r;
long double dist(Point x,Point y)
{
return sqrt((x.x-y.x)*(x.x-y.x)+(x.y-y.y)*(x.y-y.y));
}
void zhuanhuan(int i)
{
long double x1,y1;
x1=d[i].y*sin(a)+d[i].x*cos(a);
y1=d[i].y*cos(a)-d[i].x*sin(a);
d[i].x=x1/p;
d[i].y=y1;
return ;
}
Point center(Point a, Point b, Point c) {
long double d1 = -dot(b - a, a - c), d2 = -dot(c - b, b - a), d3 = -dot(a - c, c - b);
long double c1 = d2 * d3, c2 = d3 * d1, c3 = d1 * d2, s = c1 + c2 + c3;
return ((c2 + c3) * a + (c3 + c1) * b + (c1 + c2) * c) / 2 / s;
}
void mincircle()
{
c=d[0]; r=0;
for (int i=1;i<n;i++)
{
if (dist(d[i],c)>r+eps)
{
c=d[i]; r=0;
for (int j=0;j<i;j++)
{
if (dist(d[j],c)>r+eps)
{
c.x=(d[j].x+d[i].x)/2;
c.y=(d[j].y+d[i].y)/2;
r=dist(c,d[j]);
for (int k=0;k<j;k++)
{
if (dist(d[k],c)>r+eps)
{
c=center(d[i],d[j],d[k]);
//printf("%.3lf %.3lf\n",(double)c.x,(double)c.y);
r=dist(c,d[j]);
}
}
}
}
}
}
return ;
}
int main()
{
freopen("amplifier.in","r",stdin);
freopen("amplifier.out","w",stdout);
scanf("%d",&n);
double x,y;
for (int i=0;i<n;i++)
{
scanf("%lf%lf",&x,&y);
d[i].x=(long double)x;
d[i].y=(long double)y;
}
scanf("%d%d",&a4,&p1);
a=(long double) a4;
p=(long double) p1;
a=a*pi/180;
for (int i=0;i<n;i++) zhuanhuan(i);
random_shuffle(d,d+n);
mincircle();
printf("%.3lf\n", (double)r);
return 0;
}
|
bzoj3564: [SHOI2014]信号增幅仪
最新推荐文章于 2018-12-09 19:37:52 发布