HDU 5531 Rebuild
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的更多相关文章
- HDU 5531 Rebuild (2015长春现场赛,计算几何+三分法)
Rebuild Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)Total S ...
- 2015ACM/ICPC亚洲区长春站 E hdu 5531 Rebuild
Rebuild Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)Total S ...
- 2015长春 HDU 5531 Rebuild
题意:n个顶点组成的多边形能否形成正多边形? #include <cstdio> #include <cstring> #include <cmath> #incl ...
- [三分]HDOJ 5531 Rebuild
题意:给n个点,以这n个点为圆心画圆,使得所有的圆与其相邻的圆相切. 求n个圆最小的面积和. 分析:很容易想到确定了其中一个圆的半径之后,其他的圆的半径也能随之确定了. 画一画三个点的和四个点的,会发 ...
- HDU 5531
题目大意: 给定一个n边形的顶点 以每个顶点为圆心画圆(半径可为0) 每个顶点的圆要和它相邻顶点的圆相切(不相邻的可相交) 求所有圆的最小面积总和并给出所有圆的半径 设半径为r1 r2 ... rn, ...
- 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 ...
- HDU 3080 The plan of city rebuild(除点最小生成树)
题意 一个城市原来有l个村庄 e1条道路 又添加了n个村庄 e2条道路 后来后销毁了m个村庄 与m相连的道路也销毁了 求使全部未销毁村庄相互连通最小花费 不能连通输出what a pity ...
- E - Rebuild UVALive - 7187 (二次函数极值问题)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5531 Problem Description Archaeologists find ruins of ...
- HDU 5723 Abandoned country(落后渣国)
HDU 5723 Abandoned country(落后渣国) Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 65536/65536 ...
随机推荐
- JavaScript高级程序设计:第八章
1.window对象——BOM的核心 BOM的核心对象时window,它表示浏览器的一个实例.在浏览器中,window对象有双重角色,它既是通过javascript访问浏览器窗口的一个接口,又是ECM ...
- Linux文件系统的目录结构
Linux下的文件系统为树形结构,入口为/ 树形结构下的文件目录: 无论哪个版本的Linux系统,都有这些目录,这些目录应该是标准的.各个Linux发行版本会存在一些小小的差异,但总体来说,还是大体差 ...
- hdu_2446_Shell Pyramid(数学,二分)
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=2446 题意:题面很大,有用的就那么几句,意思就是用自然数来堆它画的那个金字塔,比如第一个金字塔的第一个 ...
- 很好的容斥思想 HDU 5514
题目描述:有n只青蛙,m个石头(围成圆圈).第i只青蛙每次只能条a[i]个石头,问最后所有青蛙跳过的石头的下标总和是多少? 思路:经过绘图我们发现,每次跳过的位置一定是k*gcd(a[i], m).然 ...
- listener.ora
EOF YESTERDAY=`cat /database/log/tns_log/yesterday.out` TODAY=`date '+%d-%b-%Y'` echo $YESTERDAY $T ...
- Redis 笔记
Redis是一个key-value存储系统.和Memcached类似,但是解决了断电后数据完全丢失的情况,而且她支持更多无化的value类型,除了和string外,还支持lists(链表).sets( ...
- PE文件格式详解(下)
作者:MSDN译者:李马 预定义段 一个Windows NT的应用程序典型地拥有9个预定义段,它们是.text..bss..rdata..data..rsrc..edata..idata..pdata ...
- 查找mysql数据库中所有包含特定名字的字段所在的表
整个数据库查找 placement 字段: select * from INFORMATION_SCHEMA.columns where COLUMN_NAME Like '%placement%'; ...
- 百度地图API地点搜索-获取经纬度
分享一下地图上的地点搜索和鼠标点击获取地点经纬度,这些都是地图比较基本和实用的代码,其中还包括了根据用户IP进行地图的显示.改变地图上的鼠标样式.启用滚轮缩放等,算是半入门吧,其他的一些可以自己参考百 ...
- java基础增强
Eclipse使用: java Compile配置的是java编译环境 java Build path配置的是java运行环境 运行环境的版本必须高于编译环境的版本.否则报错 工程上 右键--prop ...