Kostya the Sculptor Codeforces Round#378-D(逻辑+排序)
Kostya the Sculptor
time limit per test 3 seconds memory limit per test 256 megabytes
inputstandard input outputstandard output
Kostya 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.
传送门:CF733D
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.Sample Input
1
2
3
4
5
6
7 6
5 5 5
3 2 4
1 4 1
2 1 3
3 2 4
3 3 4Sample Output
1
2 1
1题解
本道题的难点就在于如何统计两个Stone合并起来的最短边长为多少,如果按普通的查找是O(n^2)的,会超时。 这道题的技巧在于把长方体排过序后合并的长方体必然是相邻的! 所以,排序O(nlogn),搜索只要O(n),总体是O(nlogn)级别的。那么怎么做那,首先将每个长方体的三条边由小到大排序,然后对于每个长方体,按最长边为最高优先级把所有的长方体进行排序。这样排好序后只要看相邻的两个长方体是否能合并,如果能合并,再找出合并后的最小边就行了。 注意还有一个坑,如果现在长方体1:a1,b,c,长方体2:a2,b,c,那么这两个长方体可以合并。但是合并后最短的边不一定就是a1+a2,还需要与b和c进行比较。## AC code:(不包含输入类)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82 import java.io.*;
import java.util.*;
public class Main {
static class Stone implements Comparable<Stone>{
int a,b,c,position;
Stone(int a,int b,int c,int d){
this.a=a;
this.b=b;
this.c=c;
this.position=d;
}
Stone(){
}
public int compareTo(Stone s) {
if(this.c<s.c)
return -1;
else if(this.c>s.c)
return 1;
else if(this.b<s.b)
return -1;
else if(this.b>s.b)
return 1;
else if(this.a<s.a)
return -1;
else if(this.a>s.a)
return 1;
else
return 0;
} //长方体排序的基础
}
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
while(sc.hasNext()){
int n=sc.nextInt();
int max=-1;
int index=0;
Stone []s=new Stone[n];
int flag=0;
int jg1=0;
int jg2=0;
int shu[]=new int[3];
for(int i=0;i<n;i++){
shu[0]=sc.nextInt();
shu[1]=sc.nextInt();
shu[2]=sc.nextInt();
Arrays.sort(shu); //将长方体的三条边按从小到大排序
s[i]=new Stone(shu[0],shu[1],shu[2],i+1);
if(max<shu[0]){
index=i+1;
max=shu[0];
} //遍历找只用一个长方体时最短的半径
}
Arrays.sort(s);
for(int i=0;i<n-1;i++){
if(s[i].b==s[i+1].b&&s[i].c==s[i+1].c){ //当两个长方体能合并
int[] bj=new int [3];
bj[0]=s[i].a+s[i+1].a;
bj[1]=s[i].b;
bj[2]=s[i].c;
Arrays.sort(bj); //找出合并后的最短边长
if(bj[0]>max){
flag=1;
max=bj[0];
jg1=s[i].position;
jg2=s[i+1].position;
}
}
}
if(flag==1){
System.out.println(2);
System.out.println(jg1+" "+jg2);
}
else
{
System.out.println(1);
System.out.println(index);
}
}
}
}