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. petstore-jdbc

    拖了好多天,终于决定开始写作业了,搞了大半天的把软件安好. jdk(安装与环境配置) Tomcat(安装与环境配置) mysql(安装,同时配置图形化操作界面) eclipse for Javaee ...

  2. dip2px

    package com.itheima.zhbj.utils; import android.content.Context; public class DensityUtils { public s ...

  3. javase swing

    package com.test; import java.awt.BorderLayout; import java.awt.Color; import java.awt.event.ActionE ...

  4. iperf linux版本移植到android (使用工具链方式不是使用Android.mk)

    由于很多程序是用makefile编译linux应用程序的,如果移植到android就要重新写Android.mk,对于不熟悉这个的人来说,特别麻烦,所以这里介绍只修改makefile就能移植到andr ...

  5. 笨方法学python--数字和数学计算

    1 数学运算符号 + plus 加号 - minus 减号 / slash 除法 * asterisk 乘法 % percent 模除 求余 < less than 小于号 > great ...

  6. asp的RegExp对象正则表达式功能用法

    RegExp对象提供简单的正则表达式支持功能. RegExp对象的用法: 以下为引用的内容: Function RegExpTest(patrn, strng) Dim regEx, Match, M ...

  7. sql-删除delete涉及到三个表,这个时候就要使用from,比如这样

    delete y from dbo.XZXK_BANJIE b ,YJDC_YELLOWRED_CONTENT y , dbo.XZXK_SHOULI s where b.shoulioid=s.sh ...

  8. 【转】configure/make/make install的使用说明

    这些都是典型的使用GNU的AUTOCONF和AUTOMAKE产生的程序的安装步骤. ./configure是用来检测你的安装平台的目标特征的.比如它会检测你是不是有CC或GCC,并不是需要CC或GCC ...

  9. cin详解(cin.get()、cin.getline()、cin.clear()、cin.sync())

    在C中,输入输出用scanf和printf,在输入数据的同时还需说明数据的类型,如果输入数据较多,那就很麻烦,而C++中也有相似的东西cin和cout,它们来自C++的一个名叫" iostr ...

  10. Segments POJ 3304 直线与线段是否相交

    题目大意:给出n条线段,问是否存在一条直线,使得n条线段在直线上的投影有至少一个公共点. 题目思路:如果假设成立,那么作该直线的垂线l,该垂线l与所有线段相交,且交点可为线段中的某两个交点 证明:若有 ...