当前位置: 首页 > news >正文

洛谷题单指南-进阶数论-CF582A GCD Table

原题链接:https://www.luogu.com.cn/problem/CF582A

题意解读:已知数列中每两个数的GCD(包括自己和自己的GCD),求原数列有哪些数。

解题思路:

由于GCD(a, b) <= min(a, b),

那么初始情况下GCD表中最大的数一定是数列中的数,

将最大的数从GCD表中移除,让后看剩下的数中最大的数,第二大的数也一定是数列中的数,

再把第二大的数移除,看第三大的数,第三大的数有可能是第一大的数和第二大的数的GCD,不能断定就是最大的数,

那么这样操作一下,将第一大和第二大的数的GCD也都移除,再看剩下的数里最大的数,必然是数列中的数。

因此,算法可以描述为:

1、将GCD表排序,用map记录每个数的个数

2、取最大的数,将此数移除(移除用map的个数减少来表示)

3、将此时最大的数和已经加入答案的数的GCD都移除

4、将此最大数加入答案

5、重复2操作

100分代码:

#include <bits/stdc++.h>
using namespace std;const int N = 505;
int g[N * N];
unordered_map<int, int> mp;//记录某个数的出现次数
int ans[N], cnt;
int n;int gcd(int a, int b)
{return b == 0 ? a : gcd(b, a % b);
}   int main()
{cin >> n;for(int i = 1; i <= n * n; i++) {cin >> g[i];mp[g[i]]++;}sort(g + 1, g + n * n + 1, greater<int>());for(int i = 1; i <= n * n; i++){int x = g[i];if(mp[x] == 0) continue; //已经删除的,跳过mp[x]--;for(int i = 1; i <= cnt; i++){int d = gcd(ans[i], x);mp[d] -= 2;}ans[++cnt] = x;if(cnt == n) break;}for(int i = 1; i <= n; i++) cout << ans[i] << " ";return 0;
}

 

http://www.fuzeviewer.com/news/87/

相关文章:

  • 2025年10月美国投资移民机构推荐榜:权威机构综合对比分析
  • 2025 年企业级 GPU 服务器,8 卡风扇 GPU 服务器,大模型训练 GPU 服务器厂家最新推荐,技术实力与市场口碑深度解析
  • 揭秘 MCP Streamable HTTP 协议亲和性的技术内幕
  • 2025年10月EB5投资移民中介评测榜:客观数据支撑的专业推荐
  • 2025年10月EB5投资移民中介评价报告:五强机构深度解析
  • 2025年氨水换热器源头厂家权威推荐榜单:板式换热器/缠绕管换热器/螺旋板换热器源头厂家精选
  • 权威媒体:得帆信息连续两年领跑iPaaS市占率