题目
思路1:map
每输入一个数就将它所有的约数个数+1,最后找到最后一个约数个数>=k的数,输出它的下标即可。
注意:用map的原因是在这里用到了桶的思想,只用普通数组会爆空间。(输入的数最大是1000000000)
#include <bits/stdc++.h>
using namespace std;
map<int,int> mp;
int n,k,a,ans;
int main()
{
scanf("%d%d",&n , &k);
for(int i = 1;i <= n;i ++ )
{
cin>>a;
for(int j = 1; j <= a / j;j++)
{
if(a % j == 0)
{
mp[j]++;
if(j * j != a) mp[a / j] ++ ;
}
}
}
for(auto it = mp.begin();it != mp.end();it++)
if(it->second >= k)
ans = max(ans,it->first);
cout<<ans;
return 0;
}
思路2:数组
可以发现,上述思路要用map的原因就是用了桶的思路来记录约数个数。那么,我们能否不用桶的思路来记录各个约数个数呢?可以!只不过有些复杂~
先将所有约数记录在一个数组yue[]中(不用去重),再排序。
然后再用y[i]储存第i个约数,gs[i]储存y[i]在yue[]中出现的个数,最后最后找到最后一个约数个数(gs[i])>=k的数,输出它所对应的约数(y[i])即可
#include <bits/stdc++.h>
using namespace std;
int yue[10000001],gs[10000001],y[10000001],ys = 1,gss = 1,n,k,a,ans;
int main()
{
scanf("%d%d",&n,&k);
for(int i = 1; i <= n; i++)
{
cin>>a;
for(int j = 1; j <= a / j; j++)
{
if(a % j == 0)
{
yue[ys++] = j;
if(j * j != a) yue[ys++] = a / j;
}
}
}
ys--;
sort(yue + 1,yue + 1 + ys);
y[1] = 1;
gs[1] = 1;
for(int i = 2; i <= ys; i++)
if(yue[i] == yue[i - 1]) gs[gss]++;
else y[++gss] = yue[i],gs[gss] = 1;
for(int i = 1; i <= gss; i++)
if(gs[i] >= k)
ans = max(ans,y[i]);
cout<<ans;
return 0;
}