2 数学问题
2.1 求最大公约数最小公倍数
[算法描述]
辗转相除法
[源程序]
/* 求a,b的最大公约数max和最小公倍数min */
n=2;
Max=1;
while (n<=a && n<=b)
if(a%n==0 && b%n==0)
{
a=(int)(a/n);
b=(int)(b/n);
Max=Max*n;
}
else++n;
Min=Max*a*b;
2.2 求素数
2.2.1 穷举法
[算法描述]
判断一个数是否能被2到sqrt(2)之间的任意一个整数整除,如果能则说明这个数不是素数,如果不能则说明这个数是素数.
[源程序]
int prime(int x)
{
intAns,i;
Ans=1;
for(i=2;i<=(int)sqrt(x);i++)
if (x%i==0)
{
Ans=0;
break;
}
if (x==1)return 0;
elsereturn Ans;
}
2.2.2筛法
[算法描述]
1.设2~n均为素数(for i:=2 to n do a[i]:=1);
2.将2的倍数清零;
3.找到接下来的第一个非零数并将其倍数清零;
4.重复步骤3,直到筛完第n个数.
数组中的非零数即是素数.
[源程序]
/* init */
a[1]=0;
for (i=2;i<=n;i++) a[i]=1;
i=2;
/* main */
while (i<=n)
{
k=i;
while(k<=n)
{
k=k+i;
a[k]=0;
}
++i;
while(a[i]==0 && i<n) ++i;
}
2.3 排列组合
2.3.1 排列数
[算法描述]
排列数公式
[源程序]
int A(int m, int n)
{
inti,Ans;
Ans=1;
for(i=1;i<=m;i++)
{
Ans=Ans*n;
--n;
}
returnAns;
}
2.3.2 组合数
[算法描述]
组合数公式
[源程序]
int C(int m, int n)
{
inti,Ans;
Ans=1;
for(i=1;i<=m;i++)
{
Ans=Ans*n;
--n;
}
for(i=1;i<=m;i++) Ans=Ans/i;
returnAns;
}
2.3.3 全排列算法
[算法描述]
1.1,2……N依次赋给a[1]至a[n],输出第一种排列;
2.构造下一种全排列,分四步完成:
(1)i的初值为1,在a[1]至a[n]中搜索找出相应的i,使i是a[k]>a[k-1]的k中最大的,即i=max{k|a[k]>a[k-1],k=2,3…n};
(2)在a[x]至a[n]中搜索找出相应的j,使j是a[k]>a[i-1]的k中最大的,即j=max{k|a[k]>a[i-1],k=i,i+1…n};
(3) 交换a[i-1]与a[j]形成新的序列;
(4) 对新的序列从 a[i+1]……a[n]进行逆序处理,输出相应序列.
3.重复2直到i=1时结束.
[源代码]:
void Arrange(int n)
{
intNum[255];
chari,x,y;
Num[0]=0;
for(i=1;i<=n;i++)
{
Num[i]=i;
printf("%d ",Num[i]);
}
printf("/n");
do
{
for (i=1;i<=n;i++)
if (Num[i]>Num[i-1]) x=i;
for (i=x;i<=n;i++)
if (Num[i]>Num[x-1]) y=i;
if (x>1)
{
Swap(&Num[x-1],&Num[y]); //交换Num[x-1]和Num[y]
Inverse(Num,x,n); //对num[x]~num[n]作逆序处理
for (i=1;i<=n;i++) printf("%d ",Num[i]); //输出当前序列
printf("/n");
}
}while(x!=1);
}
2.3.4 从n个数中选m个的组合
[算法描述]
类似于穷举.
[源程序]
void Combination(int n, int m)
{
inta[256],i,j;
a[0]=1;
for(i=1;i<=m;i++) a[i]=i;
while(a[0]==1)
{
for (i=1;i<=m;i++) printf("%d ",a[i]);
printf("/n");
j=m;
while (a[j]==n-m+j && j>0) j--;
a[j]++;
for (i=j+1;i<=n;i++) a[i]=a[i-1]+1;
}
}
2.4 进制转换
2.4.1 十进制转N进制
[算法描述]
辗转相除法.
[源程序]
void IntToN(int x, int n, char Ans[])
{
intCount,i,Temp=0,a[256];
for(i=0;i<=255;i++) Ans[i]=0;
Count=0;
if (x==0)Ans[0]='0';
else
{
while (x>0)
{
a[Count++]=x%n;
x=x/n;
}
for (i=Count-1;i>=0;i--)
if (a[i]<10) Ans[Temp++]=a[i]+'0';
else Ans[Temp++]=a[i]+'A'-10;
}
}
2.4.2 N进制转十进制
[算法描述]
加权.
[源程序]
int NToInt(char x[], int n)
{
inta[256],Ans,y,Count,i,j;
Ans=0;
for(i=0;i<=strlen(x)-1;i++)
if ('0'<=x[i] && x[i]<='9') a[i]=x[i]-'0';
else a[i]=x[i]-'A'+10;
Count=0;
for(i=strlen(x)-1;i>=0;i--)
{
y=1;
for (j=1;j<=Count;j++) y=y*n;
Count++;
Ans=Ans+y*a[i];
}
returnAns;
}