您的位置:首页 > 其它

HDU 5432 Pyramid Split 二分

2015-09-12 22:29 316 查看
小明是城会玩,他有很多底面是正方形的黄金锥体,我们称之为金字塔,它由高度和底面正方形边长可以确定,分别称之为金字塔的高和宽。

为了便于理解,单位统一取米。现在小明有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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: