ACM+数论常用的模版Word文档格式.docx

上传人:b****3 文档编号:17912090 上传时间:2022-12-12 格式:DOCX 页数:34 大小:27.48KB
下载 相关 举报
ACM+数论常用的模版Word文档格式.docx_第1页
第1页 / 共34页
ACM+数论常用的模版Word文档格式.docx_第2页
第2页 / 共34页
ACM+数论常用的模版Word文档格式.docx_第3页
第3页 / 共34页
ACM+数论常用的模版Word文档格式.docx_第4页
第4页 / 共34页
ACM+数论常用的模版Word文档格式.docx_第5页
第5页 / 共34页
点击查看更多>>
下载资源
资源描述

ACM+数论常用的模版Word文档格式.docx

《ACM+数论常用的模版Word文档格式.docx》由会员分享,可在线阅读,更多相关《ACM+数论常用的模版Word文档格式.docx(34页珍藏版)》请在冰豆网上搜索。

ACM+数论常用的模版Word文档格式.docx

Noanswer\n"

);

else

x=(x*c/d)%b;

//第一次求出的x;

__int64t=b/d;

x=(x%t+t)%t;

%I64d\n"

x);

//最小的正数的值

for(inti=0;

i<

d;

i++)

printf("

The%dthansweris:

%ld\n"

i+1,(x+i*(b/d))%b);

//所有的正数值

/*

函数返回值为gcd(a,b),并顺带解出ax+by=gcd(a,b)的一个解x,y,

对于不定方程ax+by=c的通解为:

x=x*c/d+b/d*t

y=y*c/d+a/d*t

当c%gcd(a,b)!

=0时,不定方程无解.*/

中国剩余定理

intext_euclid(inta,intb,int&

x,int&

y)//求gcd(a,b)=ax+by

intt,d;

intChina(intW[],intB[],intk)//W为按多少排列,B为剩余个数W>

BK为组数

inti;

intd,x,y,a=0,m,n=1;

