Kostya the Sculptor(贪心
这题本来 想二分。想了很久很久,解决不了排序和二分的冲突。 用贪心吧。。
题意:
给你n个长方形,让你找出2个或1个长方体,使得他们拼接成的长方体的内接球半径最大(这是要求最短边越大越好)(两个矩形拼接的条件是
他们有一个面完全相同)
输入n,输入第 i个长方体的 三条边长度。最多2个长方体拼接。
输出 不要拼接的"1"和最大能切成内切球的 i ;或者输出要拼接的“2”和这两个长方体的序号 i 。
如果 两个长方体的边长分别是 3 2 4,3 2 4 。可以拼接成 6 2 4,3 2 8,3 4 4;
显然 3 4 4这种拼法 内切球是最大的。(这里是 想到用贪心的起点)
给所有的长方体记录原来的位置序号,再按边长排序,(下面代码里的cmp)。这样可以保证每个长方体的第三条边都是最小的,
这样两个长方体的第三条边相加起来, 能使两个长方体的最短边得到加强。(类似木桶的短板原理)
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 #include<string> 7 #include<cmath> 8 #include<set> 9 #include<vector> 10 #include<stack> 11 #include<queue> 12 #include<map> 13 using namespace std; 14 #define ll long long 15 #define se second 16 #define fi first 17 const int INF= 0x3f3f3f3f; 18 const int N=1e5+5; 19 20 int a[3],b[3]; 21 int n,maxn=0; 22 23 struct note 24 { 25 int x,y,z; 26 int loc; 27 }q[N]; 28 29 bool cmp(note r,note t) 30 { 31 return (r.x>t.x|| 32 r.x==t.x&&r.y>t.y|| 33 r.x==t.x&&r.y==t.y&&r.z>t.z); 34 } 35 36 int main() //(3 2 4 ;3 2 4)3*2*8,6*2*4,3*4*4选的是3*4*4。 37 { 38 cin>>n; 39 int loc=0,loc1=0,loc2=0; //这是要输出的长方体位置 40 for(int i=1;i<=n;i++){ 41 scanf("%d%d%d",&a[0],&a[1],&a[2]); 42 sort(a,a+3); 43 q[i].z =a[0]; 44 q[i].y =a[1]; 45 q[i].x =a[2]; 46 q[i].loc =i; //记录原来的下标 47 if(maxn<a[0]) 48 { 49 maxn=a[0]; 50 loc=i; 51 } 52 } 53 sort(q+1,q+1+n,cmp); 54 int sign=0; 55 56 for(int i=1;i<n;i++) 57 { 58 if(q[i].x==q[i+1].x && q[i].y==q[i+1].y) 59 { 60 b[0]=q[i].x; b[1]=q[i].y; b[2]=q[i].z+q[i+1].z; 61 sort(b,b+3); 62 if(maxn<b[0]) 63 { 64 maxn=b[0]; 65 loc1=q[i].loc; 66 loc2=q[i+1].loc; 67 sign=1; 68 } 69 } 70 } 71 if(sign){ 72 cout<<2<<endl; 73 cout<<loc1<<' '<<loc2; 74 } 75 else 76 cout<<1<<endl<<loc; 77 }