c/c++实现奇偶数,质数,最大公约数,最小公倍数,最大奇约数判断

c/c++实现基本数学概念转换

1.奇偶数


说明:一个整数不是奇数就是偶数,包括0,0是偶数。这里,我们可以利用一个数能被2整除则是偶数的性质,或者二进制表示该数,末位是否为1,1则是奇数的性质,可以很好判断一个数是奇是偶
一般情况下逻辑操作比算数运算更高效。


1.1 求余判断

bool isOdd(int num)
{
     return (num % 2) == 1; //奇数返回1,偶数返回0
}

1.2逻辑判断

bool isOdd(int num)
{
    return ( num & 1) == 1;//奇数返回1,偶数返回0
}

2.质数(Prime)


(1)概念:质数定义为在大于1的自然数中,除了1和它本身以外不再有其他因数;
合数概念与之相对。
1既不是质数,也不是合数
(2)判断方法:根据合数的一个性质:若一个数是合数,那么它的最小质因数肯定小于等于其平方根。因为我们只需找到一个数存在1或者其本身以外的一个因数,我们就可以判断该数不是质数,所以可以遍历该数平方根到1之前,是否存在这个数的因数即可。


//用到函数sqrt,头文件 <math.h> 
bool isPrime(int num)
{
    for(int i = sqrt(mun); i>1; i--)
    {
         if(num%i == 0)
            return 0;
    }
    return 1;
}//合数返回0,质数返回1

3.最大公约数


(1)概念:如果数a能被数b整除,a就叫做b的倍数,b就叫做a的约数。约数和倍数都表示一个整数与另一个整数的关 系,不能单独存在。如只能说16是某数的倍数,2是某数的约数,而不能孤立地说16是倍数,2是约数。最大公因数,也称最大公约数、最大公因子,指两个或多个整数共有约数中最大的一个
(2)算法:辗转相除法,穷举法


辗转相除法
两个数相除求余,如果不为0,除数和余数继续求余,直到余数为0。直接见程序:

int getGCD(int a,int b)
{
    int temp;
    while(b!=0)
    {
        temp = a%b;
        a = b;
        b = temp;
    }
    return b;
}

穷举法
设立起始一个整数i =b,如果两个数a和b能够同时整除i,那么i则为最大公约数,否则i一直递减下去。

int getGCD(int a,int b)
{
    for(int i = b; i>1; i--)
    {
        if(a%i == 0&& b%i ==0)
           return i;
    }
    return 1;
}

4.最小公倍数


(1)概念:两个或多个整数公有的倍数叫做它们的公倍数,其中除0以外最小的一个公倍数就叫做这几个整数的最小公倍数。
(2)算法:
分解质因数:先把这几个数的质因数写出来,最小公倍数等于它们所有的质因数的乘积(如果有几个质因数相同,则比较两数中哪个数有该质因数的个数较多,乘较多的次数)
公式法:由于两个数的乘积等于这两个数的最大公约数与最小公倍数的积。即(a,b)×[a,b]=a×b。所以,求两个数的最小公倍数,就可以先求出它们的最大公约数,然后用上述公式求出它们的最小公倍数。
穷举法

int getLCM(int a,int b)
{
    for(int i =b;;i++)
    {
        if(i%a == 0&& i%b == 0)
            return i;
    }
    return 0;
}

公式法

最小公倍数 = 两数乘积 - 最大公约数;

5.最大奇约数

这里写图片描述
奇数的最大约数是自身, 偶数的最大奇约数是除所有偶因子之后的那个奇数。所以直观的思路就是挨个遍历一遍加起来。

#include <iostream>
using namespace std;
int main(int argc, char **argv)
{
    long long N;
    long long sum = 0;
    long long temp;
    cin>>N;
    for (long long i = 1; i <= N; ++i)
    {
        temp = i;
        while(0 == temp%2)
            temp /= 2;
        sum += temp;
    }
    cout<<sum;
    return 0;
}

然而, N的取值范围时10^10,所以O(n)的算法是超时的。
考虑优化,设sum(i) = f(1) + f(2) + … + f(i);
求sum(i)的过程中,如果i 为奇数可以直接求,就是 i 本身,即f(i) = i。
问题就是求所有f(i), i为偶数的和。
因为是最大奇约数,所以f(2k) = f(k),所以f(2) + f(4) + … + f(2k) = f(1) + f(2) + … + f(k);
这里写图片描述
时间复杂度为(O(logn))

#include<iostream>
using namespace std;
long long sum(long long n) {
    if (n == 1) {
        return 1;
    }
    if (n % 2 == 0) {
        return  sum(n / 2) + n * n / 4;//奇数等差数列之和
    }
    else {
        return sum(n - 1) + n; 
    }
}
int main() {
    int N;
    cin >> N;
    cout << sum(N) << endl;
}

转自:
[https://blog.csdn.net/FX677588/article/details/52824950]
[https://www.cnblogs.com/wangxiaobao/p/5866351.html ]

猜你喜欢

转载自blog.csdn.net/jzj_c_love/article/details/82110075
今日推荐