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=1001Description
小明是城会玩,他有很多底面是正方形的黄金锥体,我们称之为金字塔,它由高度和底面正方形边长可以确定,分别称之为金字塔的高和宽。
为了便于理解,单位统一取米。现在小明有nn个金字塔,已知它们的高和宽,小明打算重铸,想将它重铸成两个体积一样的物体。
当然,小明是城会玩,不会简单的把所有金字塔融了再分,他有一把屠龙刀,该刀削金如泥。
他现在把所有金字塔正放(即底面贴地放)在水平地面上,用屠龙刀切割一个平面,该平面与水平面平行,称之为割平面。
我们的任务是找到一个这样的割平面,使得这个割平面上方的体积之和等于下方的体积之和,该割平面称之为平均割平面。求平均割平面的高度。
Input
第一行输入一个整数TT,表示TT组数据( 1 \leq T \leq100 )(1≤T≤100)。
每组数据有三行,第一行有一个整数nn,表示金字塔的个数( 1 \leq n \leq 10000 )(1≤n≤10000)。
第二行有nn个整数A_iAi,分别表示第ii个金字塔的高度( 1 \leq A_i \leq 1000)(1≤Ai≤1000)。
第三行有nn个整数B_iBi,分别表示第ii个金字塔的宽度(1 \leq B_i \leq 100 )(1≤Bi≤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); } }