计算机历年考研复试上机题-约数的个数
题目描述
输入n个整数,依次输出每个数的约数的个数
输入描述:
输入的第一行为N,即数组的个数(N<=1000) 接下来的1行包括N个整数,其中每个数的范围为(1<=Num<=1000000000) 当N=0时输入结束。
输出描述:
可能有多组输入数据,对于每组输入数据, 输出N行,其中每一行对应上面的一个数的约数的个数。
示例1
输入
5 1 3 4 6 12
输出
1 2 3 4 6
解题思路
开始的时候把题目想的太复杂了,心想能够使用质因数分解然后依次累乘质因数的幂即可,后来发现自己的思路不对,然后想到了最简单的暴力求解方式,由于数据太大,我们需要开根才不会导致超时。
解题代码
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include<vector>
#define rep(i,s,e) for(int i = s;i<e;i++)
using namespace std;
typedef long long ll;
const int maxn = 100000;
bool vis[maxn];
int p[maxn];
int ct = 0;
void getP(){
vis[2] = true;
rep(i,2,maxn+1){
if(vis[i]==true){
for(int j = 2*i;j<=maxn;j+=i){
vis[j] = false;
}
}
}
rep(i,2,maxn+1){
if(vis[i]){
p[ct++] = i;
}
}
}
ll getSum(ll n){
ll sum = 1;
rep(i,0,ct){
int t = 0;
if(n==p[i]){
sum*=2;
return sum;
}
while(n%p[i]==0&&n!=0&&n!=1){
n/=p[i];
t++;
}
sum*=t+1;
if(n==0||n==1) return sum;
}
return sum;
}
ll getSum2(ll n){
ll x = sqrt(n);
ll sum = 2;
rep(i,2,x+1){
if(n%i==0&&i*i!=n) sum+=2;
else if(n%i==0&&i*i==n) sum+=1;
}
return sum;
}
int main(){
rep(i,0,maxn) vis[i] = true;
getP();
ll n;
while(cin>>n){
vector<ll>sums;
sums.clear();
rep(i,0,n){
ll num;
cin>>num;
sums.push_back(num);
}
rep(i,0,n){
if(sums[i]==1) cout<<1;
else cout<<getSum2(sums[i]);
cout<<endl;
}
}
}