约数的个数等于分解质因数后幂次加一的累乘。
这题用分解质因数方法做,求约数个数加一的时候最后的特例忘了加一,直接导致犯了一堆智障错误,现在想想好简单一道题。。。还特地用了后面那道杭电题验证。。等等,那个题因为质因子数少不需要特例。。。T T
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <string>
#include <cstring>
#include <vector>
#include <stack>
#include <cctype>
#include <cmath>
#include <climits>
using namespace std;
const int MAXN = 100005;
const int INF = INT_MAX;
bool isPrime[MAXN];
vector<int> prime;
void Initial(){
for(int i = 2; i < MAXN; i++){
isPrime[i] = true;//打假
}
for(int i = 2; i < MAXN; i++){
if(!isPrime[i]) continue;
prime.push_back(i);
for(int j = i*i; j < MAXN; j += i){
if(isPrime[j]) isPrime[j] = false;
}
}
}
int main(){
// freopen("in.txt", "r", stdin);
int N;
Initial();
while(~scanf("%d", &N)){
if(N == 0) break;
while(N--){
long long x;
int ans = 1;
scanf("%lld", &x);
for(int i = 0; (i < prime.size()) && (prime[i] <= x); i++){
int factor = prime[i];
int time = 0;
while(x % factor == 0){
x /= factor;
time++;
}
time++;
ans *= time;
}
if(x > 1) ans *= 2;
printf("%d\n", ans);
}
}
return 0;
}
另外这题还有另外一种做法(看了题解),不用素数筛,直接暴力,只不过暴力根号后的范围,这样的确简单,不过时间花费较多,而且需要多一些思考。。
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <string>
#include <cstring>
#include <vector>
#include <stack>
#include <cctype>
#include <cmath>
#include <climits>
using namespace std;
const int MAXN = 10005;
const int INF = INT_MAX;
int main(){
// freopen("in.txt", "r", stdin);
int N;
while(~scanf("%d", &N)){
if(N == 0) break;
while(N--){
long long x;
int num = 0;
scanf("%lld", &x);
int i;
for(i = 1; i*i < x; i++){
if(x % i == 0) num += 2;
}
if(i*i == x) num++;
printf("%d\n", num);
}
}
return 0;
}
http://acm.hdu.edu.cn/showproblem.php?pid=1492
求约数个数,将其分解质因数后对质因数的个数加一后相乘,用的组合思想,之所以加一是因为还要考虑0次幂。
这个题只是为了验证方法做的测试题。。
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <string>
#include <cstring>
#include <vector>
#include <stack>
#include <cctype>
#include <cmath>
#include <climits>
using namespace std;
const int MAXN = 105;
const int INF = INT_MAX;
bool isPrime[MAXN];
vector<int> prime;
void Initial(){
for(int i = 2; i < MAXN; i++){
isPrime[i] = true;//打假
}
for(int i = 2; i < MAXN; i++){
if(!isPrime[i]) continue;
prime.push_back(i);
for(int j = i*i; j < MAXN; j += i){
if(isPrime[j]) isPrime[j] = false;
}
}
}
int main(){
// freopen("in.txt", "r", stdin);
long long N;
Initial();
while(~scanf("%lld", &N)){
if(N == 0) break;
int ans = 1;
for(int i = 0; (i < prime.size()) && (prime[i] <= N); i++){
int factor = prime[i];
int time = 0;
while(N % factor == 0){
N /= factor;
time++;
}
time++;
ans *= time;
}
printf("%d\n", ans);
}
return 0;
}