BZOJ 3564: [SHOI2014]信号增幅仪

看了一上午平面图最短路的论文还是没看懂

很想知道旅行者那题出成在线的要怎么做(离线的你都不会好不好

然后发现老师发了个压缩包过来。

咦,14年的SH省选题

还有数据,果断开坑。

话说第一题是考高中数学吗。。。。。。

最小椭圆覆盖

和最小圆覆盖差不多

就是要推几个公式

40+min码完是不是慢了点

话说竟然1A了真神奇

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
const double eps=1e-9;
const int N=500000+5;
const double pi=acos(-1.0);
int dcmp(double x){
	if(fabs(x)<eps)return 0;
	return x<0?-1:1;
}
struct equ{
	double a,b,c;//ax+by=c;
};
struct point{
	double x,y;
	bool operator == (point p){
		return !dcmp(x-p.x)&&!dcmp(y-p.y);
	}
	void debug(){
		printf("%lf %lf\n",x,y);
	}
};
double sqr(double x){return x*x;}
double dist(point a,point b){
	return sqrt(sqr(a.x-b.x)+sqr(a.y-b.y));
}
point solve(equ e1,equ e2){
	double D=e1.a*e2.b-e1.b*e2.a,D1=e1.c*e2.b-e2.c*e1.b,D2=e1.a*e2.c-e1.c*e2.a;
	return (point){D1/D,D2/D};
}
double p;
struct elp{
	point p;
	double a,b;
	void debug(){
		p.debug();
		printf("%lf %lf\n",a,b);
	}
};
equ pro(point p1,point p2){
	double a=2*(p2.x-p1.x),b=2*sqr(p)*(p2.y-p1.y),
	c=sqr(p2.x)-sqr(p1.x)+sqr(p)*(sqr(p2.y)-sqr(p1.y));
	return (equ){a,b,c};
}
double calcb(point p0,point p1){
	return sqrt(sqr(p1.x-p0.x)/sqr(p)+sqr(p1.y-p0.y));
}
elp solve(point p1,point p2,point p3){
	elp ans;
	ans.p=solve(pro(p1,p2),pro(p2,p3));
	ans.b=calcb(ans.p,p1);
	ans.a=ans.b*p;
	return ans;
}
point mid(point a,point b){
	return (point){(a.x+b.x)/2.0,(a.y+b.y)/2.0};
}
elp solve(point p1,point p2){
	elp ans;
	ans.p=mid(p1,p2);
	ans.b=calcb(ans.p,p1);
	ans.a=ans.b*p;
	return ans;
}
bool cover(elp e,point p){
	if(!e.b)return p==e.p;
	return dcmp(sqr(e.b*(p.x-e.p.x))+sqr(e.a*(p.y-e.p.y))-sqr(e.a*e.b))<=0;
}
elp min_ellipse_cover(point *P,int n){
	random_shuffle(P,P+n);
	elp ans;
	ans.p=P[0];ans.a=ans.b=0;
	for(int i=1;i<n;i++)
	if(!cover(ans,P[i])){
		ans.p=P[i];ans.a=ans.b=0;
		for(int j=0;j<i;j++)
		if(!cover(ans,P[j])){
			ans=solve(P[i],P[j]);
			for(int k=0;k<j;k++)
			if(!cover(ans,P[k]))
			ans=solve(P[i],P[j],P[k]);
		}
	}
	return ans;
}
point t[N];
point rotate(point p,double a){
	return (point){p.x*cos(a)+p.y*sin(a),p.y*cos(a)-p.x*sin(a)};
}
int main(){
	//freopen("a.in","r",stdin);
	int n;scanf("%d",&n);
	for(int i=0;i<n;i++)
	scanf("%lf%lf",&t[i].x,&t[i].y);
	double a;scanf("%lf%lf",&a,&p);
	a=a/180.0*pi;
	for(int i=0;i<n;i++)t[i]=rotate(t[i],a);
	printf("%.3lf\n",min_ellipse_cover(t,n).b);
	return 0;
}
				

TM才发现脑残了。

直接把横坐标除以p,然后做最小圆覆盖就好了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值