一道数论好题(math)
Time Limit:1000ms Memory Limit:128MB
题目描述
rsy最近在研究欧几里得算法,不会的同学可以去看下课件以及代码……
现在她想到了一个新的问题,求k个数的最大公约数!
事实上这个问题仍然很简单。所以rsy想强化一下,她觉得最大公约数等于1就不是很有趣了。因此她想在n个数中找最多的数,使得它们的最大公约数不等于1。
现在rsy想知道,能找最多多少个数。
输入格式(math.in)
第一行一个数n。
第二行n个数ai。
输出格式(math.out)
一个数表示答案。
输入样例
5 2 3 4 5 6
输出样例
3
数据范围
对于30%的数据n<=5。
对于50%的数据n<=20。
对于80%的数据n<=1000,ai<=1000。
对于100%的数据1<=n<=100000,1<=ai<=100000,数据几乎是随机的。
我一开始做的时候想到了一些奇奇怪怪的想法,得了70,WA了一个,TLE了两个(莫名其妙)。
正确打开方式应该是这样的:
我们枚举从2到输入的数中最大的数作为所要选择的数的最大公约数。
然后看看有几个数是这个数的倍数。
到最后存下最大值就OK了。
主要看这一行操作
for(int j=i; j<=maxn; j+=i)
万能的主啊,请看我的代码
#include <iostream> #include <cstdio> using namespace std; int n, ans, maxn; int s[100008]; int a[100008]; int main() { scanf("%d", &n); for(int i=1; i<=n; i++) { scanf("%d", &s[i]); a[s[i]]++; maxn = max(maxn, s[i]); } for(int i=2; i<=maxn; i++) { int sum = 0; for(int j=i; j<=maxn; j+=i) { if(a[j]) { sum += a[j]; } } ans = max(sum, ans); } printf("%d", ans); }