2015 ACM/ICPC 长春现场赛 E题

三分。

如果节点个数是奇数,那么直接列方程可以求解,因为,如果第一个圆半径变大,必然导致最后一个圆的半径变大,

所以,节点是奇数的时候,要么无解,要么只有一组解。

如果节点个数是偶数,如果奇数编号起点的线段长度之和不等于偶数编号起点的线段长度之和,那么必定无解,这个列方程也可以发现的。

剩下的就要三分求最优解了,边界的确定有点小坑,第一个半径是X,第二个半径就是 L12-X,第三个半径就是L23-L12+X.....写出n个关于X的表达式,可以确定三分范围。

至此,此题已解。

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std; const double PI=acos(-1.0);
const double eps=1e-; struct Point
{
double x,y;
double r;
}P[+];
struct Line
{
double len;
}L[+];
int T,n;
double r[+]; bool Equal(double a,double b)
{
if(fabs(a-b)<eps) return ;
return ;
} double Dis(int a,int b)
{
return sqrt((P[a].x-P[b].x)*(P[a].x-P[b].x)+(P[a].y-P[b].y)*(P[a].y-P[b].y));
} void read()
{
scanf("%d",&n);
for(int i=;i<=n;i++)
scanf("%lf%lf",&P[i].x,&P[i].y);
for(int i=;i<=n;i++)
{
if(i<n) L[i].len=Dis(i,i+);
else L[i].len=Dis(n,);
}
} void print1()
{
double sum=;
for(int i=;i<=n;i++)
if(P[i].r<)
{
printf("IMPOSSIBLE\n");
return ;
}
for(int i=;i<=n;i++)
sum=sum+P[i].r*P[i].r;
printf("%.2lf\n",sum*PI);
for(int i=;i<=n;i++)
printf("%.2lf\n",P[i].r);
} double ff(double R)
{
r[]=R;
for(int i=;i<=n;i++)
r[i]=L[i-].len-r[i-]; double sum=;
for(int i=;i<=n;i++) sum=sum+r[i]*r[i];
return sum;
} void solve()
{
if(n%==)
{
double len1=,len2=;
for(int i=;i<=n;i++)
{
if(i%==) len2=len2+L[i].len;
else len1=len1+L[i].len;
}
P[].r=(len1-len2)/2.0;
for(int i=;i<=n;i++)
P[i].r=L[i-].len-P[i-].r; if(!Equal(L[n].len-P[].r,P[n].r))
{
printf("IMPOSSIBLE\n");
return;
}
print1();
} else if(n%==)
{
double len1=,len2=;
for(int i=;i<=n;i++)
{
if(i%==) len1=len1+L[i].len;
else len2=len2+L[i].len;
}
if(len1!=len2) printf("IMPOSSIBLE\n");
else
{
double left,right,mid,midmid;
left=; right=min(L[].len,L[n].len);
double sum=;
for(int i=;i<=n;i++)
{
if(i%==)
{
sum=sum+L[i].len;
if(sum<right) right=sum;
}
else
{
sum=sum-L[i].len;
if(sum>left) left=sum;
}
}
int tot=;
while(tot--)
{
mid=(left+right)/2.0;
midmid=(mid+right)/2.0;
double k1=ff(mid);
double k2=ff(midmid); if(k1-k2>eps) left=mid;
else right=midmid; }
for(int i=;i<=n;i++)
if(r[i]<)
{
printf("IMPOSSIBLE\n");
return ;
}
printf("%.2lf\n",ff(midmid)*PI);
for(int i=;i<=n;i++) printf("%.2lf\n",r[i]);
}
}
} int main()
{
scanf("%d",&T);
while(T--)
{
read();
solve();
}
return ;
}

HDU 5531 Rebuild的更多相关文章

  1. HDU 5531 Rebuild (2015长春现场赛,计算几何+三分法)

    Rebuild Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total S ...

  2. 2015ACM/ICPC亚洲区长春站 E hdu 5531 Rebuild

    Rebuild Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total S ...

  3. 2015长春 HDU 5531 Rebuild

    题意:n个顶点组成的多边形能否形成正多边形? #include <cstdio> #include <cstring> #include <cmath> #incl ...

  4. [三分]HDOJ 5531 Rebuild

    题意:给n个点,以这n个点为圆心画圆,使得所有的圆与其相邻的圆相切. 求n个圆最小的面积和. 分析:很容易想到确定了其中一个圆的半径之后,其他的圆的半径也能随之确定了. 画一画三个点的和四个点的,会发 ...

  5. HDU 5531

    题目大意: 给定一个n边形的顶点 以每个顶点为圆心画圆(半径可为0) 每个顶点的圆要和它相邻顶点的圆相切(不相邻的可相交) 求所有圆的最小面积总和并给出所有圆的半径 设半径为r1 r2 ... rn, ...

  6. HDU 3080 The plan of city rebuild(prim和kruskal)

    The plan of city rebuild Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java ...

  7. HDU 3080 The plan of city rebuild(除点最小生成树)

    题意  一个城市原来有l个村庄 e1条道路  又添加了n个村庄 e2条道路  后来后销毁了m个村庄  与m相连的道路也销毁了  求使全部未销毁村庄相互连通最小花费  不能连通输出what a pity ...

  8. E - Rebuild UVALive - 7187 (二次函数极值问题)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5531 Problem Description Archaeologists find ruins of ...

  9. HDU 5723 Abandoned country(落后渣国)

    HDU 5723 Abandoned country(落后渣国) Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 65536/65536 ...

随机推荐

  1. 你需要简单了解JVM中的内存长什么样子

    下面有关JVM内存,说法错误的是? 1.程序计数器是一个比较小的内存区域,用于指示当前线程所执行的字节码执行到了第几行,是线程隔离的 2.Java方法执行内存模型,用于存储局部变量,操作数栈,动态链接 ...

  2. DOM操作-主动触发按钮的单击事件

    代码: ———————————————————————————————— <script>       function fireBtnClick(){        var myBtn ...

  3. JSP内置对象--pageContent,request,response,session,application,config,out,page,exception

  4. linux下mysql root密码忘记修改方法

    一.MySQL密码的恢复方法之一 如果忘记了MySQL的root密码,可以用以下方法重新设置:1.切换到root下su root 2. KILL掉系统里的MySQL进程: killall -TERM ...

  5. Android ADT安装时卡在Calculating requirements and dependencies

    AndroidSDK及Eclipse安装都很顺利,但是在Eclipse下安装ADT插件时,先采用点击Help->installnew software->Add...,无论输入https: ...

  6. perl的package和module

    来源: http://www.cnblogs.com/itech/archive/2010/03/23/1692836.html 一 package 1) package 相当于C++中的namesp ...

  7. Qt学习

    博客 一去丶二三里的博客 http://blog.sina.com.cn/s/articlelist_2801495241_0_4.html

  8. PCI-E调试方式

    PCI-E的调试步骤 1.板子插上去之后正常情况下使用lspci 就能看的一个设备 这个设备上存在几个ID,可以根据ID可以确定设备是否识识别到 2.然后就是加载设备的驱动的时候,设备驱动会有VEND ...

  9. 1.2 sikuli API

    sikuli API网站:http://nightly.sikuli.de/docs/index.html eclipse中如果要用到相应的 sikuli 功能,可以查看API ,然后import相应 ...

  10. 【多重背包模板】poj 1014

    #include <iostream> #include <stdio.h> #include <cstring> #define INF 100000000 us ...