【AcWing算法基础课】第四章 数学知识(未完待续)(1)

简介: 利用秦九韶算法来实现其他进制转十进制的结果求解

课前温习

8dc679b764b3809c1e1561c9d57b212c_d303555596e145cdbfeba228e635c7e5.png


番外:秦九韶算法

利用秦九韶算法来实现其他进制转十进制的结果求解


下图内容来源:百度百科,侵删。

594e56edbaa273534ca436ca3dd94a30_59095ea1885a49c791c590a57e703fff.png

核心模板

int nToTen(string s,int n){
  int ans=0;
  for(int i=0;i<s.size();i++){   
    ans=ans*n+s[i]-'0';            
  }
  return ans;
}

主要代码


#include <iostream>
#include <string> 
using namespace std;
string s;
int n;
//其他进制转十进制(所有进制均适合) 
/*
int nToTen(string s,int n){
  int ans=0;
  for(int i=0;i<s.size();i++){
  if(s[i]>='A'&&s[i]<='Z') ans=ans*n+s[i]-'A'+10; 
  else ans=ans*n+s[i]-'0';
  }
  return ans;
} 
*/
//其他进制转十进制(仅能处理十进制以下的进制转十进制) 
int nToTen(string s,int n){
  int ans=0;
  for(int i=0;i<s.size();i++){   
    ans=ans*n+s[i]-'0';            //可以这样理解:原始答案中一个数都没有,然后把第一个数加了进去,然后每次向答案中加数,都要将原来的答案整体向前移一位,空出位置留给当前位。所以结果就是ans往前移一位的结果再加上当前位的数字 
  }
  return ans;
} 
int main(){
    cin>>n;
    cin>>s;
    cout<<nToTen(s,n);
  return 0;
}


一、质数

1c0f2074e3067d1a71877cec1eabe837_f9b4c0d8b18847d3ab2da8c51ae9cb01.png

(“就被称为质数”)


1. 试除法判定质数

小于x的约数是成对出现的(d和x/d),所以不需要从2枚举到n-1,只需要每次枚举较小的约数即可。即每次枚举从i到x/i。


核心模板

普通版


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;
}


优化版


bool is_prime(int x){
    if(x<=3) return x>1;
    if(x%6!=1&&x%6!=5) return false;
    for(int i=5;i<=x/i;i+=6){
        if(x%i==0&&x%(i+2)==0) return false;
    }
    return true;
}


题目链接:

866. 试除法判定质数


1.1题目描述

给定 n 个正整数 ai,判定每个数是否是质数。


输入格式


第一行包含整数 n。

接下来 n 行,每行包含一个正整数 ai。


输出格式


共 n 行,其中第 i 行输出第 i 个正整数 ai 是否为质数,是则输出 Yes,否则输出 No。


数据范围


1≤n≤100,1≤ai≤231−1


输入样例:


2
2
6


输出样例:


Yes
No


1.2思路分析

套用模板即可,注意细节。


1.3代码实现

#include <iostream>
using namespace std;
const int N=110;
int a[N];
int n;
bool is_p(int n){
    if(n<2) return false;
    for(int i=2;i<=n/i;i++){
        if(n%i==0) return false;
    }
    return true;
}
int main(){
    cin>>n;
    for(int i=0;i<n;i++){
        cin>>a[i];
        if(is_p(a[i]))  cout<<"Yes"<<endl;
        else cout<<"No"<<endl;
    }
    return 0;
}


2、试除法分解质因数

下图内容来源:百度百科,侵删。


思路:


下图内容来源这里,侵删。


核心模板

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;
}


题目链接:867. 分解质因数


1.4题目描述

给定 n 个正整数 ai ,将每个数分解质因数,并按照质因数从小到大的顺序输出每个质因数的底数和指数。


输入格式


第一行包含整数 n。


接下来 n 行,每行包含一个正整数 ai。


输出格式


对于每个正整数 ai,按照从小到大的顺序输出其分解质因数后,每个质因数的底数和指数,每个底数和指数占一行。


每个正整数的质因数全部输出完毕后,输出一个空行。


数据范围


1≤n≤100,2≤ai≤2×109


输入样例:


2
6
8

1

2

3

输出样例:

2 1
3 1
2 3


1.5思路分析

套用模板即可,注意细节。


1.6代码实现

#include <iostream>
using namespace std;
int n;
void divide(int n){
    for(int i=2;i<=n/i;i++){
        if(n%i==0){
            int s=0;
            while(n%i==0){
                n/=i;
                s++;
            }
            cout<<i<<' '<<s<<endl;
        }
    }
    if(n>1) cout<<n<<' '<<1<<endl;
    cout<<endl;
}
int main(){
    cin>>n;
    while(n--){
        int a;
        cin>>a;
        divide(a);
    }
    return 0;
}


二、筛素数

