牛客月赛57-D-最大gcd

链接:https://ac.nowcoder.com/acm/contest/40229/D
来源:牛客网

题目描述 
给一个长度为 n 的序列a:a1,a2 ⋯an 。
定义序列的最大 gcd 为:每次选择两个正整数 i,j(1≤i<j≤n),最大的gcd(ai,aj) 即为这个序列的最大 gcd。


输入描述:
第一行一个整数 n(2≤n≤1×10e6)。
第二行 n 个正整数 a1,a2,a3,⋯,an(1≤ai≤10e6),表示序列 a。

输出描述:
一个整数,表示这个序列的最大 gcd。

 当一个数g是一个数num的因数时,可以得出k*g = num,因此只要开个标记用的数组,记录给定的数组中的每一个数及出现次数,并枚举k和g,如果k*g的值存在于标记数组中,并总的出现次数大于等于2,则g是给定数组的公因数。 求出最大的g即可。


时间复杂度:首先要枚举g,从1到1e6(最坏情况),然后枚举k, 因为k*g<1e6, 所以时间复杂度为 n*(1e6/1+1e6/2+...+1e6/1e6),由于括号里的式子是调和级数,值约等于
1e6ln(n), 所以时间复杂度为O(nlogn)。

代码如下:

#include<iostream>
const int N = 1e6 + 5;
using namespace std;
int nums[N];
int fg[N] {0};
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0), cout.tie(0);
	int n;
	cin >> n;
	int maxv = 0;
	for(int i=0; i<n; i++) cin >> nums[i], fg[nums[i]] ++; //用数组记录每一个数
	for(int g=1; g<N; g++)
	{
		int sum = 0;
		for(int k=1; k*g<N; k++) 
			sum += fg[k*g];
		if(sum>=2) maxv = max(maxv, g); //当sum>=2时,说明至少有两个数的最大公约数是g
	}
	cout << maxv << endl;
	return 0;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值