for(i=0;

k;

n*=W[i];

for(i=0;

m=n/W[i];

d=ext_euclid(W[i],m,x,y);

a=(a+y*m*B[i])%n;

if(a>

0)

returna;

return(a+n);

intB[100],W[100];

intk;

a=2(mod5)

cin>

k;

a=3(mod13)

for(inti=0;

i<

i++)的解

{2

cin>

W[i];

52

B[i];

133

}输出42

China(W,B,k)<

欧拉函数

求小于n的所有欧拉数

intphi[1000];

//数组中储存每个数的欧拉数

voidgenPhi(intn)//求出比n小的每一个数的欧拉数(n-1的)

inti,j,pNum=0;

memset(phi,0,sizeof(phi));

phi[1]=1;

for(i=2;

n;

i++)

if(!

phi[i])

{

for(j=i;

j<

j+=i)

{

if(!

phi[j])

phi[j]=j;

phi[j]=phi[j]/i*(i-1);

}

}

求n的欧拉数

inteular(intn)

intret=1,i;

for(i=2;

i*i<

=n;

if(n%i==0)

n/=i,ret*=i-1;

while(n%i==0)

n/=i,ret*=i;

if(n>

1)

ret*=n-1;

returnret;

//n的欧拉数

行列式计算

intjs(ints[100][100],intn)

intz,j,k,r,total=0;

intb[100][100];

/*b[N][N]用于存放,在矩阵s[N][N]中元素s[0]的余子式*/

if(n>

2)

for(z=0;

z<

n;

z++)

for(j=0;

j<

n-1;

j++)

for(k=0;

k<

k++)

if(k>

=z)

b[j][k]=s[j+1][k+1];

else

b[j][k]=s[j+1][k];

if(z%2==0)

r=s[0][z]*js(b,n-1);

/*递归调用*/

r=(-1)*s[0][z]*js(b,n-1);

total=total+r;

}

}

elseif(n==2)

total=s[0][0]*s[1][1]-s[0][1]*s[1][0];

returntotal;

排列

longA(longn,longm)//n>

m

longa=1;

while(m!

=0){a*=n;

n--;

m--;

returna;

组合

longC(longn,longm)//n>

longi,c=1;

i=m;

while(i!

=0){c*=n;

i--;

while(m!

=0){c/=m;

returnc;

大数乘大数

string>

chara[1000],b[1000],s[10000];

voidmult(chara[],charb[],chars[])//a被乘数,b乘数,s为积

inti,j,k=0,alen,blen,sum=0,res[65][65]={0},flag=0;

charresult[65];

alen=strlen(a);

blen=strlen(b);

alen;

for(j=0;

blen;

j++)res[i][j]=(a[i]-'

0'

)*(b[j]-'

for(i=alen-1;

i>

=0;

i--)

for(j=blen-1;

j>

j--)sum=sum+res[i+blen-j-1][j];

result[k]=sum%10;

k=k+1;

sum=sum/10;

for(i=blen-2;

=i;

j++)sum=sum+res[i-j][j];

if(sum!

=0){result[k]=sum;

k=k+1;

i++)result[i]+='

;

for(i=k-1;

i--)s[i]=result[k-1-i];

s[k]='

\0'

while

(1)

if(strlen(s)!

=strlen(a)&

&

s[0]=='

strcpy(s,s+1);

break;

mult(a,b,s);

s<

大数乘小数

chara[100],t[1000];

voidmult(charc[],intm,chart[])//c为大数,m<

=10,t为积

inti,l,k,flag,add=0;

chars[100];

l=strlen(c);

l;

s[l-i-1]=c[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;

else

l=i;

t[l-1-i]=s[i]+'

t[l]='

i;

mult(a,i,t);

t<

大数加法

voidadd(chara[],charb[],chars[])//a被加数,b加数,s和

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>

if(i<

0)x='

elsex=a[i];

if(j<

0)y='

elsey=b[j];

z=x-'

+y-'

if(up)z+=1;

if(z>

9){up=1;

z%=10;

}elseup=0;

c[k++]=z+'

i--;

j--;

if(up)c[k++]='

1'

i=0;

c[k]='

for(k-=1;

k>

k--)

s[i++]=c[k];

s[i]='

add(a,b,s);

大数减法

voidsub(chara[],charb[],chars[])

inti,l2,l1,k;

l2=strlen(b);

l1=strlen(a);

s[l1]='

l1--;

for(i=l2-1;

i--,l1--)

if(a[l1]-b[i]>

=0)

s[l1]=a[l1]-b[i]+'

s[l1]=10+a[l1]-b[i]+'

a[l1-1]=b[l1-1]-1;

k=l1;

while(a[k]<

0){a[k]+=10;

a[k-1]-=1;

k--;

while(l1>

=0){s[l1]=a[l1];

loop:

if(s[0]=='

l1=strlen(a);

l1-1;

i++)s[i]=s[i+1];

s[l1-1]='

gotoloop;

if(strlen(s)==0){s[0]='

s[1]='

sub(a,b,s);

大数阶乘

cmath>

longa[10000];

intfactorial(intn)//n为所求阶乘的n!

的n

inti,j,c,m=0,w;

a[0]=1;

for(i=1;

{

c=0;

for(j=0;

=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("

%ld"

a[m]);

//输出

for(i=m-1;

i--)//

%4.4ld"

a[i]);

//

\n"

returnw;

//返回值为阶乘的位数

储存方法很巧,每一个a[i]中存四位,不足四位在前加0补齐

大数求余

intmod(intB)//A为大数,B为小数

inti=0,r=0;

while(A[i]!

='

r=(r*10+A[i++]-'

)%B;

returnr;

//r为余数

高精度任意进制转换

chars[1000],s2[1000];

//s[]:

原进制数字,用字符串表示,s2[]:

转换结果,用字符串表示

longd1,d2;

//d1:

原进制数,d2:

需要转换到的进制数

voidconversion(chars[],chars2[],longd1,longd2)

longi,j,t,num;

charc;

num=0;

s[i]!

='

if(s[i]<

9'

s[i]>

)t=s[i]-'

elset=s[i]-'

A'

+10;

num=num*d1+t;

t=num%d2;

if(t<

=9)s2[i]=t+'

elses2[i]=t+'

-10;

num/=d2;

if(num==0)break;

i++;

=i/2;

{c=s2[j];

s2[j]=s2[i-j];

s2[i-j]=c;

s2[i+1]='

while

(1)

cin>

s>

d1>

d2;

conversion(s,s2,d1,d2);

cout<

s2<

判断一个数是否素数

//基本方法,n为所求数,返回1位素数,0为合数

intcomp(intn){

inti,flag=1;

=sqrt(n);

if(n%i==0){flag=0;

break;

if(flag==1)return1;

elsereturn0;

素数表

intprime(inta[],intn)//小于n的素数

{inti,j,k,x,num,*b;

n++;

n/=2;

b=(int*)malloc(sizeof(int)*(n+1)*2);

a[0]=2;

a[1]=3;

num=2;

=2*n;

b[i]=0;

for(i=3;

i+=3)

2;

x=2*(i+j)-1;

while(b[x]==0)

a[num++]=x;

for(k=x;

k+=x)

b[k]=1;

returnnum;

}//小于n的素数的个数}

boolflag[1000000];

voidprime(intM)//01表

{inti,j;

intsq=sqrt(double(M));

for(i=0;

i<

M;

i++)

flag[i]=true;

flag[1]=false;

flag[0]=false;

for(i=2;

=sq;

if(flag[i])

for(j=i*i;

j<

j+=i)

flag[j]=false;

Miller_Rabin随机素数测试算法

说明:

这种算法可以快速地测试一个数是否

满足素数的必要条件,但不是充分条件。

过也可以用它来测试素数,出错概率很小,

对于任意奇数n>

2和正整数s,该算法出错概率

至多为2^(-s),因此,增大s可以减小出错概

率,一般取s=50就足够了。

intWitness(inta,intn)

{

inti,d=1,x;

for(i=ceil(log((float)n-1)/log(2.0))-1;

i>

=0;

i--)

x=d;

d=(d*d)%n;

if((d==1)&

(x!

=1)&

=n-1))

return1;

if(((n-1)&

(1<

i))>

0)

d=(d*a)%n;

return(d==1?

0:

1);

intMiller_Rabin(intn,ints)

intj,a;

for(j=0;

s;

j++)

a=rand()*(n-2)/RAND_MAX+1;

if(Witness(a,n))

return0;

return1;

intx;

x;

Miller_Rabin(x,50)<

KMP

chart[1010],p[100];

//t为大字符串,p为小字符串

intnext[100];

voidsn()

intj,k;

next[0]=-1;

j=1;

do

k=next[j-1];

while(k!

=-1&

p[k]!

=p[j])

k=next[k];

next[j]=k+1;

j+=1;

while(p[j]!

intmatch(intx)//x是大字符串下标,从头开始为0,j为小字符串下标

intk=x,j=0;

if(t[0]=='

return0;

while(t[k]!

while(j!

p[j]!

=t[k])

j=next[j];

k+=1;

if(p[j]=='

returnk-j;

//返回p所在的下标

return-1;

//搜索失败返回-1

intx=0;

sn();

intr=match(x);

r<

(一)巴什博奕(BashGame):

只有一堆n个物品,两个人轮流从这堆物品中取物,规定每次至少取一个,最多取m个。

最后取光者得胜。

显然,如果n=m+1,那么由于一次最多只能取m个,所以,无论先取者拿走多少个,后取者都能够一次拿走剩余的物品,后者取胜。

因此我们发现了如何取胜的法则:

如果n=(m+1)r+s,(r为任意自然数,s≤m),那么先取者要拿走s个物品,如果后取者拿走k(≤m)个,那么先取者再拿走m+1-k个,结果剩下(m+1)(r-1)个,以后保持这样的取法,那么先取者肯定获胜。

总之,要保持给对手留下(m+1)的倍数,就能最后获胜。

这个游戏还可以有一种变相的玩法:

两个人轮流报数,每次至少报一个,最多报十个,谁能报到100者胜。

(二)威佐夫博奕(WythoffGame):

有两堆各若干个物品,两个人轮流从某一堆或同时从两堆中取同样多的物

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 管理学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1