POJ 1267 Fence(几何 + 二分)

32 篇文章 0 订阅
3 篇文章 0 订阅

大体题意:

给你n 条木棍,要用它们组成凸多边形,每个木棍都要用上,使得面积最大,数据范围3 <= n <= 100

如果不存在的话,要输出0.00.(结果保留两位小数)

思路:

首先这个题目得知道,固定边长的多边形面积最大是 圆内接多边形!


参考网站:点我打开网站

是然后思路是很明确的,我们直接二分枚举圆的半径R,然后判断那n 个边是否能放在这半径为R的圆里面。

判断方法:

你可以把根据圆的半径和边长的长度,转换成弧度,最后看看弧度之和是否是2π。

但是会有一些特殊情况,比如说是所有的边构成的多边形在圆的上半侧,这样的话,画个图知道,需要把最长的边对应的弧度变为 2π-弧度!(样例就是这个情况)

分情况讨论好就行!

这里给大家三组数据,这三组数据过了一般就没问题了!

4

10 5 5 4  ----->28.00

3

1 1 6 ---->  0.00

3

3 4 5 ----->6.00

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
const double eps = 1e-10;
const int inf = 0x3f3f3f3f;
const double pi=3.1415926535897932384626433832795;
double a[107];

int dcmp(double a,double b){
    if (fabs(a - b ) < eps) return 0;
    if (a < b) return -1;
    return 1;
}

int main(){
    int n;
    scanf("%d",&n);
    double Max = -1;
    int pos;
    for (int i = 0; i < n; ++i){
        scanf("%lf",a+i);
        if (a[i] > Max){
            Max = a[i];
            pos = i;
        }
    }

    double che = 0;
    for (int i = 0; i < n; ++i){
        if (i != pos) che += a[i];
    }

    if (che < a[pos]) return 0 * puts("0.00");


    double l = Max / 2, r = inf;
    double ans = 0;
    double s0 = 0;
    int flag = 0;
    for (int i = 0; i < n; ++i){
        s0 += asin( a[i]/(2*l) );
    }
    if (dcmp(s0,pi) == -1) flag = 1;
    double R;
    while(l + eps < r){
        double sum = 0;
//        double s = 0;
        R = (l + r) / 2;
        for (int i = 0; i < n; ++i){
            if (!flag){
                sum += asin( a[i]/(2*R) );
            }
            else {
                if (i != pos)
                    sum += asin( a[i]/(2*R) );
                else sum += pi - asin( a[i]/(2*R) );;
            }


        }
//        printf("%lf %lf %lf\n",sum,2*pi,R);
//        printf("%lf\n",R);
        if (dcmp(sum , pi) == 0){
//            ans = s;
//            puts("ahahha");
            l = R;
        }
        else {
            if (flag){
                if (sum < pi){
                    l = R;
                }
                else r = R;
            }
            else {
                if (sum < pi){
                    r = R;
                }
                else l = R;
            }
        }
    }
    R = (l+r)/2;
    for (int i = 0; i < n; ++i){
        if (!flag){
            ans += a[i] * sqrt(R*R - a[i]*a[i]/4) / 2;
        }
        else {
            if (i != pos)
                ans += a[i] * sqrt(R*R - a[i]*a[i]/4) / 2;
            else
                ans -= a[i] * sqrt(R*R - a[i]*a[i]/4) / 2;
        }
    }
    printf("%.2f\n",ans);


    return 0;
}

Fence
Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 828 Accepted: 197

Description

Workers are going to enclose a new working region with a fence. For their convenience the enclosed area has to be as large as possible. They have N rectangular blocks to build the fence. The length of the i-th block is Li meters. All blocks have the same height of 1 meter. The workers are not allowed to break blocks into parts. All blocks must be used to build the fence.

Input

The first line of the input file contains one integer N (3 <= N <= 100). 
The following N lines describe fence blocks. Each block is represented by its length in meters (integer number, 1 <= Li <= 100). 

Output

Write to the output file one non-negative number S - maximal possible area of the working region (in square meters). S must be written with at least two digits after the decimal point. If it is not possible to construct the fence from the specified blocks, write 0.00.

Sample Input

4
10
5
5
4

Sample Output

28.00

Source

Northeastern Europe 2001, Northern Subregion 2001(URAL 1159)


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值