BZOJ 3564: [SHOI2014]信号增幅仪(随机增量法)

如果是个圆的话好办,如果是拉成椭圆呢?直接压回去!!!

然后随机增量法就行了

CODE:

#include<cstdio>

#include<iostream>

#include<cstring>

#include<algorithm>

#include<cmath>

using namespace std;

#define sqr(x) ((x)*(x))

#define fi first

#define se second

#define maxn 100100

typedef pair<double,double> ii;

ii a[maxn],cir;

double r;

double dis(ii x,ii y) {

return sqrt(sqr(x.fi-y.fi)+sqr(x.se-y.se));

}

ii getcir(ii x,ii y,ii z){

double a=sqr(x.fi)-sqr(y.fi)+sqr(x.se)-sqr(y.se),

  b=sqr(x.fi)-sqr(z.fi)+sqr(x.se)-sqr(z.se),

  c=2*(x.se-z.se)*(x.fi-y.fi)-2*(x.se-y.se)*(x.fi-z.fi);

return ii((a*(x.se-z.se)-b*(x.se-y.se))/c,

(a*(x.fi-z.fi)-b*(x.fi-y.fi))/(-c));

}

#define exp 1e-10

int cmp(double x) {

if (x<-exp) return -1;

if (x>exp) return 1;

return 0;

}

int n;

const double pi=acos(-1);

int main(){

 freopen("amplifier.in","r",stdin);

 freopen("amplifier.out","w",stdout);

scanf("%d",&n);

for (int i=1;i<=n;i++) scanf("%lf%lf",&a[i].fi,&a[i].se);

double tmp;

scanf("%lf",&tmp);

tmp*=-pi/180;

for (int i=1;i<=n;i++) a[i]=ii(a[i].fi*cos(tmp)-a[i].se*sin(tmp),

a[i].fi*sin(tmp)+a[i].se*cos(tmp));

scanf("%lf",&tmp);

for (int i=1;i<=n;i++) a[i].fi/=tmp;

random_shuffle(a+1,a+1+n);

cir=a[1],r=0;

for (int i=1;i<=n;i++) {

if (cmp(dis(cir,a[i])-r)<=0) continue;

cir=a[i],r=0;

for (int j=1;j<i;j++) {

if (cmp(dis(cir,a[j])-r)<=0) continue;

cir.fi=(a[i].fi+a[j].fi)/2,cir.se=(a[i].se+a[j].se)/2;

r=dis(cir,a[j]);

for (int k=1;k<j;k++) {

if (cmp(dis(cir,a[k])-r)<=0) continue;

cir=getcir(a[i],a[j],a[k]);

r=dis(cir,a[i]);

}

}

}

printf("%.3lf\n",r);

return 0;

}


posted @ 2014-12-16 17:22  New_Godess  阅读(141)  评论(0编辑  收藏  举报