题目:
问题描述
你要写一个程序,使得能够模拟在长方体的盒子里放置球形的气球。
接下来是模拟的方案。假设你已知一个长方体的盒子和一个点集。每一个点代表一个可以放置气球的位置。在一个点上放置一个气球,就是以这个点为球心,然后让这个球膨胀,直到触及盒子的边缘或者一个之前已经被放置好的气球。你不能使用一个在盒子外面或者在一个之前已经放置好的气球里面的点。但是,你可以按你喜欢的任意顺序使用这些点,而且你不需要每个点都用。你的目标是按照某种顺序在盒子里放置气球,使得气球占据的总体积最大。
你要做的是计算盒子里没被气球占据的体积。
接下来是模拟的方案。假设你已知一个长方体的盒子和一个点集。每一个点代表一个可以放置气球的位置。在一个点上放置一个气球,就是以这个点为球心,然后让这个球膨胀,直到触及盒子的边缘或者一个之前已经被放置好的气球。你不能使用一个在盒子外面或者在一个之前已经放置好的气球里面的点。但是,你可以按你喜欢的任意顺序使用这些点,而且你不需要每个点都用。你的目标是按照某种顺序在盒子里放置气球,使得气球占据的总体积最大。
你要做的是计算盒子里没被气球占据的体积。
输入格式
第一行包含一个整数n表示集合里点的个数(1≤n≤6)。第二行包含三个整数表示盒子的一个角落的(x,y,z)坐标,第三行包含与之相对的那个角落的(x,y,z)坐标。接下来n行,每行包含三个整数,表示集合中每个点的(x,y,z)坐标。这个盒子的每维的长度都是非零的,而且它的边与坐标轴平行。
输出格式
只有一行,为那个盒子没被气球占据的最小体积(四舍五入到整数)。
样例输入
2
0 0 0
10 10 10
3 3 3
7 7 7
0 0 0
10 10 10
3 3 3
7 7 7
样例输出
774
数据规模和约定
所有坐标的绝对值小于等于1000
对于20%的数据:n=1
对于50%的数据:1≤n≤3
对于100%的数据:1≤n≤6
对于20%的数据:n=1
对于50%的数据:1≤n≤3
对于100%的数据:1≤n≤6
题目分析:
几何计算,用到STL中全排列next_permutation来进行枚举。注意排除气球内部和盒子外的点。(然而不知道还有哪里欠考虑,欢迎指正)
题目分析:
1 #include<iostream> 2 #include<cmath> 3 #include<algorithm> 4 #include<cstring> 5 #define PI 3.1415926 6 using namespace std; 7 int n; //输入的点数量 8 int c; //坐标在盒子内部的点数量 9 int sx,sy,sz; //起始坐标 10 int ex,ey,ez; //对角坐标 11 int x[6],y[6],z[6]; //点的坐标 12 int order[6]={0,1,2,3,4,5}; //气球膨胀的顺序 13 int r[6]; //气球对应膨胀的半径 14 float vmax; //最大体积 15 int ans; //四舍五入后的最终结果 16 float min(float dist[]){ 17 float mindist=1000.0; 18 for(int i=0;i<7;i++){ 19 if(mindist>dist[i]){ 20 mindist=dist[i]; 21 } 22 } 23 return mindist; 24 } 25 26 int main(){ 27 cin>>n; 28 cin>>sx>>sy>>sz; 29 cin>>ex>>ey>>ez; 30 vmax=0.0; 31 c=0; 32 for(int i=0;i<n;i++){ 33 int xtemp,ytemp,ztemp; //筛选出在盒子内的点 34 cin>>xtemp>>ytemp>>ztemp; 35 if(xtemp>min(sx,ex)&&xtemp<max(sx,ex)&& 36 ytemp>min(sy,ey)&&ytemp<max(sy,ey)&& 37 ztemp>min(sz,ez)&&ztemp<max(sz,ez)){ 38 x[c]=xtemp; 39 y[c]=ytemp; 40 z[c]=ztemp; 41 c++; 42 } 43 } 44 do{ 45 memset(r,0,sizeof(r)); 46 float vtemp=0.0; 47 for(int i=0;i<c;i++){ 48 float tempdist[7]; 49 tempdist[0]=(float)abs(sx-x[i]); 50 tempdist[1]=(float)abs(sy-y[i]); 51 tempdist[2]=(float)abs(sz-z[i]); 52 tempdist[3]=(float)abs(ex-x[i]); 53 tempdist[4]=(float)abs(ey-y[i]); 54 tempdist[5]=(float)abs(ez-z[i]); 55 tempdist[6]=1000.0; 56 for(int j=0;j<i;j++){ //与其它气球的最近距离 57 float temp=sqrt(pow((x[i]-x[j]),2)+pow((y[i]-y[j]),2)+pow((z[i]-z[j]),2))-r[j]; 58 tempdist[6]=min(tempdist[6],temp); 59 } 60 r[i]=min(tempdist); 61 if(r[i]>0){ //如果一个点在气球内部,就会出现负数的情况,此点不能算入 62 vtemp+=4.0/3.0*PI*pow(r[i],3); 63 } 64 } 65 if(vtemp>vmax){ 66 vmax=vtemp; 67 } 68 }while(next_permutation(order,order+c)); //全排列,对气球膨胀顺序枚举 69 int vsquare=abs((sx-ex)*(sy-ey)*(sz-ez)); 70 ans=(int)((double)vsquare-vmax+0.5); //四舍五入 71 cout<<ans<<endl; 72 return 0; 73 }