【二分+计算几何】hdu 4033 Regular Polygon

【二分+计算几何】hdu 4033 Regular Polygon

题目链接:hdu 4033 Regular Polygon

题目大意

已知正多边形中的一个内点到所有顶点的距离,求多边形的边长。

这里写图片描述
这里写图片描述

二分问题一般都存在含有一个未知量的方程(等式关系),通过二分未知量的范围实现查找,这道题目的几何关系就是:知道一边,内角和(围着内点)等于360度。根据三角不等式确定边的二分范围,二分查找边使得内角之和为2π即可。


说一下思路

笔者根据第一条边和最后一条边确定二分边的范围,边确定由余弦定理能确定所有内角,二分查找使得内角之和==2π,注意浮点数误差,用三态函数dcmp判等即可。

这里写图片描述


参考代码

/*====================================*\
|*        二分  +   计算几何          *|
\*====================================*/
/*Author:Hacker_vision*/
#include<bits/stdc++.h>
#define clr(k,v) memset(k,v,sizeof(k))
#define eps 1e-8
using namespace  std;

const int _max = 1e3 + 10;
const double PI = acos(-1);
int n;
double a[_max];
int dcmp(double x){//三态函数,避免精度误差
  if(fabs(x)<eps) return 0;else return x<0?-1:1;
}

double angle(double x){//根据余弦定理和正多边形n条边相等的特性,返回内角和
  double ans = 0;
  a[n] = a[0];
  for(int i = 0;i < n;++ i)
    ans += acos((a[i]*a[i]+a[i+1]*a[i+1]-x*x)/(2*a[i]*a[i+1]));
  return ans;
}

double bsearch(double L,double R){//二分查找边长
  double m;
  while(R - L >= eps){
    m = (L + R) / 2.0;//不能用位运算了QAQ
    if(dcmp(angle(m)-2*PI)==0) return m;//一条边一旦确定,内角和也就确定下来了
    if(angle(m) < 2*PI) L = m + eps;
    else R = m;
  }
  return -1;
}

int main(){
  #ifndef ONLINE_JUDGE
  freopen("input.txt","r",stdin);
  #endif // ONLINE_JUDGE
  int T;cin>>T;int cnt=1;
  while(T--){
    scanf("%d",&n);
    for(int i = 0;i < n; ++ i)
        scanf("%lf",a+i);
    double res = bsearch(fabs(a[0]-a[n-1]),a[0]+a[n-1]);
    printf("Case %d: ",cnt++);
    if(dcmp(res+1)==0) puts("impossible");
    else printf("%.3f\n",res);
  }
  return 0;
}

  • 加粗 Ctrl + B
  • 斜体 Ctrl + I
  • 引用 Ctrl + Q
  • 插入链接 Ctrl + L
  • 插入代码 Ctrl + K
  • 插入图片 Ctrl + G
  • 提升标题 Ctrl + H
  • 有序列表 Ctrl + O
  • 无序列表 Ctrl + U
  • 横线 Ctrl + R
  • 撤销 Ctrl + Z
  • 重做 Ctrl + Y
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值