2015final题 Cutting Cheese 二分切点+积分
2015-06-03 17:09
411 查看
题目链接:https://icpc.kattis.com/problems/cheese
Of course you have all heard of the International Cheese Processing Company. Their machine for cutting a piece of cheese into slices of exactly the same thickness is a classic. Recently they produced a machine able to cut a spherical cheese (such as Edam) into
slices – no, not all of the same thickness, but all of the same weight! But new challenges lie ahead: cutting Swiss cheese.
Swiss cheese such as Emmentaler has holes in it, and the holes may have different sizes. A slice with holes contains less cheese and has a lower weight than a slice without holes. So here is the challenge: cut
a cheese with holes in it into slices of equal weight.
By smart sonar techniques (the same techniques used to scan unborn babies and oil fields), it is possible to locate the holes in the cheese up to micrometer precision. For the present problem you may assume that
the holes are perfect spheres.
Each uncut block has size 100×100×100 where
each dimension is measured in millimeters. Your task is to cut it into s slices
of equal weight. The slices will be 100 mm
wide and 100 mm
high, and your job is to determine the thickness of each slice.
The first line of the input contains two integers n and s,
where 0≤n≤10000 is
the number of holes in the cheese, and 1≤s≤100 is
the number of slices to cut. The next n lines
each contain four positive integers r, x, y,
and z that
describe a hole, where r is
the radius and x, y,
and z are
the coordinates of the center, all in micrometers.
The cheese block occupies the points (x,y,z) where 0≤x,y,z≤100000,
except for the points that are part of some hole. The cuts are made perpendicular to the z axis.
You may assume that holes do not overlap but may touch, and that the holes are fully contained in the cheese but may touch its boundary.
Display the s slice
thicknesses in millimeters, starting from the end of the cheese with z=0.
Your output should have an absolute or relative error of at most 10−6.
Download the sample data files
题意:
给出一个固定100*100*100的正方体奶酪
正方体里有很多空心球体(完全在正方体奶酪里面)
现在需要把奶酪切片,要求每片的质量(由于密度固定,所以也是体积)一样
n个空心球体,s片
n行:球体的r x y z
思路:
二分切点,切点处的体积积分求出 F()
本人提前做一次排序预处理,让球体从前到后排序,这样切点后面的空心体对体积就无影响了。做不做提前排序其实都可以,此优化并不是很必要
Of course you have all heard of the International Cheese Processing Company. Their machine for cutting a piece of cheese into slices of exactly the same thickness is a classic. Recently they produced a machine able to cut a spherical cheese (such as Edam) into
slices – no, not all of the same thickness, but all of the same weight! But new challenges lie ahead: cutting Swiss cheese.
Swiss cheese such as Emmentaler has holes in it, and the holes may have different sizes. A slice with holes contains less cheese and has a lower weight than a slice without holes. So here is the challenge: cut
a cheese with holes in it into slices of equal weight.
By smart sonar techniques (the same techniques used to scan unborn babies and oil fields), it is possible to locate the holes in the cheese up to micrometer precision. For the present problem you may assume that
the holes are perfect spheres.
Each uncut block has size 100×100×100 where
each dimension is measured in millimeters. Your task is to cut it into s slices
of equal weight. The slices will be 100 mm
wide and 100 mm
high, and your job is to determine the thickness of each slice.
Input
The first line of the input contains two integers n and s,where 0≤n≤10000 is
the number of holes in the cheese, and 1≤s≤100 is
the number of slices to cut. The next n lines
each contain four positive integers r, x, y,
and z that
describe a hole, where r is
the radius and x, y,
and z are
the coordinates of the center, all in micrometers.
The cheese block occupies the points (x,y,z) where 0≤x,y,z≤100000,
except for the points that are part of some hole. The cuts are made perpendicular to the z axis.
You may assume that holes do not overlap but may touch, and that the holes are fully contained in the cheese but may touch its boundary.
Output
Display the s slicethicknesses in millimeters, starting from the end of the cheese with z=0.
Your output should have an absolute or relative error of at most 10−6.
Sample Input 1 | Sample Output 1 |
---|---|
0 4 | 25.000000000 25.000000000 25.000000000 25.000000000 |
Sample Input 2 | Sample Output 2 |
---|---|
2 5 10000 10000 20000 20000 40000 40000 50000 60000 | 14.611103142 16.269801734 24.092457788 27.002992272 18.023645064 |
题意:
给出一个固定100*100*100的正方体奶酪
正方体里有很多空心球体(完全在正方体奶酪里面)
现在需要把奶酪切片,要求每片的质量(由于密度固定,所以也是体积)一样
n个空心球体,s片
n行:球体的r x y z
思路:
二分切点,切点处的体积积分求出 F()
本人提前做一次排序预处理,让球体从前到后排序,这样切点后面的空心体对体积就无影响了。做不做提前排序其实都可以,此优化并不是很必要
#include<vector> #include<cmath> #include<cstring> #include<algorithm> #include<string> #include<cstdio> #include<iostream> using namespace std; const int MAX = 10000; const double esp = 1e-7; const double PI = acos(-1.0); struct H { double r,x,y,z; H(double r=0,double x=0,double y=0,double z=0):r(r),x(x),y(y),z(z) {} }; H hole[MAX+10]; int holes,slices;//空心球的数量 和 要切的片数 bool cmp(H a,H b) { return (a.z-a.r)<(b.z-b.r); } double calculus(double r,double x)//半径,到球心的距离.。返回球体小部分的体积 { return r*r*r*PI*2.0/3.0-r*r*x*PI+x*x*x*PI/3.0;//积分公式 } double F(double index) //计算切点处包含的总体积 { double weight=100*100*index; for(int i=0;i<holes;++i){ if((hole[i].z+hole[i].r)<=index) weight-=(PI*hole[i].r*hole[i].r*hole[i].r*4.0/3.0);//完全包括 else if(hole[i].z<=index&&(hole[i].z+hole[i].r)>=index) weight-=(PI*hole[i].r*hole[i].r*hole[i].r*4.0/3.0-calculus(hole[i].r,index-hole[i].z) );//大半球 else if(hole[i].z>=index&&(hole[i].z-hole[i].r)<=index) weight-=calculus(hole[i].r,hole[i].z-index); //小半球 else if((hole[i].z-hole[i].r)>index) break; } return weight; } double serch(double l,double ans) //二分切点 { double r=100.0; while(r-l>esp){ double mid=(l+r)/2.0; double f=F(mid); if(fabs(f-ans)<esp) return mid; else if(f>ans) r=mid; else l=mid; } return (l+r)/2.0; } void solve() { double sum=100.0*100.0*100.0; //奶酪总体积 for(int i=0; i<holes; ++i) { double xx,yy,rr,zz; scanf("%lf%lf%lf%lf",&rr,&xx,&yy,&zz); hole[i].r=rr/1000; hole[i].x=xx/1000; hole[i].y=yy/1000; hole[i].z=zz/1000; sum-=(PI*hole[i].r*hole[i].r*hole[i].r*4.0/3.0); } if(holes>1) sort(hole,hole+holes,cmp); //提前对球体按照最左边的z值进行排序,方便二分求体积时,超出部分的球体不用计算 double last = 0,ans=sum/slices; //last表示上一个切点 ans表示每片应该的体积 for(int i=1;i<=slices;++i) { if(i==slices) {printf("%.9lf\n",100-last);break;} //最后一个的厚度 double cur=serch(last,ans*i); printf("%.9lf\n",cur-last); //此切点减去上一个切点就是厚度 last=cur; } } int main() { //freopen("F:\\1.txt","r",stdin); while(scanf("%d%d",&holes,&slices)!=EOF) { solve(); } return 0; }
相关文章推荐
- 计算机视觉课程作业 代码说明以及源文件
- Jlink在ADS下的配置说明及常见问题解决办法 (转载)
- 使用WebFrom来模拟一些MVC的MODEL与View的数据交互功能
- .NET 4.0 任务(Task)
- Java核心API -- 3(正则表达式)
- IOS开发学习31 ObjectC 实现自定义Event
- How to completely uninstall mysql in ubuntu
- UML的分析与设计
- 类似微信朋友圈动态的数字红点
- 使用snmp4j实现Snmp功能(一)
- phpmyadmin访问远程数据库
- python-gearman使用
- Logging 日志记录最佳实践
- VC窗体透明而控件不透明以及Static文本背景透明方法
- 2015届华为校园招聘机试题一
- android 音频资料
- iOS FMDB的简单使用
- 黑马程序员-----集合框架(Map和泛型)
- Android手机tcpdump抓包
- 对HGE游戏引擎的一次封装