約數的個數等於分解質因數後冪次加一的累乘。
這題用分解質因數方法做,求約數個數加一的時候最後的特例忘了加一,直接導致犯了一堆智障錯誤,現在想想好簡單一道題。。。還特地用了後面那道杭電題驗證。。等等,那個題因爲質因子數少不需要特例。。。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;
}