涉及机试中涉及的一系列数学问题,包括数位拆解、分解素因数等高频知识点,以及最小公倍数,最大公约数的基本方法,高精度整数运算的实现。
进制转换
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| #include <bits/stdc++.h> using namespace std; int main() { int a,b; string n; while(cin>>a>>n>>b) { long num=0; string result=""; while(n[0]=='0') n=n.substr(1); int k=1; for(int i=n.length()-1;i>=0;--i) { if(n[i]>='0'&&n[i]<='9') num+=(n[i]-'0')*k; else if(n[i]>='a'&&n[i]<='z') num+=(n[i]-'a'+10)*k; else if(n[i]>='A'&&n[i]<='Z') num+=(n[i]-'A'+10)*k; k*=a; } while(num!=0) { if(num%b<=9) result=to_string(num%b)+result; else result=string(1,num%b-10+'A')+result; num/=b; } cout<<result<<endl; } return 0; }
|
最大公约数 GCD
求a,b的最大公约数:
- 如果a,b全为0,则它们的最大公约数不存在
- 若a,b其中之一为零,它们的最大公约数为a,b中非0的那个
- 若a,b都不为0 则使a=b;b=a%b; 然后重复该过程
1 2 3 4 5
| int gcd(int a,int b) { if(b==0) return a; else return gcd(b,a%b); }
|
最小公倍数 LCM
a,b两数的最小公倍数为两数的乘积除以它们的最大公约数
素数
合数是指在大于1的整数中除了能被1和本身整除外,还能被其他数(0除外)整除的数。与之相对的是质数(素数),而1既不属于质数也不属于合数。最小的合数是4。其中,完全数与相亲数是以它为基础的。
素数筛
若一个数不是素数,则必存在一个小于它的素数为其的因数。在我们获得一个素数时,将它的所有倍数均标记为非素数,这样当我们遍历到一个数时,它没有被任何小于它的素数标记为非素数,则确定其为素数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| #include<iostream> using namespace std; int prime[10000]={0}; int primesize=0; bool mark[10001]; void init() { for(int i=1;i<10001;i++) mark[i]=false; for(int i=2;i<=10000;i++){ if(mark[i]==true) continue; prime[primesize++]=i; for(int j=i*i;j<=10000;j+=i) mark[j]=true; } } int main() { init(); int n; while(cin>>n) { bool flag=false; for(int i=0;i<primesize;i++) { if(prime[i]<n&&prime[i]%10==1) { if(flag==false) { flag=true; cout<<prime[i]; } else{ cout<<" "<<prime[i]; } } } cout<<endl; } return 0; }
|
分解素因数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| #include<iostream> using namespace std; int prime[100000]={0}; int primesize; bool mark[100001]; void init() { for(int i=0;i<100001;i++) mark[i]=false; for(int i=2;i<=100000;i++) { if(mark[i]) continue; prime[primesize++]=i; for(int j=i*i;j<=100000;j+=i) mark[j]=true; } } int main() { init(); int N; while(cin>>N) { int ansPrime[30]; int ansSize=0; int ansNum[30]; for(int i=0;i<primesize;i++) { if(N%prime[i]==0){ ansPrime[ansSize]=prime[i]; ansNum[ansSize]=0; while(N%prime[i]==0) { ansNum[ansSize]++; N/=prime[i]; } ansSize++; if(N==1) break; } } if(N!=1){ ansPrime[ansSize]=N; ansNum[ansSize++]=1; } int ans=0; for(int i=0;i<ansSize;i++){ ans+=ansNum[i]; } cout<<ans<<endl; } return 0; }
|
阶乘的素因数分解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| #include<stdio.h> int main(){ int a,n; while(scanf("%d%d",&n,&a)!=EOF){ int count1[1010]={0}; int count2[1010]={0}; for(int i=2;i<=n;i++){ int t=n; while(t){ count1[i]+=t/i; t=t/i; } } int ans=233333333; for(int i=2;i<=a;i++){ while(a%i==0){ count2[i]++; a/=i; } if(count2[i]==0) continue; if(count1[i]/count2[i]<ans) ans=count1[i]/count2[i]; } printf("%d\n",ans); } return 0; }
|
使用素数筛
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| #include<stdio.h> #define N 1010 int prime[N]; int primesize; bool mark[N]; void init(){ for(int i=0;i<N;i++) mark[i]=false; for(int i=2;i<N;i++){ if(mark[i]==true) continue; else{ prime[primesize++]=i; for(int j=i*i;j<N;j+=i) mark[j]=true; } } } int main(){ init(); int a,n; while(scanf("%d%d",&n,&a)!=EOF){ int count1[N]={0}; int count2[N]={0}; for(int i=0;i<primesize;i++){ int t=n; while(t){ count1[i]+=t/prime[i]; t/=prime[i]; } } int ans=233333333; for(int i=0;i<primesize;i++){ while(a%prime[i]==0){ count2[i]++; a/=prime[i]; } if(count2[i]==0) continue; if(count1[i]/count2[i]<ans) ans=count1[i]/count2[i]; } printf("%d\n",ans); } return 0; }
|
二分求幂
快速幂
csdn相关介绍博客
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| #include<iostream> using namespace std; int binaryPow(int a,int b) { int ans=1; while(b) { if(b%2!=0) ans*=a; a*=a; b/=2; } return ans; } int main() { int a,b; while(cin>>a>>b) { cout<<binaryPow(a,b)<<endl; } return 0; }
|
矩阵快速幂
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| const int N=10; int tmp[N][N]; void multi(int a[][N],int b[][N],int n) { memset(tmp,0,sizeof tmp); for(int i=0;i<n;i++) for(int j=0;j<n;j++) for(int k=0;k<n;k++) tmp[i][j]+=a[i][k]*b[k][j]; for(int i=0;i<n;i++) for(int j=0;j<n;j++) a[i][j]=tmp[i][j]; } int res[N][N]; void Pow(int a[][N],int n) { memset(res,0,sizeof res); for(int i=0;i<N;i++) res[i][i]=1; while(n) { if(n&1) multi(res,a,N); multi(a,a,N); n>>=1; }
———————————————— 版权声明:本文为CSDN博主「wust_wenhao」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https:
|
高精度整数
计算n的阶乘
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| #include<iostream> using namespace std; int res[3000]={0}; int main() { int N; while(cin>>N) { for(int i=0;i<3000;i++) res[i]=0; int size=0;res[size++]=1; for(int i=2;i<=N;i++) { int jinwei=0; for(int j=0;j<size;j++) { res[j]=(res[j]*i+jinwei); if(res[j]>9) { jinwei=res[j]/10; res[j]%=10; } else jinwei=0; } while(jinwei){ res[size++]=jinwei%10; jinwei/=10; } } for(int i=size-1;i>=0;i--) cout<<res[i]; cout<<endl; } return 0; }
|