2011成都网赛 / 1003 - Regular Polygon
2011-09-12 01:07
369 查看
题目
利用余弦定理,构造函数 b=sigma(acos(a[i]^2+a[i+1]^2-e^2)/(2a[i]a[i+1]))。e为边长。当e为解时,b=2*pi(内角和)。重点是,b(e)是单调上升的。所以可以二分。(事实上我觉得这种题目必然要二分,重点就是找一个单调函数)。
写的时候,犯了个很傻逼的错误,还以为是精度问题,就一直改精度........(我发现其实做eps的精度,就把eps对应成整数里的1来理解就是了,二分、比较大小什么的都是跟整数同理的,这样好想很多)。 改到我觉得精度不可能有问题的时候...........突然发现,原来我开始的上下界写错了。竟然把 +-eps写到循环里了.......还有,这题是maxe=min(a[i]+a[i+1]),mine=max(fabs(a[i]-a[i+1])) 的.......这里写的时候也傻逼了。
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
#define MAXN 110
#define INF 1<<30
#define pi acos(-1.0)
#define eps 1e-8 //eps !!
double a[MAXN]; //边长
int n;
double f(double x1, double x2, double e) //返回角度
{
return acos((x1*x1+x2*x2-e*e)/(2*x1*x2));
}
double func(double e) // f(边长)-> 2pi
{
double ret=0;
for(int i=0; i<n; i++)
{
int j=(i+1)%n;
ret+=f(a[i], a[j], e);
}
return ret;
}
int cmp(double x, double y)
{
if(fabs(x-y)<eps) return 0; //
else if(x>=y+eps) return 1; //x>=y+eps
else return -1;
}
double solve()
{
double maxe=INF, mine=0; //① 很容易错,因为max值是取min操作的........
for(int i=0; i<n; i++)
{
int j=(i+1)%n;
// maxe = max(maxe, a[i]+a[j])-eps; //!!!! 傻逼
// mine = min(mine, fabs(a[i]-a[j]))+eps;
//maxe = max(maxe, a[i]+a[j]); //!!!傻逼,too
//mine = min(mine, fabs(a[i]-a[j]));
maxe = min(maxe, a[i]+a[j]);
mine = max(mine, fabs(a[i]-a[j]));
}
double l=mine+eps, r=maxe-eps;
int yes=0; //防止一直处于 l=r
while(r-l>eps || !cmp(r, l)) //相当于eps精度下的 l<=r
{
double mid=(l+r)/2;
double t = func(mid);
//printf("t=%lf, 2*pi=%lf, sub=%.10lf\n", t, 2*pi, fabs(t-2*pi));
int flag = cmp(t, 2*pi);
if(!flag) return mid;
else if(flag>0) r=mid-eps;
else if(flag<0) l=mid+eps;
//printf("(%.10lf, %.10lf), sub=%.10lf, eps=%.10lf\n", l, r, r-l, eps);
if(yes) break;
if(!cmp(l, r)) yes=1;
}
return 0;
}
int main()
{
int t; scanf("%d", &t);
for(int T=0; T<t; T++)
{
printf("Case %d: ", T+1);
scanf("%d", &n);
for(int i=0; i<n; i++)
{
scanf("%lf", &a[i]);
}
double t = solve();
if(t) printf("%.3lf\n", t);
else printf("impossible\n");
}
}
利用余弦定理,构造函数 b=sigma(acos(a[i]^2+a[i+1]^2-e^2)/(2a[i]a[i+1]))。e为边长。当e为解时,b=2*pi(内角和)。重点是,b(e)是单调上升的。所以可以二分。(事实上我觉得这种题目必然要二分,重点就是找一个单调函数)。
写的时候,犯了个很傻逼的错误,还以为是精度问题,就一直改精度........(我发现其实做eps的精度,就把eps对应成整数里的1来理解就是了,二分、比较大小什么的都是跟整数同理的,这样好想很多)。 改到我觉得精度不可能有问题的时候...........突然发现,原来我开始的上下界写错了。竟然把 +-eps写到循环里了.......还有,这题是maxe=min(a[i]+a[i+1]),mine=max(fabs(a[i]-a[i+1])) 的.......这里写的时候也傻逼了。
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
#define MAXN 110
#define INF 1<<30
#define pi acos(-1.0)
#define eps 1e-8 //eps !!
double a[MAXN]; //边长
int n;
double f(double x1, double x2, double e) //返回角度
{
return acos((x1*x1+x2*x2-e*e)/(2*x1*x2));
}
double func(double e) // f(边长)-> 2pi
{
double ret=0;
for(int i=0; i<n; i++)
{
int j=(i+1)%n;
ret+=f(a[i], a[j], e);
}
return ret;
}
int cmp(double x, double y)
{
if(fabs(x-y)<eps) return 0; //
else if(x>=y+eps) return 1; //x>=y+eps
else return -1;
}
double solve()
{
double maxe=INF, mine=0; //① 很容易错,因为max值是取min操作的........
for(int i=0; i<n; i++)
{
int j=(i+1)%n;
// maxe = max(maxe, a[i]+a[j])-eps; //!!!! 傻逼
// mine = min(mine, fabs(a[i]-a[j]))+eps;
//maxe = max(maxe, a[i]+a[j]); //!!!傻逼,too
//mine = min(mine, fabs(a[i]-a[j]));
maxe = min(maxe, a[i]+a[j]);
mine = max(mine, fabs(a[i]-a[j]));
}
double l=mine+eps, r=maxe-eps;
int yes=0; //防止一直处于 l=r
while(r-l>eps || !cmp(r, l)) //相当于eps精度下的 l<=r
{
double mid=(l+r)/2;
double t = func(mid);
//printf("t=%lf, 2*pi=%lf, sub=%.10lf\n", t, 2*pi, fabs(t-2*pi));
int flag = cmp(t, 2*pi);
if(!flag) return mid;
else if(flag>0) r=mid-eps;
else if(flag<0) l=mid+eps;
//printf("(%.10lf, %.10lf), sub=%.10lf, eps=%.10lf\n", l, r, r-l, eps);
if(yes) break;
if(!cmp(l, r)) yes=1;
}
return 0;
}
int main()
{
int t; scanf("%d", &t);
for(int T=0; T<t; T++)
{
printf("Case %d: ", T+1);
scanf("%d", &n);
for(int i=0; i<n; i++)
{
scanf("%lf", &a[i]);
}
double t = solve();
if(t) printf("%.3lf\n", t);
else printf("impossible\n");
}
}
相关文章推荐
- 2011成都网赛 / 1003 - Regular Polygon
- hdu 4120【2011 成都现场赛 J题】
- 2011 ACM-ICPC 成都赛区A题 Alice and Bob (博弈动规)
- 2011阿里巴巴程序设计公开赛 1003 I'll play a trick on you
- 绝杀!!!(成都online2011)
- Hdu 4035 Maze (dp求期望) - 2011 ACM/ICPC 成都赛区网络预选赛 1005
- 2011迈普招聘成都笔试 (技术类)
- 2011阿里巴巴程序设计公开赛 / 1003 I'll play a trick on you
- hdu 4112 2011 ACM成都现场赛B
- 2011 ACM-ICPC 成都赛区解题报告(转)
- 2011 ACM-ICPC 成都赛区A题 Alice and Bob (博弈动规)
- 2011阿里巴巴程序设计公开赛 / 1003 I'll play a trick on you
- The 36th ACM/ICPC Asia Regional Chengdu Site 1003 Regular Polygon
- hdu 4034 2011成都赛区网络赛 逆向floyd **
- hdu 4031 2011成都赛区网络赛A题 线段树 ***
- trainging contest#2(2011成都现场赛)D BY bly
- HDU/HDOJ 4038 2011成都赛区网络赛H题
- 2011成都regional比赛总结
- hdu 4033 2011成都赛区网络赛 余弦定理+二分 **
- hdu 4035 2011成都赛区网络赛E 概率dp ****