BestCoder Round #55 ($) 1001

本文探讨了如何通过数学计算,找到将多个金字塔等体积分割的平面高度,涉及几何体积计算与数学逻辑。

Pyramid Split

Accepts: 247
Submissions: 1097
Time Limit: 4000/2000 MS (Java/Others)
Memory Limit: 65536/65536 K (Java/Others)
问题描述
小明是城会玩,他有很多底面是正方形的黄金锥体,我们称之为金字塔,它由高度和底面正方形边长可以确定,分别称之为金字塔的高和宽。
为了便于理解,单位统一取米。现在小明有nnn个金字塔,已知它们的高和宽,小明打算重铸,想将它重铸成两个体积一样的物体。
当然,小明是城会玩,不会简单的把所有金字塔融了再分,他有一把屠龙刀,该刀削金如泥。
他现在把所有金字塔正放(即底面贴地放)在水平地面上,用屠龙刀切割一个平面,该平面与水平面平行,称之为割平面。
我们的任务是找到一个这样的割平面,使得这个割平面上方的体积之和等于下方的体积之和,该割平面称之为平均割平面。求平均割平面的高度。
输入描述
第一行输入一个整数TTT,表示TTT组数据(1≤T≤100)( 1 \leq T \leq100 )(1T100)。
每组数据有三行,第一行有一个整数nnn,表示金字塔的个数(1≤n≤10000)( 1 \leq n \leq 10000 )(1n10000)。
第二行有nnn个整数AiA_iAi,分别表示第iii个金字塔的高度(1≤Ai≤1000)( 1 \leq A_i \leq 1000)(1Ai1000)。
第三行有nnn个整数BiB_iBi,分别表示第iii个金字塔的宽度(1≤Bi≤100)(1 \leq B_i \leq 100 )(1Bi100)
输出描述
对于每组数据,输出平均割平面的高度,取整数部分(如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

分析:每个锥体的体积与高之间关系比是体积比等于高的立方比,我们可以先求出大椎的体积,然后依次从高度为1,高度为2.。。。依次往上切割,依次求出每个高度对应的上边的小锥的体积和,如果小锥的体积和<大椎体积的一半,那么就找到所求的高度了,找出的高度要减一,因为比如15.8  ,输出的是15,高度从1开始枚举,上面的体积和是一定不会小于下边的(如果小于下边,那么那么输出0),因为输出的那个高度,上面的体积和一定大于等于下边。

#include<iostream>
#include<stdio.h>
#include<string>
#include<string.h>
#include<algorithm>
#include<vector>
#include<math.h>
#define LL long long
using namespace std;
int main()
{
    int T,n,a[10000],b[10000];
    double aa[10000],v[10000];
    scanf("%d",&T);
    while(T--){
        scanf("%d",&n);
        int maxn=200000;
        for(int i=0;i<n;i++){
            scanf("%d",&a[i]);
             if(a[i]>maxn)maxn=a[i];
        }

        for(int i=0;i<n;i++){
            scanf("%d",&b[i]);

           // else if(b[i]<minn)minn=b[i];
        }
        double sum=0,h=0;
        for(int i=0;i<n;i++){
            v[i]=b[i]*b[i]*a[i];
            sum+=v[i];
        }
        //double v=(double)sum/6.0;
        for(int i=0;i<n;i++)
            aa[i]=a[i]*a[i]*a[i];
        double minh=10000000;
        double pre=sum/2.0;
        for(int i=1;i<=maxn;i++){
            double he=0;
            for(int j=0;j<n;j++){
                if(a[j]>i)
                he+=(double)(((a[j]-i)*(a[j]-i)*(a[j]-i)*v[j])/aa[j]);
            }
            if(he<pre){h=i;break;};
           // if(fabs(pre-he)<minh){h=i;minh=fabs(pre-he);};
        }
        cout<<h-1<<endl;
    }
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值