数学知识(1)

一、数论

二、组合计数

三、高斯消元

四、简单博弈论

一、数论

(1)质数的判定—— 试除法 O(sqrt(n));

数学知识(1)

/*
质数(素数)是指在大于1的自然数中,除了1和它本身以外不再有其他因数(约数)的自然数
1.严格大于1,本身大于等于2
2.除了1和自身之外没有其他因数,也就是只能整除这两个数
//暴力 O(n)
bool is_prime(int x)
{
    if (x < 2) return false;//严格大于1
    for (int i = 2; i < x; i ++ )//在2到n-1中存在某个数被x整除
        if (x % i == 0)
            return false;
    return true;
}
*/

#include <iostream>
using namespace std;
//优化 每个数的约数都是成对出现,如果i是n的约数,则n/i也是n的约数
bool is_prime(int x)
{
    if (x < 2) return false;
/*
可以枚举每一对约数中较小的那个数即可,较小的约数的范围是1到根号n(从2开始枚举)
也可以这样理解,从小到大枚举每个可能是约数的数,循环条件是这个可能是约数的数
小于与它配对的那个约数
i<=sqrt(x)不推荐,因为每次都要执行这个较慢的操作
i*i<=n也不推荐,当n大道接近int最大值时,i*i可能溢出变成负数
时间复杂度sqrt(n)
*/
    for (int i = 2; i <= x / i; i ++ )
        if (x % i == 0)
            return false;
    return true;
}

int main()
{
    int n;
    cin >> n;

    while (n -- )
    {
        int x;
        cin >> x;
        if (is_prime(x)) puts("Yes");//输出且换行
        else puts("No");
    }

    return 0;
}
bool is_prime(int x)
{
    if (x < 2) return false;
    for (int i = 2; i <= x / i; i ++ )
        if (x % i == 0)
            return false;
    return true;
}

(2)分解质因数——试除法

数学知识(1)

 数学知识(1)

 

/*
//暴力 O(n)
void divide(int x)
{
    for (int i = 2; i <= x; i ++ )
/*
从小到大枚举x的所有数,这里没有枚举质元素,会有问题吗?不会,因为枚举到i时,
x已经把i前面的(2到i-1)质因子全部都除干净了,此时x % i == 0的话,x是i的倍数,
且不包含任何2到i-1中的质因子,i中也不包含任何2到i-1中的质因子,所以i是质数
*/
        if (x % i == 0)
        {
            int s = 0;
            while (x % i == 0) x /= i, s ++ ;
            cout << i << ' ' << s << endl;
        }
    if (x > 1) cout << x << ' ' << 1 << endl;
    cout << endl;
}
*/
/*
判定质数算法时间复杂度一定是根号n,但这道题时间复杂度不一定是根号n,
最好情况下是除一个数就除干净了,也就是除logn次
所以时间复杂度是logn到根号n之间
*/
#include <iostream>

using namespace std;

void divide(int x)
{
//任意大于1的自然数,最多只有一个大于sqrt(n)的质因子,反证法可证
//所以先在2到sqrt(n)的范围去找质因子
    for (int i = 2; i <= x / i; i ++ ){
/*
从2开始依次遍历,每次遍历到此时的i时,此时的x是已经把从2到i-1之间可能存在的质因子
全部除干净的x,如果这个时候的i仍然是此时的x的因数的话,那此时的i必然也是质数
*/      if (x % i == 0)
        {
            int s = 0;
            //每次遍历到这个质因子时,x将这个质因子除干净
            while (x % i == 0) x /= i, s ++ ;
            cout << i << ' ' << s << endl;
        }
    }
/*
如果此时已经把sqrt(n)之前的质因子全部除干净的n仍然大于1的话,那此时的n就是
那个大于sqrt(n)的质因子
*/
    if (x > 1) cout << x << ' ' << 1 << endl;
    cout << endl;
}

int main()
{
    int n;
    cin >> n;
    while (n -- )
    {
        int x;
        cin >> x;
        divide(x);
    }

    return 0;
}
void divide(int x)
{
    for (int i = 2; i <= x / i; i ++ )
        if (x % i == 0)
        {
            int s = 0;
            while (x % i == 0) x /= i, s ++ ;
            cout << i << ' ' << s << endl;
        }
    if (x > 1) cout << x << ' ' << 1 << endl;
    cout << endl;
}

(3)

上一篇:ShaderLab实现Vignette过场动画效果


下一篇:dialog.setCancelable(false) 不生效问题分析与解决