枚举和模拟
03 约数的个数
描述
输入 n 个整数,依次输出每个数的约数的个数。
输入格式
第一行包含整数 n
第二行包含 n个整数 ai
输出格式
共 n 行,按顺序每行输出一个给定整数的约数的个数。
数据范围
1≤n≤1000
1≤ai≤10^9
输入样例
5
1 3 4 6 12
输出样例
1
2
3
4
6
解答
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include <cmath> //为了使用根号
using namespace std;
/*
题目要求
共 n行,按顺序每行输出一个给定整数的约数的个数
输入格式
5
1 3 4 6 12
输出格式
1
2
3
4
6
*/
/*
分析
首先 题目告诉我们第一行输入的是n
也就是知道了循环次数 所以想到用for循环
其次 要写一个函数 输入数字可以知道有多少个约束
所谓约数 就是可以整除的数字
又可以用for循环枚举的方式做
*/
//原始版 这里上传oj平台时显示超时
int Yueshugeshu(int k) {
int yueshu = 0;
//任何一个数字都有的约束肯定都有1和自己
for (int i = 1; i <= k; i++) {
//说说明可以整除 那么i就是约数
if (k % i == 0) {
yueshu++;
}
}
return yueshu;
}
//优化版
int Yueshugeshu2(int k) {
int yueshu = 0;
//如果有一个约束 那么必然存在另一个
//如果一个数是平方数 那么必然有一个约束是自己开根号
//其他约束 只要知道一个 那么另一个必然唯一确定
for (int i = 1; i <= sqrt(k); i++) {
//说说明可以整除 那么i就是约数
if (k % i == 0 && i!= sqrt(k)) {//可以整除 并且不是自己开根号
yueshu = yueshu + 2;
}
if (i == sqrt(k) ){//是自己的根号
yueshu++;
}
}
return yueshu;
}
int main() {
int n;//接受循环次数
int k;//临时保存此次要计算的数
scanf("%d", &n);
//接收一行多个数字的方法:采用多次循环
//输入一整行 会逐个扫描整型
for (int i = 0; i < n; i++) {
scanf("%d", &k);
printf("%d\n",Yueshugeshu2(k));
}
return 0;
}