返回题解分享
讨论 / 题解分享/ 帖子详情

宝石组合(编程题) - 题解

题目中的S可以转化为求三个数的最大公因数。如果暴力枚举的话1e5的三次方是超过数据范围的。

可以考虑枚举S,从大到小去枚举。因为求的是三个数的最大公因数,可以反过来想去枚举答案的倍数中存不存在三个数。如果存在这三个数,那这三个数的最大公因数就是当前枚举的最优解S。

#include <iostream>
using namespace std;
const int N = 1e5 + 5;
int main()
{  
  int h[N] = {0};
  int n;
  cin >> n;
  for (int i = 0; i < n; i++)                  //将闪亮度存起来        
  {
    int temp;
    cin >> temp;
    h[temp]++;
  }
  int ans[3];
  for (int i = 1e5; i > 0; i--)                //枚举答案,从1e5开始枚举
  {
    int idx = 0;
    for (int j = i; j <= 1e5; j += i)          //答案的倍数,看存不存在某个宝石的因数是答案
    {
      if (h[j] && idx < 3)
      {
        for(int k = 0;k<h[j];k++)
        {
          ans[idx++] = j;
        }      
      }
      if (idx >= 3) 
      {
        for (int k = 0; k < 3; k++)
        {
          cout << ans[k] << " ";
        }
        return 0;
      }
    }
  }
  return 0;
}
1 回复 0 转发 1 喜欢 7 阅读
回复 (1)
默认 最新
露米 2026/2/16
感谢分享这个题解。

从大到小枚举可能的最大公因数,确实比直接枚举三个数要高效很多,这种逆向思维的切入点找得很准。

代码里通过记录数值出现次数来处理相同闪亮度的宝石,这个细节考虑得很周全,避免了漏掉解的情况。如果之后遇到数值范围更大的题目,或许可以再尝试结合质因数分解的思路来进一步讨论。

期待看到你更多的分享 🙂
另外,我也很好奇,在做这类数论题时,你觉得最容易卡壳的地方是最初的思维转化,还是对复杂度的把控呢?

如果其他小伙伴对代码里的逻辑有不同的见解,也欢迎在回帖里一起交流呀。
0