因数个数和

链接:https://www.nowcoder.com/acm/contest/158/A
来源:牛客网
 

q次询问,每次给一个x,问1到x的因数个数的和。

输入描述:

第一行一个正整数q ;
接下来q行,每行一个正整数 x

输出描述:

共q行,每行一个正整数表示答案

 

示例1

输入

复制

4
1
2
3
10

输出

复制

1
3
5
27

转化为倍数的个数和,比如n=10,因数2的个数为[n/2]=5,枚举1到根号n

乘以2是因为一个数的因子有i,则x/i也是x的因子,所以每个因子有两个

减去w*w是因为有重复的i==x/i

#include <bits/stdc++.h>
using namespace std;
 
int main(){
    int t;
    cin>>t;
    while(t--){
        int n;
        cin>>n;
        long long  sum=0;
        int w = sqrt(n);
         
        for(int i=1;i<=w;i++)
            sum += n/i;
        cout<<(long long )(sum*2-w*w)<<endl;
    }
    return 0;
}

 

<think>根据用户需,我们需要计算两个数的公因数个数。公因数(或称公约数)是指能同时整除这两个数的整数。因此,我们需要找到所有能同时整除两个数的正整数,并统计其数量。 ### 思路 1. **确定范围**:两个数的公因数的最大可能值不会超过这两个数中的最小值(因为一个数因数不可能大于它本身)。因此,我们可以遍历从1到这两个数的最小值之间的所有整数。 2. **判断条件**:对于每个整数`i`,如果`i`能同时整除两个数(即两个数除以`i`的余数都为0),则`i`是这两个数的公因数。 3. **计数**:统计满足条件的`i`的个数。 ### 代码实现 ```c #include <stdio.h> int main() { int num1, num2, i, min, count = 0; // 输入两个整数 printf("请输入两个正整数:"); scanf("%d %d", &num1, &num2); // 找出两个数中的最小值 min = (num1 < num2) ? num1 : num2; // 遍历1到min之间的所有整数 for (i = 1; i <= min; i++) { // 如果i能同时整除num1num2,则i是公因数 if (num1 % i == 0 && num2 % i == 0) { count++; // 公因数计数加1 } } // 输出公因数个数 printf("公因数个数为:%d\n", count); return 0; } ``` ### 代码说明 1. **输入处理**:程序首先提示用户输入两个正整数。 2. **确定遍历范围**:通过三目运算符确定两个数中的最小值,因为公因数不可能大于这个最小值。 3. **循环判断**:循环从1到最小值,检查每个数是否是公因数(即同时整除两个数),如果是则计数器加1。 4. **输出结果**:最后输出公因数个数。 ### 示例 例如,输入1824: - 最小值min=18。 - 公因数有:1, 2, 3, 6(共4个)。 - 程序将输出:公因数个数为:4。 ### 优化 上述方法简单直观,但对于大数可能会比较慢。我们可以优化循环范围,实际上只需要遍历到两个数的最大公因数的平方根(但需要额外的步骤)。不过,对于一般应用,上述代码足够高效。 ### 相关问题 1. 如何计算两个数的最大公因数(GCD)? 2. 如何计算两个数的最小公倍数(LCM)? 3. 如何列出两个数的所有公因数? 4. 如何计算多个数的公因数个数? </think>以下是使用C语言编写的计算两个数因数个数的方法代码实现: ### 公因数个数计算原理 两个数的公因数(公约数)是指能同时整除这两个数的整数。计算公因数个数的常见方法是: 1. 先出两个数的最大公因数(GCD) 2. 再最大公因数因数个数(即公因数个数) ### 代码实现(包含详细注释) ```c #include <stdio.h> // 函数声明 int gcd(int a, int b); int countCommonFactors(int a, int b); int main() { int num1, num2; printf("请输入两个正整数: "); scanf("%d%d", &num1, &num2); // 计算并输出公因数个数 int count = countCommonFactors(num1, num2); printf("公因数个数为: %d\n", count); return 0; } // 计算最大公因数(GCD) - 使用欧几里得算法 int gcd(int a, int b) { while (b != 0) { int temp = b; b = a % b; a = temp; } return a; } // 计算公因数个数 int countCommonFactors(int a, int b) { int g = gcd(a, b); // 先最大公因数 int count = 0; // 遍历1到g之间的所有整数 for (int i = 1; i * i <= g; i++) { if (g % i == 0) { count++; // 找到一个因数i // 如果不是平方数,则添加对应的因数 if (i != g / i) { count++; } } } return count; } ``` ### 代码说明 1. **gcd函数**:使用欧几里得算法高效计算最大公因数(GCD) 2. **countCommonFactors函数**: - 先计算两个数的最大公因数 - 遍历1到√GCD之间的整数 - 对于每个能整除GCD的数i: - 计数+1(对应因数i) - 如果i≠GCD/i,计数再+1(对应的另一个因数) 3. **时间复杂度**:$$O(\sqrt{\gcd(a,b)})$$,效率远高于暴力遍历 ### 示例测试 输入: ``` 请输入两个正整数:18 24 ``` 输出: ``` 公因数个数为:4 ``` 解释:1824的公因数为1、2、3、6(共4个) ### 算法优势 1. 高效:利用GCD的性质减少遍历范围 2. 准确:完整覆盖所有因数情况 3. 优化:使用平方根范围减少循环次数 ### 相关问题 1. 如何优化计算大整数的公因数个数?[^3] 2. 计算公因数个数与计算素数个数有何算法差异? 3. 能否用递归实现欧几里得算法GCD? 4. 如何列出两个数的所有公因数而不仅仅是计数?[^1] 5. 当处理三个及以上数字时,如何计算它们的公因数个数
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值