1.朴素筛法求素数

从2到n枚举每个数,删掉其所有的倍数,枚举完之后,没有被删掉的数为质数。


核心模板

int primes[N],cnt;   //primes[]存储所有素数
bool st[N];    //st[x]存储x是否被筛掉
void get_primes(int n){
    st[0]=st[1]=true;           //0和1均不是质数
    for(int i=2;i<=n;i++){
        if(st[i]) continue;
        primes[cnt++]=i;
        for(int j=i+i;j<=n;j+=i){
            st[j]=true;
        }
    }
}


埃氏筛法


int primes[N],cnt;   //primes[]存储所有素数
bool st[N];    //st[x]存储x是否被筛掉
void get_primes(int n){
    st[0]=st[1]=true;           //0和1均不是质数
    for(int i=2;i<=n;i++){
        if(!st[i]){
        primes[cnt++]=i;
        for(int j=i+i;j<=n;j+=i){
            st[j]=true;
        }
        }
    }
}


2.线性筛法求素数(O(n))

09e8ea4b33fe85db9a01f44fe1e33a97_45a3a8b14e694ef7b30a9f70b405e8bc.png


核心模板

int primes[N],cnt;   //primes[]存储所有素数
bool st[N];   //st[x]存储x是否被筛掉
void get_primes(int n){
    st[0]=st[1]=true;           //0和1均不是质数
    for(int i=2;i<=n;i++){
        if(!st[i]) primes[cnt++]=i;
        for(int j=0;primes[j]<=n/i;j++){
            st[primes[j]*i]=true;
            if(i%primes[j]==0) break;
        }
    }
}


题目链接:868. 筛质数


2.1题目描述

给定一个正整数 n,请你求出 1∼n 中质数的个数。


输入格式


共一行,包含整数 n。


输出格式


共一行,包含一个整数,表示 1∼n 中质数的个数。


数据范围


1≤n≤106


输入样例:


8


输出样例:


4


2.2思路分析

利用上述模板即可。


2.3代码实现

埃氏筛法


#include <iostream>
using namespace std;
const int N=1000010;
int n,cnt;
int primes[N];
bool st[N];
void getPrimes(int n){
     for(int i=2;i<=n;i++){
         if(!st[i]){
            primes[cnt++]=i;
            for(int j=i+i;j<=n;j+=i){
                st[j]=true;
            }
         }
     }
}
int main(){
    cin>>n;
    getPrimes(n);
    cout<<cnt;
    return 0;
}


线性筛法


#include <iostream>
using namespace std;
const int N=1000010;
int n,cnt;
int primes[N];
bool st[N];
void getPrimes(int n){
     for(int i=2;i<=n;i++){
        if(!st[i]) primes[cnt++]=i;
        for(int j=0;primes[j]<=n/i;j++){
            st[i*primes[j]]=true;
            if(i%primes[j]==0) break;    //此时primes[j]一定是i的最小质因子
        }
    }     
}
int main(){
    cin>>n;
    getPrimes(n);
    cout<<cnt;
    return 0;
}


目录
相关文章
|
1月前
|
存储 算法 Serverless
【C/C++ 数据结构】深入探索数据结构中算法复杂度:从C++和数学的视角
【C/C++ 数据结构】深入探索数据结构中算法复杂度:从C++和数学的视角
46 0
|
2月前
|
算法 测试技术 C++
【动态规划】【数学】【C++算法】1449. 数位成本和为目标值的最大数字
【动态规划】【数学】【C++算法】1449. 数位成本和为目标值的最大数字
|
2月前
|
算法 测试技术 C++
【动态规划】【 数学】C++算法:514自由之路
【动态规划】【 数学】C++算法:514自由之路
|
3月前
|
算法
双指针算法(acwing)疑难讲解
双指针算法(acwing)疑难讲解
19 0
|
5月前
|
算法
【AcWing算法基础课】第五章 动态规划(未完待续)(3)
当然,一个人能够滑动到某相邻区域的前提是该区域的高度低于自己目前所在区域的高度。
73 0
|
1天前
|
存储 安全 算法
|
1月前
|
机器学习/深度学习 算法 Python
LSTM(长短期记忆)网络的算法介绍及数学推导
LSTM(长短期记忆)网络的算法介绍及数学推导
19 0
|
2月前
|
算法 测试技术 C++
【动态规划】【数学】【C++算法】805 数组的均值分割
【动态规划】【数学】【C++算法】805 数组的均值分割
|
2月前
|
算法 测试技术 C++
【动态规划】【数学】【C++算法】18赛车
【动态规划】【数学】【C++算法】18赛车
|
3月前
|
算法 测试技术 C#
【动态规划】【数学】【C++算法】18赛车
【动态规划】【数学】【C++算法】18赛车
【动态规划】【数学】【C++算法】18赛车