数论资料.docx
- 文档编号:5664430
- 上传时间:2022-12-30
- 格式:DOCX
- 页数:15
- 大小:19.10KB
数论资料.docx
《数论资料.docx》由会员分享,可在线阅读,更多相关《数论资料.docx(15页珍藏版)》请在冰豆网上搜索。
数论资料
(1)欧拉函数
最大公约数
intgcd(inta,intb){
returnb?
gcd(b,a%b):
a;
}
最小公倍数
inlineintlcm(inta,intb){
returna/gcd(a,b)*b;
}
//求1..n-1中与n互质的数的个数
inteular(intn){
intret=1,i;
for(i=2;i*i<=n;i++)
if(n%i==0){
n/=i,ret*=i-1;
while(n%i==0)
n/=i,ret*=i;
}
if(n>1)
ret*=n-1;
returnret;
}
1.精度计算——大数阶乘
语法:
intresult=factorial(intn);
参数:
n:
n的阶乘
返回值:
阶乘结果的位数
注意:
本程序直接输出n!
的结果,需要返回结果请保留longa[]
需要math.h
源程序:
intfactorial(intn)
{
longa[10000];
inti,j,l,c,m=0,w;
a[0]=1;
for(i=1;i<=n;i++)
{
c=0;
for(j=0;j<=m;j++)
{
a[j]=a[j]*i+c;
c=a[j]/10000;
a[j]=a[j]%10000;
}
if(c>0){m++;a[m]=c;}
}
w=m*4+log10(a[m])+1;
printf("\n%ld",a[m]);
for(i=m-1;i>=0;i--)printf("%4.4ld",a[i]);
returnw;
}
2.精度计算——乘法(大数乘小数)
语法:
mult(charc[],chart[],intm);
参数:
c[]:
被乘数,用字符串表示,位数不限
t[]:
结果,用字符串表示
m:
乘数,限定10以内
返回值:
null
注意:
需要string.h
源程序:
voidmult(charc[],chart[],intm)
{
inti,l,k,flag,add=0;
chars[100];
l=strlen(c);
for(i=0;i s[l-i-1]=c[i]-'0'; for(i=0;i { k=s[i]*m+add; if(k>=10){s[i]=k%10;add=k/10;flag=1;}else{s[i]=k;flag=0;add=0;} } if(flag){l=i+1;s[i]=add;}elsel=i; for(i=0;i t[l-1-i]=s[i]+'0'; t[l]='\0'; } 3.精度计算——乘法(大数乘大数) 语法: mult(chara[],charb[],chars[]); 参数: a[]: 被乘数,用字符串表示,位数不限 b[]: 乘数,用字符串表示,位数不限 t[]: 结果,用字符串表示 返回值: null 注意: 空间复杂度为o(n^2) 需要string.h 源程序: voidmult(chara[],charb[],chars[]) { inti,j,k=0,alen,blen,sum=0,res[65][65]={0},flag=0; charresult[65]; alen=strlen(a);blen=strlen(b); for(i=0;i for(j=0;j for(i=alen-1;i>=0;i--) { for(j=blen-1;j>=0;j--)sum=sum+res[i+blen-j-1][j]; result[k]=sum%10; k=k+1; sum=sum/10; } for(i=blen-2;i>=0;i--) { for(j=0;j<=i;j++)sum=sum+res[i-j][j]; result[k]=sum%10; k=k+1; sum=sum/10; } if(sum! =0){result[k]=sum;k=k+1;} for(i=0;i for(i=k-1;i>=0;i--)s[i]=result[k-1-i]; s[k]='\0'; while (1) { if(strlen(s)! =strlen(a)&&s[0]=='0') strcpy(s,s+1); else break; } } 4.精度计算——加法 语法: add(chara[],charb[],chars[]); 参数: a[]: 被乘数,用字符串表示,位数不限 b[]: 乘数,用字符串表示,位数不限 t[]: 结果,用字符串表示 返回值: null 注意: 空间复杂度为o(n^2) 需要string.h 源程序: voidadd(chara[],charb[],charback[]) { inti,j,k,up,x,y,z,l; char*c; if(strlen(a)>strlen(b))l=strlen(a)+2;elsel=strlen(b)+2; c=(char*)malloc(l*sizeof(char)); i=strlen(a)-1; j=strlen(b)-1; k=0;up=0; while(i>=0||j>=0) { if(i<0)x='0'; elsex=a[i]; if(j<0)y='0'; elsey=b[j]; z=x-'0'+y-'0'; if(up)z+=1; if(z>9){up=1;z%=10;} elseup=0; c[k++]=z+'0'; i--;j--; } if(up)c[k++]='1'; i=0; c[k]='\0'; for(k-=1;k>=0;k--) back[i++]=c[k]; back[i]='\0'; } 5.精度计算——减法 语法: sub(chars1[],chars2[],chart[]); 参数: s1[]: 被减数,用字符串表示,位数不限 s2[]: 减数,用字符串表示,位数不限 t[]: 结果,用字符串表示 返回值: null 注意: 默认s1>=s2,程序未处理负数情况 需要string.h 源程序: voidsub(chars1[],chars2[],chart[]) { inti,l2,l1,k; l2=strlen(s2);l1=strlen(s1); t[l1]='\0';l1--; for(i=l2-1;i>=0;i--,l1--) { if(s1[l1]-s2[i]>=0) t[l1]=s1[l1]-s2[i]+'0'; else { t[l1]=10+s1[l1]-s2[i]+'0'; s1[l1-1]=s1[l1-1]-1; } } k=l1; while(s1[k]<0){s1[k]+=10;s1[k-1]-=1;k--;} while(l1>=0){t[l1]=s1[l1];l1--;} loop: if(t[0]=='0') { l1=strlen(s1); for(i=0;i t[l1-1]='\0'; gotoloop; } if(strlen(t)==0){t[0]='0';t[1]='\0';} } 6.任意进制转换 语法: conversion(chars1[],chars2[],longd1,longd2); 参数: s[]: 原进制数字,用字符串表示 s2[]: 转换结果,用字符串表示 d1: 原进制数 d2: 需要转换到的进制数 返回值: null 注意: 高于9的位数用大写'A'~'Z'表示,2~16位进制通过验证 源程序: voidconversion(chars[],chars2[],longd1,longd2) { longi,j,t,num; charc; num=0; for(i=0;s[i]! ='\0';i++) { if(s[i]<='9'&&s[i]>='0')t=s[i]-'0';elset=s[i]-'A'+10; num=num*d1+t; } i=0; while (1) { t=num%d2; if(t<=9)s2[i]=t+'0';elses2[i]=t+'A'-10; num/=d2; if(num==0)break; i++; } for(j=0;j {c=s2[j];s2[j]=s[i-j];s2[i-j]=c;} s2[i+1]='\0'; } 8.组合序列 语法: m_of_n(intm,intn1,intm1,int*a,inthead) 参数: m: 组合数C的上参数 n1: 组合数C的下参数 m1: 组合数C的上参数,递归之用 *a: 1~n的整数序列数组 head: 头指针 返回值: null 注意: *a需要自行产生 初始调用时,m=m1、head=0 调用例子: 求C(m,n)序列: m_of_n(m,n,m,a,0); 源程序: voidm_of_n(intm,intn1,intm1,int*a,inthead) { inti,t; if(m1<0||m1>n1)return; if(m1==n1) { for(i=0;i cout<<'\n'; return; } m_of_n(m,n1-1,m1,a,head);//递归调用 t=a[head];a[head]=a[n1-1+head];a[n1-1+head]=t; m_of_n(m,n1-1,m1-1,a,head+1);//再次递归调用 t=a[head];a[head]=a[n1-1+head];a[n1-1+head]=t; } 素数表 //用素数表判定素数,先调用initprime intplist[10000],pcount=0; intprime(intn){ inti; if((n! =2&&! (n%2))||(n! =3&&! (n%3))||(n! =5&&! (n%5))||(n! =7&&! (n%7))) return0; for(i=0;plist[i]*plist[i]<=n;i++) if(! (n%plist[i])) return0; returnn>1; } voidinitprime(){ inti; for(plist[pcount++]=2,i=3;i<50000;i++) if(prime(i)) plist[pcount++]=i; } 素数随机判定(miller_rabin) //millerrabin //判断自然数n是否为素数 //time越高失败概率越低,一般取10到50 #include #ifdefWIN32 typedef__int64i64; #else typedeflonglongi64; #endif intmodular_exponent(inta,intb,intn){//a^bmodn intret; for(;b;b>>=1,a=(int)((i64)a)*a%n) if(b&1) ret=(int)((i64)ret)*a%n; returnret; } //Carmichealnumber: 561,41041,825265,321197185 intmiller_rabin(intn,inttime=10){ if(n==1||(n! =2&&! (n%2))||(n! =3&&! (n%3))||(n! =5&&! (n%5))||(n! =7&&! (n%7))) return0; while(time--) if(modular_exponent(((rand()&0x7fff<<16)+rand()&0x7fff+rand()&0x7fff)%(n-1)+1,n-1,n)! =1) return0; return1; } 矩阵乘法 1.void Multiply (int a[100][100], int b[100][100],int c[100][100]) 2. { 3. int i, j, k; 4. 5. for (i = 0; i < row_a; i++) 6. { 7. for (j = 0; j < column_b; j++) 8. { 9. c[i][j] = 0; 10. for (k = 0; k < column_a; k++) 11. { 12. c[i][j] += a[i][k] * b[k][j]; 13. } 14. } 15. } 16. } N皇后问题 1.#include 2.#include 3.#include 4.using namespace std; 5. 6.int main() 7.{ 8. int n,temp=0; 9. cin>>n; 10. int f[20]; 11. if(n%6! =2&&n%6! =3) 12. { 13. if(n%2==0) 14. { 15. for(int i=2;i<=n;i+=2) 16. f[temp++]=i; 17. for(int i=1;i<=n-1;i+=2) 18. f[temp++]=i; 19. } 20. else 21. { 22. for(int i=2;i<=n-1;i+=2) 23. f[temp++]=i; 24. for(int i=1;i<=n;i+=2) 25. f[temp++]=i; 26. } 27. } 28. else 29. { 30. int k=0; 31. if(n%2==0) 32. { 33. k=n/2; 34. if(k%2==0) 35. { 36. for(int i=k;i<=n;i+=2) 37. f[temp++]=i; 38. for(int i=2;i<=k-2;i+=2) 39. f[temp++]=i; 40. for(int i=k+3;i<=n-1;i+=2) 41. f[temp++]=i; 42. for(int i=1;i<=k+1;i+=2) 43. f[temp++]=i; 44. } 45. else 46. { 47. for(int i=k;i<=n-1;i+=2) 48. f[temp++]=i; 49. for(int i=1;i<=k-2;i+=2) 50. f[temp++]=i; 51. for(int i=k+3;i<=n;i+=2) 52. f[temp++]=i; 53. for(int i=2;i<=k+1;i+=2) 54. f[temp++]=i; 55. } 56. } 57. else 58. { 59. k=(n-1)/2; 60. if(k%2==0) 61. { 62. for(int i=k;i<=n-1;i+=2) 63. f[temp++]=i; 64. for(int i=2;i<=k-2;i+=2) 65. f[temp++]=i; 66. for(int i=k+3;i<=n-2;i+=2) 67. f[temp++]=i; 68. for(int i=1;i<=k+1;i+=2) 69. f[temp++]=i; 70. f[temp++]=n; 71. } 72. else 73. { 74. for(int i=k;i<=n-2;i+=2) 75. f[temp++]=i; 76. for(int i=1;i<=k-2;i+=2) 77. f[temp++]=i; 78. for(int i=k+3;i<=n-1;i+=2) 79. f[temp++]=i; 80. for(int i=2;i<=k+1;i+=2) 81. f[temp++]=i; 82. f[temp++]=n; 83. } 84. } 85. } 86. 87. for(int i=0;i 88. cout< 89. return 0; 90. 91.} 大数幂模 1.#include 2
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数论 资料