sincerit 约数的个数

题目描述
输入n个整数,依次输出每个数的约数的个数
输入描述:
输入的第一行为N,即数组的个数(N<=1000)
接下来的1行包括N个整数,其中每个数的范围为(1<=Num<=1000000000)
当N=0时输入结束。
输出描述:
可能有多组输入数据,对于每组输入数据,
输出N行,其中每一行对应上面的一个数的约数的个数。
示例1
输入
复制
5
1 3 4 6 12
输出
复制
1
2
3
4
6

筛法解释: https://blog.csdn.net/controlbear/article/details/77527115
一般的方法会超时,找到一个约数个数定理,约数个数定理可以计算出一个数约数的个数
假设要求的数是m
m=(p1)(x1)*(p2)(x2)(p3)^(x3)……
其中p1,p2,p3…是质数(素数),x1,x2,x3…是它们的指数
则m的约数的个数是(x1+1)(x2+1)(x3+1)……
例如24=(2^3) * (3^1)—分解成质因子的形式
所以其约数的个数为(3+1)
(1+1)=8个

突然发现题目的数据太大,这个数组没法开到那么大
代码还是贴在这里,碰到数据小的就可以用这个代码了,后面还有求约数和的问题

#include <stdio.h>
typedef long long ll;
const ll N = 1e5+5;

ll prim[N];  // 表示第N个素数 
ll num[N];  // 表示N的最小因子的个数 
ll d[N];   // 表示N的因子的个数
// 打表 求1到n每个数的约数个数 

void getNum() {
  ll mark[N] = {0};
  int cnt = 0; // 记录第几个素数
  d[1] = 1;
  for (int i = 2; i < N; i++) { 
    if (mark[i] == 0) {
      prim[cnt++] = i;
      d[i] = 2;
      num[i] = 1;
    }
    for (int j = 0; j < cnt && i*prim[j] < N; j++) {
      mark[i*prim[j]] = 1; // i*prim[j]不是素数
      if (i % prim[j] == 0) {
        num[i*prim[j]] = num[i] + 1;
        d[i*prim[j]] = d[i] / (num[i]+1) * (num[i]+2);
        break; // 找到最小素因子即可  
      }
      d[i*prim[j]] = d[i] * d[prim[j]];
      num[i*prim[j]] = 1;
    }
  } 
}

int main() {
  ll n, x;
  getNum();
  scanf("%lld", &n);
  for (int i = 1; i <= n; i++) {
    scanf("%lld", &x);
    printf("%lld\n", d[x]);
  }
  return 0;
}
#include <stdio.h>
#include <math.h> 
int main() {
  long long n, x, i, j;
  scanf("%lld", &n);
  for (i = 1; i <= n; i++) {
    scanf("%lld", &x);
    long k = long (sqrt(x));
    long long sum = 0; // 3 25
    for (j = 1; j*j <= x; j++) {
      if (x % j == 0) sum += 2; 
    }
    if (x == k * k) sum--;
    printf("%lld\n", sum);
  }
  return 0;
}

求一个数的质因子个数,用一般的方法超时,这个就过了

#include <stdio.h>
int isprim(int k) {
  for (int i = 2; i * i <= k; i++) {
    if (k % i == 0) return 0;
  }
  return 1;
}
int main() {
  long long m;
  while (~scanf("%lld", &m)) {
    long long sum = 0;
    for (int i = 2; i * i <= m; i++) {
      if (isprim(i)) {
        while (m % i == 0) {
          m /= i;
          sum++;
        } 
      }
    }
    if (m > 1) sum++;
    printf("%lld\n", sum);
  }
  return 0;
}

猜你喜欢

转载自blog.csdn.net/sincerit/article/details/85216480