hdu 5432 Pyramid Split 二分

Pyramid Split

Time Limit: 1 Sec  

Memory Limit: 256 MB

题目连接

http://bestcoder.hdu.edu.cn/contests/contest_chineseproblem.php?cid=629&pid=1001

Description

小明是城会玩,他有很多底面是正方形的黄金锥体,我们称之为金字塔,它由高度和底面正方形边长可以确定,分别称之为金字塔的高和宽。
为了便于理解,单位统一取米。现在小明有nn个金字塔,已知它们的高和宽,小明打算重铸,想将它重铸成两个体积一样的物体。
当然,小明是城会玩,不会简单的把所有金字塔融了再分,他有一把屠龙刀,该刀削金如泥。
他现在把所有金字塔正放(即底面贴地放)在水平地面上,用屠龙刀切割一个平面,该平面与水平面平行,称之为割平面。
我们的任务是找到一个这样的割平面,使得这个割平面上方的体积之和等于下方的体积之和,该割平面称之为平均割平面。求平均割平面的高度。

Input

第一行输入一个整数TT,表示TT组数据( 1 \leq T \leq100 )(1T100)。
每组数据有三行,第一行有一个整数nn,表示金字塔的个数( 1 \leq n \leq 10000 )(1n10000)。
第二行有nn个整数A_iAi​​,分别表示第ii个金字塔的高度( 1 \leq A_i \leq 1000)(1Ai​​1000)。
第三行有nn个整数B_iBi​​,分别表示第ii个金字塔的宽度(1 \leq B_i \leq 100 )(1Bi​​100)。

Output

对于每组数据,输出平均割平面的高度,取整数部分(如15.8请输出15)。

Sample Input

2
2
6 5
10 7
8
702 983 144 268 732 166 247 569
20 37 51 61 39 5 79 99

Sample Output

1
98

HINT

 

题意

 

题解:

高度是满足二分性质的,所以直接二分答案就好了

最后把答案的值的小数部分略去就好了

注意,这个题的hdu的数据比较弱

代码:

//qscqesze
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <cmath>
#include <cstring>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <set>
#include <bitset>
#include <vector>
#include <sstream>
#include <queue>
#include <typeinfo>
#include <fstream>
#include <map>
#include <stack>
typedef long long ll;
using namespace std;
//freopen("D.in","r",stdin);
//freopen("D.out","w",stdout);
#define sspeed ios_base::sync_with_stdio(0);cin.tie(0)
#define maxn 500001
#define mod 1001
#define eps 1e-7
#define pi 3.1415926
int Num;
//const int inf=0x7fffffff;
const ll inf=999999999;
inline ll read()
{
    ll x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
//*************************************************************************************

double getlen(double x,double h,double h2)
{
    if(h2>=h)
        return h;
    return x*h2/h;
}
double getarea(double x,double h)
{
    return x*x*h;
}
double h[10050];
double x[10050];
int n;
double check(double mid)
{
    double s2 = 0;
    for(int i = 1 ; i <= n ; ++ i)
    {
        if(mid >= h[i]) continue;
        else
        {
            double c = h[i] - mid;
            double v1 = (x[i]*x[i])*(h[i]-mid)*(h[i]-mid)*(h[i]-mid)/(h[i]*h[i]);
            s2 += v1;
        }
    }
    return s2;
}
int main()
{
    int t=read();
    while(t--)
    {
        memset(h,0,sizeof(h));
        memset(x,0,sizeof(x));
        n=read();
        for(int i=1;i<=n;i++)
            scanf("%lf",&h[i]);
        for(int i=1;i<=n;i++)
            scanf("%lf",&x[i]);
        double s = 0;
        for(int i=1;i<=n;i++)
            s+=getarea(x[i],h[i]);
        s/=2.0;
        double mid;
        double L = 0;
        double R = 1000;
        while((R-L) > eps)
        {
            double mid = (L+R)/2.0;
            if(check(mid) > s) L = mid;
            else R = mid;
        }
        int ans = L;
        printf("%d\n",ans);
    }
}

 

posted @ 2015-09-12 22:22  qscqesze  阅读(370)  评论(0编辑  收藏  举报