问题概述
在一个神秘的森林里,住着一个小精灵名叫小蓝。有一天,他偶然发现了一个隐藏在树洞里的宝藏,里面装满了闪烁着美丽光芒的宝石。这些宝石都有着不同的颜色和形状,但最引人注目的是它们各自独特的 “闪亮度” 属性。每颗宝石都有一个与生俱来的特殊能力,可以发出不同强度的闪光。小蓝共找到了 NN 枚宝石,第 ii 枚宝石的 “闪亮度” 属性值为 HiHi,小蓝将会从这 NN 枚宝石中选出三枚进行组合,组合之后的精美程度 SS 可以用以下公式来衡量:
S=HaHbHc⋅LCM(Ha,Hb,Hc)LCM(Ha,Hb)⋅LCM(Ha,Hc)⋅LCM(Hb,Hc)S=HaHbHc⋅LCM(Ha,Hb)⋅LCM(Ha,Hc)⋅LCM(Hb,Hc)LCM(Ha,Hb,Hc)
其中 LCMLCM 表示的是最小公倍数函数。
小蓝想要使得三枚宝石组合后的精美程度 SS 尽可能的高,请你帮他找出精美程度最高的方案。如果存在多个方案 SS 值相同,优先选择按照 HH 值升序排列后字典序最小的方案。
输入格式
第一行包含一个整数 NN 表示宝石个数。
第二行包含 NN 个整数表示 NN 个宝石的 “闪亮度”。
输出格式
输出一行包含三个整数表示满足条件的三枚宝石的 “闪亮度”。
样例输入
5
1 2 3 4 9
样例输出
1 2 3
评测用例规模与约定
对于 30%30% 的评测用例:3≤N≤100,1≤Hi≤10003≤N≤100,1≤Hi≤1000 。
对于 60%60% 的评测用例:3≤N≤20003≤N≤2000 。
对于 100%100% 的评测用例:3≤N≤105,1≤Hi≤1053≤N≤105,1≤Hi≤105 。
解决方案
#include<iostream>
#include<set>
using namespace std;
typedef long long LL;
const int maxn=1e5+5;
//const int inf=0x3f3f3f3f;
int n,a[maxn],b[4];
multiset<int>s;
int main()
{
int i,c,j,k;
scanf("%d",&n);
for(i=1;i<=n;i++){
scanf("%d",&a[i]),s.insert(a[i]);
}
for(i=maxn-5;i>=1;i--)
{
c=0;
for(j=i;j<=maxn&&c<=2;j+=i){
for(k=1;k<=s.count(j)&&c<=2;k++){
b[++c]=j;
}
}
if(c==3) break;
}
printf("%d %d %d\n",b[1],b[2],b[3]);
return 0;
}
对于这道题目,应先简化一下s,方便后续运行,证明过程参考大佬,最后得出s=gcd(a,b,c)。由于数据范围是1e5,所以分别枚举a,b,c,应该会超时。但可以枚举s,使用set中的multiset来查重ks,检查s是否满足条件且字典序最小。如此优化,时间复杂度减少,应该不会超时。