CodeForces733D Kostya the Sculptor 贪心+二分

这篇博客讨论了如何选择两个长方体,通过拼接使它们形成的长方体内接球半径最大化。策略是首先找到单个长方体的最大半径,然后通过排序和二分查找,筛选可能的长方体组合,以找到最短边最大的组合。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


Kosta is a genial sculptor, he has an idea: to carve a marble sculpture in the shape of a sphere. Kostya has a friend Zahar who works at a career. Zahar knows about Kostya's idea and wants to present him a rectangular parallelepiped of marble from which he can carve the sphere.

Zahar has n stones which are rectangular parallelepipeds. The edges sizes of the i-th of them are ai, bi and ci. He can take no more than two stones and present them to Kostya.

If Zahar takes two stones, he should glue them together on one of the faces in order to get a new piece of rectangular parallelepiped of marble. Thus, it is possible to glue a pair of stones together if and only if two faces on which they are glued together match as rectangles. In such gluing it is allowed to rotate and flip the stones in any way.

Help Zahar choose such a present so that Kostya can carve a sphere of the maximum possible volume and present it to Zahar.

Input

The first line contains the integer n (1 ≤ n ≤ 105).

n lines follow, in the i-th of which there are three integers ai, bi and ci (1 ≤ ai, bi, ci ≤ 109) — the lengths of edges of the i-th stone. Note, that two stones may have exactly the same sizes, but they still will be considered two different stones.

Output

In the first line print k (1 ≤ k ≤ 2) the number of stones which Zahar has chosen. In the second line print k distinct integers from 1 to n — the numbers of stones which Zahar needs to choose. Consider that stones are numbered from 1 to n in the order as they are given in the input data.

You can print the stones in arbitrary order. If there are several answers print any of them.

Examples
Input
6
5 5 5
3 2 4
1 4 1
2 1 3
3 2 4
3 3 4
Output
1
1
Input
7
10 7 8
5 10 3
4 2 6
5 5 5
10 2 8
4 2 1
7 7 7
Output
2
1 5
Note

In the first example we can connect the pairs of stones:

  • 2 and 4, the size of the parallelepiped: 3 × 2 × 5, the radius of the inscribed sphere 1
  • 2 and 5, the size of the parallelepiped: 3 × 2 × 8 or 6 × 2 × 4 or 3 × 4 × 4, the radius of the inscribed sphere 1, or 1, or 1.5 respectively.
  • 2 and 6, the size of the parallelepiped: 3 × 5 × 4, the radius of the inscribed sphere 1.5
  • 4 and 5, the size of the parallelepiped: 3 × 2 × 5, the radius of the inscribed sphere 1
  • 5 and 6, the size of the parallelepiped: 3 × 4 × 5, the radius of the inscribed sphere 1.5

Or take only one stone:

  • 1 the size of the parallelepiped: 5 × 5 × 5, the radius of the inscribed sphere 2.5
  • 2 the size of the parallelepiped: 3 × 2 × 4, the radius of the inscribed sphere 1
  • 3 the size of the parallelepiped: 1 × 4 × 1, the radius of the inscribed sphere 0.5
  • 4 the size of the parallelepiped: 2 × 1 × 3, the radius of the inscribed sphere 0.5
  • 5 the size of the parallelepiped: 3 × 2 × 4, the radius of the inscribed sphere 1
  • 6 the size of the parallelepiped: 3 × 3 × 4, the radius of the inscribed sphere 1.5

It is most profitable to take only the first stone. 


给一些长方体,可以将两个长方体拼起来,使得最后得到的长方体内接球半径最大,问所选取的长方体编号。

想要长方体内接球半径最大,也就是长方体最短边尽可能大。

首先遍历所有长方体,先得到只用一个长方体的最大半径值乘二,记为D;

之后对长方体进行排序,因为如果要使得拼起来的长方体最短边有可能大于D,那么长方体的第二长边就必须大于等于D,因此排序后可以先二分筛除部分长方体,

其次,只有当两个长方体的最大两边相同时,拼出来的长方体最短边有可能超过D,因此排序可以先按第二长边排,再按第一长边排,再按最短边排。

最后从二分得到的位置向后判断一遍即可。


#include <iostream>
#include <cstdio>
#include <map>
#include <set>
#include <vector>
#include <queue>
#include <stack>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <string>
using namespace std;
#define INF 0x3f3f3f3f
typedef __int64 LL;
struct node{
    LL x,y,z;
    int num;
}s[100005];
struct p{
    LL r;
    int flag;
    int num1,num2;
}ans;
bool cmp(node a,node b)
{
    if(a.y!=b.y) return a.y<b.y;
    else if(a.z!=b.z) return a.z<b.z;
    else return a.x<b.x;
}
int main()
{
    int n;
    while(cin>>n){
        LL t[3];
        ans.r=0;
        ans.flag=1;
        for(int i=0;i<n;i++){
            cin>>t[0]>>t[1]>>t[2];
            sort(t,t+3);
            s[i].x=t[0];
            s[i].y=t[1];
            s[i].z=t[2];
            s[i].num=i;
            if(t[0]>ans.r){
                ans.r=t[0];
                ans.num1=i+1;
            }
        }
        sort(s,s+n,cmp);
        int l=0;
        int r=n-1;
        int m;
        while(l<r){
            m=(l+r)/2;
            if(s[m].y<=ans.r){
                l=m+1;
            }else{
                r=m-1;
            }
        }
        for(int i=m-1;i<n-1;i++){
            if(s[i].y==s[i+1].y&&s[i].z==s[i+1].z){
                LL tt=min(s[i].x+s[i+1].x,s[i].y);
                if(ans.r<tt){
                    ans.r=tt;
                    ans.flag=2;
                    ans.num1=s[i].num;
                    ans.num2=s[i+1].num;
                }
            }
        }
        cout<<ans.flag<<endl;
        if(ans.flag==1){
            cout<<ans.num1<<endl;
        }else{
            cout<<ans.num1+1<<" "<<ans.num2+1<<endl;
        }
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值