HDU 5432 Pyramid Split 二分

小明是城会玩,他有很多底面是正方形的黄金锥体,我们称之为金字塔,它由高度和底面正方形边长可以确定,分别称之为金字塔的高和宽。
为了便于理解,单位统一取米。现在小明有nn个金字塔,已知它们的高和宽,小明打算重铸,想将它重铸成两个体积一样的物体。
当然,小明是城会玩,不会简单的把所有金字塔融了再分,他有一把屠龙刀,该刀削金如泥。
他现在把所有金字塔正放(即底面贴地放)在水平地面上,用屠龙刀切割一个平面,该平面与水平面平行,称之为割平面。
我们的任务是找到一个这样的割平面,使得这个割平面上方的体积之和等于下方的体积之和,该割平面称之为平均割平面。求平均割平面的高度。
输入描述
第一行输入一个整数TT,表示TT组数据( 1 \leq T \leq100 )(1≤T≤100)。
每组数据有三行,第一行有一个整数nn,表示金字塔的个数( 1 \leq n \leq 10000 )(1≤n≤10000)。
第二行有nn个整数A_iA
​i
​​ ,分别表示第ii个金字塔的高度( 1 \leq A_i \leq 1000)(1≤A
​i
​​ ≤1000)。
第三行有nn个整数B_iB
​i
​​ ,分别表示第ii个金字塔的宽度(1 \leq B_i \leq 100 )(1≤B
​i
​​ ≤100)。
输出描述
对于每组数据,输出平均割平面的高度,取整数部分(如15.8请输出15)。
输入样例
2
2
6 5
10 7
8
702 983 144 268 732 166 247 569
20 37 51 61 39 5 79 99
输出样例
1
98

这道题一开始看错题了,白白wa了三次。

解题思路:
首先理解什么是平均割平面。就是将所有金字塔按一定的高度切一刀(如果没有到这个高度的则不切),如果正好切掉了总体积一半,那么这个高度就是平均割平面的高度。
首先要推出来当在高度为h的时候切,切下来的体积是多少,简单计算可得,设初始金字塔底上的正方形边长为x,高度为h,从高度h1切,则切掉的体积为1/3*x*x*(h-h1)/h*(h-h1)/h*(h-h1)。然后进行简单的二分即可。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<queue>
#include<algorithm>
#include<stack>
#include<cstring>
#include<vector>
#include<list>
#include<set>
#include<string>
using namespace std;
int a[10005],b[10005],n;
double jud(double x)
{
    double sum1=0;
    for(int i=1;i<=n;i++)
    {
        if(x>=a[i]) continue;
        double d=(double(a[i])-x)/a[i];
        sum1+=b[i]*b[i]*d*d*(double(a[i])-x);
    }
    return sum1;

}

int main()
{
    //freopen("in.txt","r",stdin);
    int t;
    cin>>t;
    while(t--)
    {
        cin>>n;
        memset(a,0,sizeof(a));
        memset(b,0,sizeof(b));
        double sum=0;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
        }
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&b[i]);
            sum+=b[i]*b[i]*a[i];
        }
        sum/=2;
        double l=0,r=1000,mid;
        while(fabs(r-l)>1e-6)
        {
            mid=(r+l)/2;
            if(jud(mid)>=sum) l=mid;
            else r=mid;
        }
        cout<<int(mid)<<endl;
    }
    return  0;
}

如果感觉对二分有困惑的,强烈建议去做一下湘大oj上的1236题,感觉如果弄懂了将会对二分的理解非常透彻。
这是题目链接
http://202.197.224.59/OnlineJudge2/index.php/Problem/read/id/1236

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值