14.水晶球

Description

和许多同龄女孩子一样,久莲也喜欢水晶球。还有 天,就是心心念念的他生日了。久莲希望把全世界最大最好看的水晶球送给他。她找到了宝石收藏家亚瑟斯,希望能够寻求他的帮助。亚瑟斯很快被打动了,拿出了精心收集的 块美丽的水晶石,这些水晶石初始是长宽高分别为 的长方体。亚瑟斯许诺久莲可以从中取走 块水晶石作为她礼物的原材料。同时亚瑟斯有一种魔法,如果这两块长方形水晶石在某一个面能够完美的契合在一起(完美的契合是指这两个长方形面全等),那么可以将它们融合成一块完整的大石头,如果真的实现的话,那么久莲就可能打磨出更大的水晶球啦!久莲太希望把最美最大的水晶球送给他了,你快帮帮她如何选择吧。

Input

第一行输入一个正整数 n <1e5 ;接下来 n 行中,第 i 行输入三个正整数 ai, bi, ci <1e9表示第 i 块水晶石的长宽高。注意可能有两个长得一模一样的水晶石,但是在这种情况下还是将它们视作是两块不同的水晶石。

Output

第一行请输出一个正整数 k (1 或 2 ),表示久莲选择的水晶球数量。第二行请输出 k 个正整数,如果 k=1,请输出一个正整数 表示久莲选择的水晶石。如果 k=2 ,则请输出两个正整数 x,y(用空格间隔),表示久莲希望亚瑟斯帮她将编号为x 和 y的水晶石融合成一块更大的水晶石,并选择用这块水晶石来打磨加工。请注意,这两块水晶石必须满足 “完美契合” 的条件,否则这个选择不合法。如果有多种最优的选择,则你可以输出任意一种合法的最优方案。

Hint

对于样例,如果久莲选择第六个水晶球,那么她可以打磨成半径为 2.5 的水晶球,这是最优的选择。

测试输入期待的输出时间限制内存限制额外进程
测试用例 1以文本方式显示
  1. 6↵
  2. 1 2 3↵
  3. 4 1 1↵
  4. 4 2 3↵
  5. 4 2 3↵
  6. 4 3 3↵
  7. 5 5 5↵
以文本方式显示
  1. 1↵
  2. 6↵
1秒64M0

思路

排序时应按照 mid>max>min的顺序降序排列才行。

简单说下思路。限制水晶球大小的只能是最短边。输入时给长宽高排序。建议使用结构体,同时将序号一并保存,调用qsort按上述优先级排序。

先找单块水晶最短边的最大值,记录下来。再找mid和max吻合的水晶(其他吻合方式无法让最短边变长)。注意比较新的最短边是原min之和还是原mid,并记录融合水晶最短边的最大值。

最后比较单块和融合输出即可。2块水晶序号顺序无影响。

代码


#include<stdio.h>
#include<stdlib.h>
struct solid{
	int min;
	int mid;
	int max;
	int place;
};
typedef struct solid node;
node box[100010];
int n,max1=0,z,max2=0,x,y;

int cmp( const void *a , const void *b )
{
	node *c = (node *)a; 
	node *d = (node *)b; 
	if(c->mid != d->mid)	return d->mid - c->mid;
	else if(c->max != d->max)	return d->max - c->max;
	else	return d->min - c->min;
}

void input(int i)
{
	int a,b,c,temp;
    scanf("%d %d %d",&a,&b,&c);
    if(a>b) temp=a,a=b,b=temp;
    if(b>c) temp=b,b=c,c=temp;
    if(a>b) temp=a,a=b,b=temp;
    //printf("%d %d %d\n",a,b,c);
    box[i].min=a;
    box[i].mid=b;
    box[i].max=c;   
    box[i].place=i;  
	
	if(a>=max1){
		max1=a;
		z=i;
	} 
}

void merge()
{
	int i=1,j,temp;
	while(i<n){
		j=i+1;
		while(box[j].mid==box[i].mid){
			if(box[j].max==box[i].max){
				temp=box[j].min+box[i].min;
				temp=(temp<box[i].mid)?temp:box[i].mid;
				if(temp>=max2){
					max2=temp;
					x=box[i].place;
					y=box[j].place;
				}
			}
			j++;
		}
		i=j;
	}
}
main()
{
	int i;
	scanf("%d",&n);
	for(i=1;i<=n;i++)
		input(i);		
	
	qsort(box+1,n,sizeof(node),cmp);
	//for(i=1;i<=n;i++)
	//printf("%d %d %d  %d\n",box[i].min,box[i].mid,box[i].max,box[i].place);		
	merge();
	
	if(max1>max2){
		printf("1\n%d\n",z);
	}
	else{
		printf("2\n%d %d\n",x,y);
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

北辰2023

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值