• 这个文件必看啊 太好了


    数学问题:   

    1.精度计算——大数阶乘

    2.精度计算——乘法(大数乘小数)

    3.精度计算——乘法(大数乘大数)

    4.精度计算——加法

    5.精度计算——减法

    6.任意进制转换

    7.最大公约数、最小公倍数

    8.组合序列

    9.快速傅立叶变换(FFT) 

    10.Ronberg算法计算积分

    11.行列式计算

    12.求排列组合数

    13.求某一天星期几   

    字符串处理:

    1.字符串替换

    2.字符串查找

    3.字符串截取

    4.LCS—最大公共子串长度

    5.LCS-生成最大公共子串

    6.数字转化为字符  

    计算几何:   

     1.叉乘法求任意多边形面积

    2.求三角形面积

    3.两矢量间角度4.两点距离(2D、3D)

    5.射向法判断点是否在多边形内部

    6.判断点是否在线段上

    7.判断两线段是否相交

    8.判断线段与直线是否相交

    9.点到线段最短距离

    10.求两直线的交点

    11.判断一个封闭图形是凹集还是凸集

    12.Graham扫描法寻找凸包

    13.求两条线段的交点  

    数论:

    1.x的二进制长度

    2.返回x的二进制表示中从低到高的第i位

    3.模取幂运算

    4.求解模线性方程

    5.求解模线性方程组(中国余数定理)

    6.筛法素数产生器

    7.判断一个数是否素数 

    8.求子距阵最大和

     9.求一个数每一位之和

    10.质因数分解

    11.高斯消元法解线性方程组 

    图论:

     1.Prim算法求最小生成树

    2.Dijkstra算法求单源最短路径

    3.Bellman-ford算法求单源最短路径

    4.Floyd算法求每对节点间最短路径

    5.解欧拉图

    排序/查找:

    1.快速排序

    2.希尔排序

    3.选择法排序

    4.二分查找

    高精度运算专题:

    1.本专题公共函数说明

    2.高精度比较

    3.高精度加法

    4.高精度减法

    5.高精度乘10

    6.高精度乘单精度

    7.高精度乘高精度

    8.高精度除单精度

    9.高精度除高精度

    一、数学问题

    1.精度计算——大数阶乘

          语法:int result=factorial(int n);

          参数:

          n:n 的阶乘

          返回值:阶乘结果的位数

          注意: 

           本程序直接输出n!的结果,需要返回结果请保留long a[]

           需要 math.h

          源程序: 

           int factorial(int n)

          {

          long a[10000];

          int i,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(" %ld",a[m]); 

          for(i=m-1;i>=0;i--) printf("%4.4ld",a[i]);

          return w;

          } 

    2.精度计算——乘法(大数乘小数)

          语法:mult(char c[],char t[],int m);

          参数:

          c[]:被乘数,用字符串表示,位数不限

          t[]:结果,用字符串表示

          m:乘数,限定10以内

          返回值:null

          注意: 

           需要 string.h

          源程序: 

           void mult(char c[],char t[],int m)

          {

              int i,l,k,flag,add=0;

              char s[100];

              l=strlen(c);

              for (i=0;i<l;i++)

                  s[l-i-1]=c[i]-'0'; 

              for (i=0;i<l;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;

              for (i=0;i<l;i++)

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

              t[l]='';

          }

    3.精度计算——乘法(大数乘大数)

          语法:mult(char a[],char b[],char s[]);

          参数:

          a[]:被乘数,用字符串表示,位数不限

          b[]:乘数,用字符串表示,位数不限

          t[]:结果,用字符串表示

          返回值:null

          注意: 

           空间复杂度为 o(n^2)

           需要 string.h

          源程序: 

           void mult(char a[],char b[],char s[])

          {

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

              char result[65];

              alen=strlen(a);blen=strlen(b); 

              for (i=0;i<alen;i++)

              for (j=0;j<blen;j++) res[i][j]=(a[i]-'0')*(b[j]-'0');

              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<k;i++) result[i]+='0';

              for (i=k-1;i>=0;i--) s[i]=result[k-1-i];

              s[k]='';

              while(1)

                  {

                  if (strlen(s)!=strlen(a)&&s[0]=='0') 

                      strcpy(s,s+1);

                  else

                      break;

                  }

          }

     

     

    4.精度计算——加法

          语法:add(char a[],char b[],char s[]);

          参数:

          a[]:被乘数,用字符串表示,位数不限

          b[]:乘数,用字符串表示,位数不限

          t[]:结果,用字符串表示

          返回值:null

          注意: 

           空间复杂度为 o(n^2)

           需要 string.h

          源程序: 

           void add(char a[],char b[],char back[])

          {

              int i,j,k,up,x,y,z,l;

              char *c;

              if (strlen(a)>strlen(b)) l=strlen(a)+2; else l=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'; else x=a[i];

                      if(j<0) y='0'; else y=b[j];

                      z=x-'0'+y-'0';

                      if(up) z+=1;

                      if(z>9) {up=1;z%=10;} else up=0;

                      c[k++]=z+'0';

                      i--;j--;

                  }

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

              i=0;

              c[k]='';

              for(k-=1;k>=0;k--)

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

              back[i]='';

          } 

     

     

    5.精度计算——减法

          语法:sub(char s1[],char s2[],char t[]);

          参数:

          s1[]:被减数,用字符串表示,位数不限

          s2[]:减数,用字符串表示,位数不限

          t[]:结果,用字符串表示

          返回值:null

          注意: 

           默认s1>=s2,程序未处理负数情况

           需要 string.h

          源程序: 

           void sub(char s1[],char s2[],char t[])

          {

              int i,l2,l1,k;

              l2=strlen(s2);l1=strlen(s1);

              t[l1]='';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<l1-1;i++) t[i]=t[i+1];

                  t[l1-1]='';

                  goto loop;

                  }

              if (strlen(t)==0) {t[0]='0';t[1]='';}

          } 

     

     

    6.任意进制转换

          语法:conversion(char s1[],char s2[],char t[]);

          参数:

          s[]:转换前的数字

          s2[]:转换后的数字

          d1:原进制数

          d2:需要转换到的进制数

          返回值:null

          注意: 

           高于9的位数用大写'A'~'Z'表示,2~16位进制通过验证

          源程序: 

           void conversion(char s[],char s2[],long d1,long d2)

          {

              long i,j,t,num;

              char c;

              num=0;

              for (i=0;s[i]!='';i++)

                  {

                  if (s[i]<='9'&&s[i]>='0') t=s[i]-'0'; else t=s[i]-'A'+10;

                  num=num*d1+t;

                  }

              i=0;

              while(1)

                  {

                  t=num%d2;

                  if (t<=9) s2[i]=t+'0'; else s2[i]=t+'A'-10;

                  num/=d2;

                  if (num==0) break;

                  i++;

                  }

              for (j=0;j<i/2;j++)

                  {c=s2[j];s2[j]=s[i-j];s2[i-j]=c;}

              s2[i+1]='';

          }

     

     

    7.最大公约数、最小公倍数

          语法:resulet=hcf(int a,int b)、result=lcd(int a,int b)

          参数:

          a:int a,求最大公约数或最小公倍数

          b:int b,求最大公约数或最小公倍数

          返回值:返回最大公约数(hcf)或最小公倍数(lcd)

          注意: 

           lcd 需要连同 hcf 使用

          源程序: 

           int hcf(int a,int b)

          {

              int r=0;

              while(b!=0)

                  {

                  r=a%b;

                  a=b;

                  b=r;

                  }

              return(a);

          } 

          lcd(int u,int v,int h)

          {

              return(u*v/h);

          }

     

     

    8.组合序列

          语法:m_of_n(int m, int n1, int m1, int* a, int head)

          参数:

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

          源程序: 

           void m_of_n(int m, int n1, int m1, int* a, int head) 

          { 

              int i,t; 

              if(m1<0 || m1>n1) return; 

              if(m1==n1) 

                  { 

                  for(i=0;i<m;i++) cout<<a[i]<<' '; // 输出序列 

                  cout<<' '; 

                  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;

          } 

     

     

    9.快速傅立叶变换(FFT)

          语法:kkfft(double pr[],double pi[],int n,int k,double fr[],double fi[],int 

          l,int il);

          参数:

          pr[n]:输入的实部 

          pi[n]:数入的虚部

          n,k:满足n=2^k

          fr[n]:输出的实部

          fi[n]:输出的虚部

          l:逻辑开关,0 FFT,1 ifFT

          il:逻辑开关,0 输出按实部/虚部;1 输出按模/幅角 

          返回值:null

          注意: 

           需要 math.h

          源程序: 

           void kkfft(pr,pi,n,k,fr,fi,l,il) 

          int n,k,l,il; 

          double pr[],pi[],fr[],fi[]; 

          {

              int it,m,is,i,j,nv,l0; 

              double p,q,s,vr,vi,poddr,poddi; 

              for (it=0; it<=n-1; it++) 

                  {

                   m=it; is=0; 

                  for (i=0; i<=k-1; i++) 

                      {j=m/2; is=2*is+(m-2*j); m=j;}

                  fr[it]=pr[is]; fi[it]=pi[is]; 

                  } 

              pr[0]=1.0; pi[0]=0.0; 

              p=6.283185306/(1.0*n); 

              pr[1]=cos(p); pi[1]=-sin(p); 

              if (l!=0) pi[1]=-pi[1]; 

              for (i=2; i<=n-1; i++) 

                  {

                 p=pr[i-1]*pr[1];

                 q=pi[i-1]*pi[1]; 

                  s=(pr[i-1]+pi[i-1])*(pr[1]+pi[1]); 

                  pr[i]=p-q; pi[i]=s-p-q; 

                  } 

              for (it=0; it<=n-2; it=it+2) 

                  {

                 vr=fr[it]; vi=fi[it]; 

                  fr[it]=vr+fr[it+1]; fi[it]=vi+fi[it+1]; 

                  fr[it+1]=vr-fr[it+1]; fi[it+1]=vi-fi[it+1]; 

                  } 

              m=n/2; nv=2; 

              for (l0=k-2; l0>=0; l0--) 

                  {

                  m=m/2; nv=2*nv; 

                  for (it=0; it<=(m-1)*nv; it=it+nv) 

                      for (j=0; j<=(nv/2)-1; j++) 

                          {

                         p=pr[m*j]*fr[it+j+nv/2]; 

                          q=pi[m*j]*fi[it+j+nv/2]; 

                          s=pr[m*j]+pi[m*j]; 

                          s=s*(fr[it+j+nv/2]+fi[it+j+nv/2]); 

                          poddr=p-q; poddi=s-p-q; 

                          fr[it+j+nv/2]=fr[it+j]-poddr; 

                          fi[it+j+nv/2]=fi[it+j]-poddi; 

                          fr[it+j]=fr[it+j]+poddr; 

                          fi[it+j]=fi[it+j]+poddi; 

                          } 

                  } 

              if (l!=0) 

                  for (i=0; i<=n-1; i++) 

                      {

                     fr[i]=fr[i]/(1.0*n); 

                      fi[i]=fi[i]/(1.0*n); 

                      } 

              if (il!=0) 

                      for (i=0; i<=n-1; i++) 

                      {

                     pr[i]=sqrt(fr[i]*fr[i]+fi[i]*fi[i]); 

                      if (fabs(fr[i])<0.000001*fabs(fi[i])) 

                          {

                         if ((fi[i]*fr[i])>0) pi[i]=90.0; 

                          else pi[i]=-90.0; 

                          } 

                      else 

                          pi[i]=atan(fi[i]/fr[i])*360.0/6.283185306; 

                      } 

              return; 

          } 

     

     

    10.Ronberg算法计算积分

          语法:result=integral(double a,double b);

          参数:

          a:积分上限

          b:积分下限

          function f:积分函数

          返回值:f在(a,b)之间的积分值

          注意: 

           function f(x)需要自行修改,程序中用的是sina(x)/x

           需要 math.h

           默认精度要求是1e-5

          源程序: 

           double f(double x)

          { 

              return sin(x)/x; //在这里插入被积函数 

          }

     

          double integral(double a,double b) 

          { 

              double h=b-a; 

              double t1=(1+f(b))*h/2.0;

              int k=1; 

              double r1,r2,s1,s2,c1,c2,t2; 

          loop: 

              double s=0.0; 

              double x=a+h/2.0; 

              while(x<b) 

                  { 

                  s+=f(x); 

                  x+=h; 

                  } 

              t2=(t1+h*s)/2.0;

              s2=t2+(t2-t1)/3.0;

              if(k==1)

                { 

                  k++;h/=2.0;t1=t2;s1=s2;

                  goto loop; 

                  } 

              c2=s2+(s2-s1)/15.0; 

              if(k==2){ 

                  c1=c2;k++;h/=2.0; 

                  t1=t2;s1=s2; 

                  goto loop; 

                  } 

              r2=c2+(c2-c1)/63.0; 

              if(k==3){ 

                  r1=r2; c1=c2;k++; 

                  h/=2.0; 

                  t1=t2;s1=s2;

                  goto loop; 

                  } 

              while(fabs(1-r1/r2)>1e-5){ 

                  r1=r2;c1=c2;k++;

                  h/=2.0; 

                  t1=t2;s1=s2; 

                  goto loop; 

                  } 

              return r2;

          } 

     

     

    11.行列式计算

          语法:result=js(int s[][],int n)

          参数:

          s[][]:行列式存储数组

          n:行列式维数,递归用

          返回值:行列式值

          注意: 

           函数中常数N为行列式维度,需自行定义

          源程序: 

           int js(s,n) 

          int s[][N],n; 

          {

              int z,j,k,r,total=0; 

              int b[N][N];/*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<n-1;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); /*递归调用*/ 

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

                      total=total+r; 

                      } 

                  } 

              else if(n==2)

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

              return total; 

          } 

     

     

    12.求排列组合数

          语法:result=P(long n,long m); / result=long C(long n,long m);

          参数:

          m:排列组合的上系数

          n:排列组合的下系数

          返回值:排列组合数

          注意: 

           符合数学规则:m<=n

          源程序: 

           long P(long n,long m)

          {

              long p=1;

              while(m!=0)

                  {p*=n;n--;m--;}

              return p;

          } 

          long C(long n,long m)

          {

              long i,c=1;

              i=m;

              while(i!=0)

                  {c*=n;n--;i--;}

              while(m!=0)

                  {c/=m;m--;}

              return c;

          } 

     

     

    13.求某一天星期几

          语法:result=weekday(int N,int M,int d)

          参数:

          N,M,d:年月日,例如:2003,11,4

          返回值:0:星期天,1星期一……

          注意: 

           需要math.h

           适用于1582年10月15日之后, 因为罗马教皇格里高利十三世在这一天启用新历法.

          源程序: 

           int weekday(int N,int M,int d)

          {

          int m,n,c,y,w;

          m=(M-2)%12;

          if (M>=3) n=N;else n=N-1;

          c=n/100;

          y=n%100;

          w=(int)(d+floor(13*m/5)+y+floor(y/4)+floor(c/4)-2*c)%7;

          while(w<0) w+=7;

          return w;

          }

     

     

    二、字符串处理

    1.字符串替换

          语法:replace(char str[],char key[],char swap[]);

          参数:

          str[]:在此源字符串进行替换操作

          key[]:被替换的字符串,不能为空串

          swap[]:替换的字符串,可以为空串,为空串表示在源字符中删除key[]

          返回值:null

          注意: 

           默认str[]长度小于1000,如否,重新设定设定tmp大小

           需要 string.h

          源程序: 

           void replace(char str[],char key[],char swap[])

          {

              int l1,l2,l3,i,j,flag;

              char tmp[1000];

              l1=strlen(str);

              l2=strlen(key);

              l3=strlen(swap);

              for (i=0;i<=l1-l2;i++)

                  {

                  flag=1;

                  for (j=0;j<l2;j++)

                      if (str[i+j]!=key[j]) {flag=0;break;}

                  if (flag)

                      {

                      strcpy(tmp,str);

                      strcpy(&tmp[i],swap);

                      strcpy(&tmp[i+l3],&str[i+l2]);

                      strcpy(str,tmp);

                      i+=l3-1;

                      l1=strlen(str);

                      }

                  }

          }

     

     

    2.字符串查找

          语法:result=strfind(char str[],char key[]);

          参数:

          str[]:在此源字符串进行查找操作

          key[]:被查找的字符串,不能为空串

          返回值:如果查找成功,返回key在str中第一次出现的位置,否则返回-1

          注意: 

           需要 string.h

          源程序: 

           int strfind(char str[],char key[])

          {

              int l1,l2,i,j,flag;

              l1=strlen(str);

              l2=strlen(key);

              for (i=0;i<=l1-l2;i++)

                  {

                  flag=1;

                  for (j=0;j<l2;j++)

                      if (str[i+j]!=key[j]) {flag=0;break;}

                  if (flag) return i;

                  }

              return -1;

          } 

     

     

    3.字符串截取

          语法:mid(char str[],int start,int len,char strback[])

          参数:

          str[]:操作的目标字符串

          start:从第start个字符串开始,截取长度为len的字符

          len:从第start个字符串开始,截取长度为len的字符

          strback[]:截取的到的字符

          返回值:0:超出字符串长度,截取失败;1:截取成功

          注意: 

           需要 string.h

          源程序: 

           int mid(char str[],int start,int len,char strback[])

          {

              int l,i,k=0;

              l=strlen(str);

              if (start+len>l) return 0;

              for (i=start;i<start+len;i++)

                  strback[k++]=str[i];

              strback[k]='';

              return 1;

          } 

     

     

    4.LCS-最大公共子串长度

          语法:result=lcs_len(char *a, char *b);

          参数:

          a,b[]:根据a,b生成最大公共子串

          返回值:最大公共子串的长度

          注意: 

           需要 string.h

           M、N是a,b数组的最大可能长度

           如果不需要生成公共子串,c[M][N]不可设置为全局变量

          源程序: 

           #define M 20

          #define N 20

          int c[M][N]; 

          int lcs_len(char *a, char *b)

          {

          int m=strlen(a),n=strlen(b),i,j;

          for(i=0;i<=m;i++) c[i][0]=0;

          for(j=0;j<=n;j++) c[0][j]=0;

          for(i=1;i<=m;i++)

              for(j=1;j<=n;j++)

              {

              if(a[i-1]==b[j-1])

                  c[i][j]=c[i-1][j-1]+1;

              else if(c[i-1][j]>c[i][j-1])

                  c[i][j]=c[i-1][j];

              else

                  c[i][j]=c[i][j-1];

              }

          return c[m][n];

          }

     

     

    5.LCS-最大公共子串长度

          语法:result=build_lcs(char s[], char *a, int blen, int clen);

          参数:

          *a:生成公共子串的字符串a,b中的a

          s[]:接受返回结果的字符串数组

          blen:生成公共子串的字符串a,b中的b的长度

          clen:最大公共子串的长度,通过lcs_len函数求得

          返回值:最大公共子串的长度

          注意: 

           需要 string.h

           需要lcs_len函数求clen并且生成c[M][N]

           可通过result=build_lcs返回指针或者通过build_lcs(s,a,blen,clen),用s接受结果

          源程序: 

           char *build_lcs(char s[], char *a, int blen, int clen)

          {

          int k=clen,alen=strlen(a),i,j;

          s[k]='';

          i=alen,j=blen;

          while(k>0)

              {

              if(c[i][j]==c[i-1][j])

              i--;

              else if(c[i][j]==c[i][j-1])

              j--;

              else

                  {

                  s[--k]=a[i-1];

                  i--;j--;

                  }

              }

          return s;

          } 

     

     

    6.数字转换为字符

          语法:cstr(int k,char o[]);

          参数:

          k:转换的数字

          o[]:存储转换结果的字符串

          返回值:null

          注意: 

           需要 math.h

          源程序: 

           void cstr(int k,char o[])

          {

              int len,i,t;

              len=log10(k)+1;

              for (i=len;i>0;i--)

                  {

                  t=k%10;

                  k-=t;k/=10;

                  o[i-1]='0'+t;

                  }

              o[len]='';

          }

     

     

    三、计算几何

    1.叉乘法求任意多边形面积

          语法:result=polygonarea(Point *polygon,int N);

          参数:

          *polygon:多变形顶点数组

          N:多边形顶点数目

          返回值:多边形面积

          注意: 

           支持任意多边形,凹、凸皆可

           多边形顶点输入时按顺时针顺序排列

          源程序: 

           typedef struct {

              double x,y;

          } Point; 

          double polygonarea(Point *polygon,int N)

          {

              int i,j;

              double area = 0;

              for (i=0;i<N;i++) {

                  j = (i + 1) % N;

                  area += polygon[i].x * polygon[j].y;

                  area -= polygon[i].y * polygon[j].x;

                  }

              area /= 2;

              return(area < 0 ? -area : area);

          }

     

     

    2.求三角形面积

          语法:result=area3(float x1,float y1,float x2,float y2,float x3,float y3);

          参数:

          x1~3:三角形3个顶点x坐标

          y1~3:三角形3个顶点y坐标

          返回值:三角形面积

          注意: 

           需要 math.h

          源程序: 

           float area3(float x1,float y1,float x2,float y2,float x3,float y3)

          {

              float a,b,c,p,s;

              a=sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));

              b=sqrt((x1-x3)*(x1-x3)+(y1-y3)*(y1-y3));

              c=sqrt((x3-x2)*(x3-x2)+(y3-y2)*(y3-y2));

              p=(a+b+c)/2;

              s=sqrt(p*(p-a)*(p-b)*(p-c));

              return s;

          }

     

     

    3.两矢量间角度

          语法:result=angle(double x1, double y1, double x2, double y2);

          参数:

          x/y1~2:两矢量的坐标

          返回值:两的角度矢量

          注意: 

           返回角度为弧度制,并且以逆时针方向为正方向

           需要 math.h

          源程序: 

           #define PI 3.1415926

     

          double angle(double x1, double y1, double x2, double y2)

          {

              double dtheta,theta1,theta2; 

              theta1 = atan2(y1,x1);

              theta2 = atan2(y2,x2);

              dtheta = theta2 - theta1;

              while (dtheta > PI)

                  dtheta -= PI*2;

              while (dtheta < -PI)

                  dtheta += PI*2; 

              return(dtheta);

          }

     

     

    4.两点距离(2D、3D)

          语法:result=distance_2d(float x1,float x2,float y1,float y2);

          参数:

          x/y/z1~2:各点的x、y、z坐标

          返回值:两点之间的距离

          注意: 

           需要 math.h

          源程序: 

           float distance_2d(float x1,float x2,float y1,float y2) 

          {

              return(sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)));

          }

     

     

          float distance_3d(float x1,float x2,float y1,float y2,float z1,float z2)

          {

              return(sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)+(z1-z2)*(z1-z2)));

          }

     

     

    5.射向法判断点是否在多边形内部

          语法:result=insidepolygon(Point *polygon,int N,Point p);

          参数:

          *polygon:多边形顶点数组

          N:多边形顶点个数

          p:被判断点

          返回值:0:点在多边形内部;1:点在多边形外部

          注意: 

           若p点在多边形顶点或者边上,返回值不确定,需另行判断

           需要 math.h

          源程序: 

           #define MIN(x,y) (x < y ? x : y)

          #define MAX(x,y) (x > y ? x : y)

          typedef struct {

              double x,y;

          } Point;

          int insidepolygon(Point *polygon,int N,Point p)

          {

              int counter = 0;

              int i;

              double xinters;

              Point p1,p2;

              p1 = polygon[0];

              for (i=1;i<=N;i++) {

                  p2 = polygon[i % N];

                  if (p.y > MIN(p1.y,p2.y)) {

                      if (p.y <= MAX(p1.y,p2.y)) {

                          if (p.x <= MAX(p1.x,p2.x)) {

                              if (p1.y != p2.y) {

                                  xinters = (p.y-p1.y)*(p2.x-p1.x)/(p2.y-p1.y)+p1.x;

                                  if (p1.x == p2.x || p.x <= xinters)

                                      counter++;

                                  }

                              }

                          }

                      }

                      p1 = p2;

                  }

              if (counter % 2 == 0)

                  return(OUTSIDE);

              else

                  return(INSIDE);

          }

     

     

    6.判断点是否在线段上

          语法:result=Pointonline(Point p1,Point p2,Point p);

          参数:

          p1、p2:线段的两个端点

          p:被判断点

          返回值:0:点在不在线段上;1:点在线段上

          注意: 

           若p线段端点上返回1

           需要 math.h

          源程序: 

           #define MIN(x,y) (x < y ? x : y)

          #define MAX(x,y) (x > y ? x : y) 

          typedef struct {

          double x,y;

          } Point;

          int FC(double x1,double x2)

          {

              if (x1-x2<0.000002&&x1-x2>-0.000002) return 1; else return 0;

          }

     

     

          int Pointonline(Point p1,Point p2,Point p)

          {

              double x1,y1,x2,y2;

              x1=p.x-p1.x;

              x2=p2.x-p1.x;

              y1=p.y-p1.y;

              y2=p2.y-p1.y;

              if (FC(x1*y2-x2*y1,0)==0) return 0;

              if ((MIN(p1.x,p2.x)<=p.x&&p.x<=MAX(p1.x,p2.x))&&

                      (MIN(p1.y,p2.y)<=p.y&&p.y<=MAX(p1.y,p2.y)))

                  return 1; else return 0;

          }

     

     

    7.判断两线段是否相交

          语法:result=lineintersect(Point p1,Point p2,Point p3,Point p4);

          参数:

          p1~4:两条线段的四个端点

          返回值:0:两线段不相交;1:两线段相交;2两线段首尾相接

          注意: 

           p1!=p2;p3!=p4;

          源程序: 

           #define MIN(x,y) (x < y ? x : y)

          #define MAX(x,y) (x > y ? x : y) 

          typedef struct {

              double x,y;

          } Point;

          int lineintersect(Point p1,Point p2,Point p3,Point p4)

          {

              Point tp1,tp2,tp3;

              if 

          ((p1.x==p3.x&&p1.y==p3.y)||(p1.x==p4.x&&p1.y==p4.y)||(p2.x==p3.x&&p2.y==p3.y)||(p2.x==p4.x&&p2.y==p4.y))

                  return 2;

          //快速排斥试验

              if 

          ((MIN(p1.x,p2.x)<=p3.x&&p3.x<=MAX(p1.x,p2.x)&&MIN(p1.y,p2.y)<=p3.y&&p3.y<=MAX(p1.y,p2.y))||

                      

          (MIN(p1.x,p2.x)<=p4.x&&p4.x<=MAX(p1.x,p2.x)&&MIN(p1.y,p2.y)<=p4.y&&p4.y<=MAX(p1.y,p2.y)))

                  ;else return 0;

          //跨立试验

              tp1.x=p1.x-p3.x;

              tp1.y=p1.y-p3.y;

              tp2.x=p4.x-p3.x;

              tp2.y=p4.y-p3.y;

              tp3.x=p2.x-p3.x;

              tp3.y=p2.y-p3.y;

              if ((tp1.x*tp2.y-tp1.y*tp2.x)*(tp2.x*tp3.y-tp2.y*tp3.x)>=0) return 1; 

          else return 0;

          }

     

     

    8.判断线段与直线是否相交

          语法:result=lineintersect(Point p1,Point p2,Point p3,Point p4);

          参数:

          p1、p2:线段的两个端点

          p3、p4:直线上的两个点

          返回值:0:线段直线不相交;1:线段和直线相交

          注意: 

           如线段在直线上,返回 1

          源程序: 

           typedef struct {

              double x,y;

          } Point;

          int lineintersect(Point p1,Point p2,Point p3,Point p4)

          {

              Point tp1,tp2,tp3;

              tp1.x=p1.x-p3.x;

              tp1.y=p1.y-p3.y;

              tp2.x=p4.x-p3.x;

              tp2.y=p4.y-p3.y;

              tp3.x=p2.x-p3.x;

              tp3.y=p2.y-p3.y;

              if ((tp1.x*tp2.y-tp1.y*tp2.x)*(tp2.x*tp3.y-tp2.y*tp3.x)>=0) return 1; 

          else return 0;

          }

     

     

    9.点到线段最短距离

          语法:result=mindistance(Point p1,Point p2,Point q);

          参数:

          p1、p2:线段的两个端点

          q:判断点

          返回值:点q到线段p1p2的距离

          注意: 

           需要 math.h

          源程序: 

           #define MIN(x,y) (x < y ? x : y)

          #define MAX(x,y) (x > y ? x : y)

          typedef struct {

              double x,y;

          } Point;

          double mindistance(Point p1,Point p2,Point q)

          {

              int flag=1;

              double k;

              Point s;

              if (p1.x==p2.x) {s.x=p1.x;s.y=q.y;flag=0;}

              if (p1.y==p2.y) {s.x=q.x;s.y=p1.y;flag=0;}

              if (flag)

                  {

                  k=(p2.y-p1.y)/(p2.x-p1.x);

                  s.x=(k*k*p1.x+k*(q.y-p1.y)+q.x)/(k*k+1);

                  s.y=k*(s.x-p1.x)+p1.y;

                  }

              if (MIN(p1.x,p2.x)<=s.x&&s.x<=MAX(p1.x,p2.x))

                  return sqrt((q.x-s.x)*(q.x-s.x)+(q.y-s.y)*(q.y-s.y));

              else

                  return 

          MIN(sqrt((q.x-p1.x)*(q.x-p1.x)+(q.y-p1.y)*(q.y-p1.y)),sqrt((q.x-p2.x)*(q.x-p2.x)+(q.y-p2.y)*(q.y-p2.y)));

          }

     

     

    10.求两直线的交点

          语法:result=mindistance(Point p1,Point p2,Point q);

          参数:

          p1~p4:直线上不相同的两点

          *p:通过指针返回结果

          返回值:1:两直线相交;2:两直线平行

          注意: 

           如需要判断两线段交点,检验k和对应k1(注释中)的值是否在0~1之间,用在0~1之间的那个求交点

          源程序: 

           typedef struct {

             double x,y;

          } Point;

          int linecorss(Point p1,Point p2,Point p3,Point p4,Point *p)

          {

             double k;

             if ((p4.y-p3.y)*(p2.x-p1.x)-(p4.x-p3.x)*(p2.y-p1.y)==0) return 0;

            if ((p4.x-p3.x)*(p1.y-p3.y)-(p4.y-p3.y)*(p1.x-p3.x)==0&&

                     (p2.x-p1.x)*(p1.y-p3.y)-(p2.y-p1.y)*(p1.x-p3.x)==0) return 0;

              

          k=((p4.x-p3.x)*(p1.y-p3.y)-(p4.y-p3.y)*(p1.x-p3.x))/((p4.y-p3.y)*(p2.x-p1.x)-(p4.x-p3.x)*(p2.y-p1.y));

          //k1=((p2.x-p1.x)*(p1.y-p3.y)-(p2.y-p1.y)*(p1.x-p3.x))/((p4.y-p3.y)*(p2.x-p1.x)-(p4.x-p3.x)*(p2.y-p1.y));

             (*p).x=p1.x+k*(p2.x-p1.x);

             (*p).y=p1.y+k*(p2.y-p1.y);

             return 1;

          }

     

     

    11.判断一个封闭图形是凹集还是凸集

          语法:result=convex(Point *p,int n);

          参数:

          *p:封闭曲线顶点数组

          n:封闭曲线顶点个数

          返回值:1:凸集;-1:凹集;0:曲线不符合要求无法计算

          注意: 

           默认曲线为简单曲线:无交叉、无圈

          源程序: 

           typedef struct {

              double x,y;

          } Point;

          int convex(Point *p,int n)

          {

              int i,j,k;

              int flag = 0;

              double z;

              if (n < 3)

                  return(0);

              for (i=0;i<n;i++) {

                  j = (i + 1) % n;

                  k = (i + 2) % n;

                  z = (p[j].x - p[i].x) * (p[k].y - p[j].y);

                  z -= (p[j].y - p[i].y) * (p[k].x - p[j].x);

                  if (z < 0)

                      flag |= 1;

                  else if (z > 0)

                      flag |= 2;

                  if (flag == 3)

                      return -1; //CONCAVE

                  }

              if (flag != 0)

                  return 1; //CONVEX

              else

              return 0;

          }

     

     

    12.Graham扫描法寻找凸包

          语法:Graham_scan(Point PointSet[],Point ch[],int n,int &len);

          参数:

          PointSet[]:输入的点集

          ch[]:输出的凸包上的点集,按照逆时针方向排列

          n:PointSet中的点的数目

          len:输出的凸包上的点的个数

          返回值:null

          源程序: 

           struct Point{

              float x,y;

          }; 

          float multiply(Point p1,Point p2,Point p0)

          {

              return((p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y)); 

          }

          float distance(Point p1,Point p2)

          {

              return(sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y))); 

          }

          void Graham_scan(Point PointSet[],Point ch[],int n,int &len)

          {

              int i,j,k=0,top=2;

              Point tmp;

     

             for(i=1;i<n;i++)

              if 

          ((PointSet[i].y<PointSet[k].y)||((PointSet[i].y==PointSet[k].y)&&(PointSet[i].x<PointSet[k].x)))

              k=i;

              tmp=PointSet[0];

              PointSet[0]=PointSet[k];

              PointSet[k]=tmp; 

              for (i=1;i<n-1;i++)

                  {

                  k=i;

                  for (j=i+1;j<n;j++)

                      if ( (multiply(PointSet[j],PointSet[k],PointSet[0])>0) ||

                               ((multiply(PointSet[j],PointSet[k],PointSet[0])==0)

                                   

          &&(distance(PointSet[0],PointSet[j])<distance(PointSet[0],PointSet[k])))   

          )

                          k=j;

                  tmp=PointSet[i];

                  PointSet[i]=PointSet[k];

                  PointSet[k]=tmp;

                  }

              ch[0]=PointSet[0];

              ch[1]=PointSet[1];

              ch[2]=PointSet[2]; 

              for (i=3;i<n;i++)

                  {

                  while (multiply(PointSet[i],ch[top],ch[top-1])>=0) top--;

                  ch[++top]=PointSet[i];

                  }

              len=top+1;

          }

     

     

    13.求两条线段的交点

          语法:Result=IntersectPoint (Point p1,Point p2,Point p3,Point p4,Point &p);

          参数:

          P1~P4:两条线断4个端点

          P:线段交点

          返回值:如果两条线段平行无交点,返回 0,否则返回 1

          源程序: 

           struct Point{

              float x,y;

          }; 

     

          int IntersectPoint (Point p1,Point p2,Point p3,Point p4,Point &p)

          {

          float a,b,c,d,e,f;

          a=p2.y-p1.y;

          b=p1.x-p2.x;

          c=p1.y*(p2.x-p1.x)+p1.x*(p2.y-p1.y);

          d=p4.y-p3.y;

          e=p3.x-p4.x;

          f=p3.y*(p4.x-p3.x)+p1.x*(p4.y-p3.y); 

          if (a*e==b*d)

              return 0;

          else

              {

              p.x=(e*c-b*f)/(b*d-a*e);

              p.y=(d*c-a*f)/(a*e-b*d);

              return 1;

              }

          }

     

     

    四、数论

    1.x的二进制长度

          语法:result=BitLength(int x);

          参数:

          x:测长的x

          返回值:x的二进制长度

          源程序: 

           int BitLength(int x)

          {

              int d = 0;

              while (x > 0) {

                  x >>= 1;

                  d++;

              }

              return d;

          }

     

     

    2.返回x的二进制表示中从低到高的第i位

          语法:result=BitAt(int x, int i);

          参数:

          x:十进制 x

          i:要求二进制的第i位

          返回值:返回x的二进制表示中从低到高的第i位

          注意: 

           最低位为第一位

          源程序: 

           int BitAt(int x, int i)

          {

              return ( x & (1 << (i-1)) );

          }

     

     

    3.模取幂运算

          语法:result=Modular_Expoent(int a,int b,int n);

          参数:

          a、b、n:a^b mod n 的对应参数

          返回值:a^b mod n 的值

          注意: 

           需要BitLength和BitAt

          源程序: 

           int Modular_Expoent(int a,int b,int n)

          {

              int i, y=1;

              for (i = BitLength(b); i > 0; i--)

                  { 

                  y = (y*y)%n;

                  if (BitAt(b,i) > 0) 

                  y = (y*a)%n;

                  }

              return y;

          }

     

     

    4.求解模线性方程

          语法:result=modular_equation(int a,int b,int n);

          参数:

          a、b、n:ax=b (mod n) 的对应参数

          返回值:方程的解

          源程序: 

           int ext_euclid(int a,int b,int &x,int &y)  //求gcd(a,b)=ax+by

          {

              int t,d;

              if (b==0) {x=1;y=0;return a;}

              d=ext_euclid(b,a %b,x,y);

              t=x;

              x=y;

              y=t-a/b*y;

              return d;

          }

     

          void modular_equation(int a,int b,int n)

          {

              int e,i,d;

              int x,y;

              d=ext_euclid(a,n,x,y);

              if (b%d>0)

                 printf("No answer! ");

              else

                  {

                 e=(x*(b/d))%n;

                  for (i=0;i<d;i++)

                      printf("The %dth answer is : %ld ",i+1,(e+i*(n/d))%n); 

                  }

          }

     

     

    5.求解模线性方程组(中国余数定理)

          语法:result=Modular_Expoent(int a,int b,int n);

          参数:

          B[]、W[]:a=B[] (mod W[]) 的对应参数

          返回值:a 的值

          注意: 

           其中W[],B[]已知,W[i]>0且W[i]与W[j]互质, 求a

          源程序: 

           int ext_euclid(int a,int b,int &x,int &y)  //求gcd(a,b)=ax+by

          {

              int t,d;

              if (b==0) {x=1;y=0;return a;}

              d=ext_euclid(b,a %b,x,y);

              t=x;

              x=y;

              y=t-a/b*y;

              return d;

          }

     

     

          int China(int B[],int W[],int k)

          {

             int i;

              int d,x,y,a=0,m,n=1;

              for (i=0;i<k;i++)

                  n*=W[i];

              for (i=0;i<k;i++)

                 {

                 m=n/W[i];

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

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

                  }

              if (a>0) return a;

              else return(a+n);

          }

     

     

    6.筛法素数产生器

          语法:result=prime(int a[],int n);

          参数:

          a[]:用于返回素数的数组

          n:产生n以内的素数,按升序放入a[]中

          返回值:n以内素数的个数

          注意: 

           其中W[],B[]已知,W[i]>0且W[i]与W[j]互质, 求a

          源程序: 

           int prime(int a[],int n)

          {

              int i,j,k,x,num,*b;

              n++;

              n/=2;

              b=new int[(n+1)*2];

              a[0]=2;a[1]=3;num=2;

              for(i=1;i<=2*n;i++)

                  b[i]=0;

              for(i=3;i<=n;i+=3)

                  for(j=0;j<2;j++)

                      {

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

                      while(b[x]==0)

                          {

                          a[num++]=x;

                          for(k=x;k<=2*n;k+=x)

                              b[k]=1;

                          }

                      }

              return num;

          }

     

     

    7.判断一个数是否素数

          语法:result=comp(int n);

          参数:

          n:判断n是否素数

          返回值:素数返回1,否则返回0

          源程序: 

           //传统方法

          int comp(int n){ 

             if(n<2)return 0; 

             if(n%2==0)return 0; 

             for(int i=3;i<=sqrt(n);i+=2) if(n%i==0) return 0; 

             return 1; 

          }

           

          //大数素数判定,(1/4)^K出错概率

          int powermod(int a,int b,int n)

          {//get (a^b)%n 

             i64 d=1, t=a; 

             while(b>0){ 

                if(t==1)return d; 

                if(b%2==1)d=(t*d)%n; 

                b/=2; t=(t*t)%n; 

             } 

             return d; 

          } 

          int isprime(int n,int k){ 

                   int a; 

             while(k--){ 

                            a=rand(); 

                            a%=n-3; a+=2; 

                if(powermod(k+2,n-1,n)!=1)return 0; 

             } 

             return 1; 

          }

     

     

    8.求距阵最大和

          语法:result=maxsum2(int n);

          参数:

          a:距阵

          n,m:距阵行列数

          返回值:一维,二维距阵最大和

          源程序: 

           int a[101][101]; 

          int maxsum(int a[],int n)//一维最大串 

          { 

              int sum=-10000000,b=0; 

              int i; 

              for(i=0;i<n;i++) 

                  { 

            if (b>0) 

             b+=a[i]; 

            else 

             b=a[i]; 

            if(b>sum) 

             sum=b; 

            } 

           return sum; 

          } 

          int maxsum2(int m,int n)//二维最大串 

          { 

           int sum = -10000000; 

           int i,j,k,max; 

           int* b = new int[n+1]; 

           for (i=0;i<m;i++) 

            { 

            for(k=0;k<n;k++) 

             b[k]=a[i][k]; 

            max = maxsum(b,n);//第i列的一维最大串 

            if(max>sum) 

             sum=max; 

            for(j=i+1;j<m;j++) 

             { 

             for (k=0;k<=n;k++)b[k]+=a[j][k]; 

             max = maxsum(b,n);//类似maxsum,通过每列相加求二维最大串 

             if(max>sum)sum=max; 

             } 

            } 

           delete []b; 

           return sum; 

          } 

     

     

    8.求一个数每一位相加之和

          语法:result=digadd(int n)

          参数:

          n:待求数字

          返回值:各数字之和

          源程序: 

           int digadd(int n)

          {

          int i=0,k=0;

          while(i=n%10,n/=10)  k+=i;

          return k+i;

          }

     

     

    10.质因数分解

          语法:result=int reduce(int prime[],int pn,int n,int rest[])

          参数:

          Prime[]:素数表,至少需要达到sqrt(n)

          pn:素数表的元素个数

          N:待分解的数

          Rest:分解结果,按照升序排列

          返回值:分解因子个数

          源程序: 

           int reduce(int prime[],int pn,int n,int rest[])

          {

          int i,k=0;

          for(i=0;i<pn;i++)

               {

               if (n==1) break;

               if (prime[i]*prime[i]>n) {rest[k++]=n;break;}

               while(n%prime[i]==0)

                   {

                   n/=prime[i];

                   rest[k++]=prime[i];

                   }

               }

          return k;

          }

     

     

    11.高斯消元法解线性方程组

          语法:gauss(int n,double ** a)

          参数:

          N:变量个数

          Rest:变量系数行列式

          源程序: 

           void gauss(int n,double **a)

          {

           int i, j, k;

           double client, temp = 0.0;

           

           for(k = 0; k < n - 1; k++)

            for(i = k + 1; i < n; i++)

            {

             client = a[i][k]/a[k][k];

             for(j = k + 1; j < n; j++)

              a[i][j] = a[i][j] - client * a[k][j];

             a[i][n] = a[j - 1][n] - client * a[k][n]; 

            }

           a[n - 1][n] = a[n - 1][n]/a[n - 1][n - 1];

           for(i = n - 2; i >= 0; i--)

           {

            for (j = i + 1; j < n; j++)

             temp += a[i][j] * a[j][n];

            a[i][n] = (a[i][n] - temp) / a[i][i];

           }

          }

           

          //打印

          //for(i = 0; i < n; i++)

          // printf("X%d = %lf ", i + 1, a[i][n]);

     

     

    五、图论

    1.Prim算法求最小生成树

          语法:prim(Graph G,int vcount,int father[]);

          参数:

          G:图,用邻接矩阵表示

          vcount:表示图的顶点个数

          father[]:用来记录每个节点的父节点

          返回值:null

          注意: 

           常数max_vertexes为图最大节点数

           常数infinity为无穷大

          源程序: 

           #define infinity 1000000

          #define max_vertexes 5 

     

          typedef int Graph[max_vertexes][max_vertexes];

     

          void prim(Graph G,int vcount,int father[])

          {

              int i,j,k;

              int lowcost[max_vertexes],closeset[max_vertexes],used[max_vertexes];

              for (i=0;i<vcount;i++)

                  {

                  lowcost[i]=G[0][i];

                  closeset[i]=0; 

                  used[i]=0;

                  father[i]=-1; 

                  }

              used[0]=1; 

              for (i=1;i<vcount;i++)

                  {

                  j=0;

                  while (used[j]) j++;

                  for (k=0;k<vcount;k++)

                      if ((!used[k])&&(lowcost[k]<lowcost[j])) j=k;

                  father[j]=closeset[j]; 

                  used[j]=1;

                  for (k=0;k<vcount;k++)

                      if (!used[k]&&(G[j][k]<lowcost[k]))

                          { lowcost[k]=G[j][k];

                          closeset[k]=j; }

                  }

          }

     

     

    2.Dijkstra算法求单源最短路径

          语法:result=Dijkstra(Graph G,int n,int s,int t, int path[]);

          参数:

          G:图,用邻接矩阵表示

          n:图的顶点个数

          s:开始节点

          t:目标节点

          path[]:用于返回由开始节点到目标节点的路径

          返回值:最短路径长度

          注意: 

           输入的图的权必须非负

           顶点标号从0开始

           用如下方法打印路径:

              i=t;

              while (i!=s)

                  {

                  printf("%d<--",i+1);

                  i=path[i];

                  }

              printf("%d ",s+1); 

          源程序: 

           int Dijkstra(Graph G,int n,int s,int t, int path[])

          {

              int i,j,w,minc,d[max_vertexes],mark[max_vertexes];

              for (i=0;i<n;i++) mark[i]=0;

              for (i=0;i<n;i++)

                  { d[i]=G[s][i];

                  path[i]=s; }

              mark[s]=1;path[s]=0;d[s]=0;

              for (i=1;i<n;i++)

                  {

                 minc=infinity;

                  w=0;

                  for (j=0;j<n;j++)

                      if ((mark[j]==0)&&(minc>=d[j])) {minc=d[j];w=j;}

                  mark[w]=1;

                  for (j=0;j<n;j++)

                  if ((mark[j]==0)&&(G[w][j]!=infinity)&&(d[j]>d[w]+G[w][j]))

                      { d[j]=d[w]+G[w][j];

                      path[j]=w; }

                  }

              return d[t];

          }

     

     

    3.Bellman-ford算法求单源最短路径

          语法:result=Bellman_ford(Graph G,int n,int s,int t,int path[],int success);

          参数:

          G:图,用邻接矩阵表示

          n:图的顶点个数

          s:开始节点

          t:目标节点

          path[]:用于返回由开始节点到目标节点的路径

          success:函数是否执行成功

          返回值:最短路径长度

          注意: 

           输入的图的权可以为负,如果存在一个从源点可达的权为负的回路则success=0

           顶点标号从0开始

           用如下方法打印路径:

              i=t;

              while (i!=s)

                  {

                  printf("%d<--",i+1);

                  i=path[i];

                  }

              printf("%d ",s+1); 

          源程序: 

           int Bellman_ford(Graph G,int n,int s,int t,int path[],int success)

          {

              int i,j,k,d[max_vertexes];

              for (i=0;i<n;i++) {d[i]=infinity;path[i]=0;}

              d[s]=0;

              for (k=1;k<n;k++)

                  for (i=0;i<n;i++)

                      for (j=0;j<n;j++)

                          if (d[j]>d[i]+G[i][j]) {d[j]=d[i]+G[i][j];path[j]=i;}

              success=0;

              for (i=0;i<n;i++)

                  for (j=0;j<n;j++)

                      if (d[j]>d[i]+G[i][j]) return 0;

              success=1;

              return d[t];

          }

     

     

    4.Floyd-Warshall算法求每对节点间最短路径

          语法:Floyd_Washall(Graph G,int n,Graph D,Graph P);

          参数:

          G:图,用邻接矩阵表示

          n:图的顶点个数

          D:D[i,j]表示从i到j的最短距离

          P:P[i,j]表示从i到j的最短路径上j 的父节点 

          返回值:null

          源程序: 

           void Floyd_Washall(Graph G,int n,Graph D,Graph P)

          {

              int i,j,k;

              for (i=0;i<n;i++)

                  for (j=0;j<n;j++)

                      { D[i][j]=G[i][j];

                          P[i][j]=i; }

              for (i=0;i<n;i++) { D[i][i]=0;P[i][i]=0; }

              for (k=0;k<n;k++)

                  for (i=0;i<n;i++)

                      for (j=0;j<n;j++)

                          if (D[i][j]>D[i][k]+D[k][j])

                              { D[i][j]=D[i][k]+D[k][j];

                                  P[i][j]=P[k][j]; }

          }

     

     

    5.解欧拉图

          语法:int Eular(int graph[8][8], int v, int *path)

          参数:

          graph:图,用邻接矩阵表示

          v:图的顶点个数

          path:D[i,j]表示从i到j的最短距离

          注意: 

           此函数会删除图中的边

          返回值:若找到欧拉回路则返回路径长度,否则返回-1

          源程序: 

           int Eular(int graph[8][8], int v, int *path)

          {

               int start,a,b,count=0, deg,i;

               int s[1000], sp=0;//栈,大小可根据需要改变     

           

               start=0;

               while(true)

               {

                   a=start;

                   s[sp++]=a;

                   for(b=-1,i=0;i<v;i++) if (graph[i][a]&& a!=i) {b=i;break;}

                   for(;b!=start&&b!=-1;)

                   {

                        s[sp++]=b;

                        graph[a][b]=graph[b][a]=0;

                        a=b;

                        for(b=-1,i=0;i<v;i++) if (graph[i][a]&& a!=i) {b=i;break;}

                   }

                   if (b==-1) return(-1);//若找不到Eular回路返回-1

                   s[sp++]=b;

                   graph[a][b]=graph[b][a]=0;

               

                   while(sp>0)

                   {             

                        b=s[--sp];

                        for(i=0,deg=0;i<v;i++) if (graph[i][b]==1) {deg++; break;}

                        if (deg>0) break;

                        path[count++]=b;

                   }

                   if (sp==0) return(count);

                   start=b;      

               }

           

          }

     

     

    六、排序/查找

    1.快速排序

          语法:quicksort(int l,int r,int b[]);

          参数:

          l:排序上界,开始时l=0

          r:排序下界,开始时r=数组元素个数

          b[]:被排序的元素

          返回值:null

          注意: 

           输出升序序列

          源程序: 

           void quicksort(int l,int r,int b[])

          {

              int i,j,x;

              if(l>=r) return;

              i=l;

              j=r;

              x=b[i];

              while(i!=j)

                  {

                  while(b[j]>x&&j>i) j--;

                  if(i<j)

                      {

                      b[i]=b[j];

                      i++;

                      }

                  while(b[i]<x&&j>i)i++;

                      if(i<j)

                          {

                          b[j]=b[i];

                          j--;

                          }

                  }

              b[i]=x;

              quicksort(l,j-1,b);

              quicksort(i+1,r,b);

          }

     

     

    2.希尔排序

          语法:shellsort(int a[],int n);

          参数:

          n:数组元素个数

          a[]:待排序数组

          返回值:null

          注意: 

           输出升序序列

          源程序: 

           void shellsort(int a[],int n)

          {

              int i,j,g;

              int temp,k;

              g=n/2;

              while(g!=0)

                  {

                  for(i=g+1;i<=n;i++)

                      {

                      temp=a[i];

                      j=i-g;

                      while(j>0)

                          {

                          k=j+g;

                          if(a[j]<=a[k])

                              j=0;

                          else

                              {

                              temp=a[j];a[j]=a[k];a[k]=temp;

                              }

                          j=j-g;

                          }

                      }

                  g=g/2;

                  }

          }

     

     

    3.选择法排序

          语法:sort(int t[],int n);

          参数:

          t[]:待排序数组

          n:数组t[]元素的个数

          返回值:null

          注意: 

           输出升序序列

           小规模排序用

          源程序: 

           void sort(int t[],int n)

          {

             int i,j,k,temp;

              for (i=0;i<n;i++)

                  {

                  k=i;

                  for (j=i;j<n;j++) if (t[j]<t[k]) k=j;

                  temp=t[i];t[i]=t[k];t[k]=temp;

                  }

          }

     

     

    4.二分查找

          语法:result=search_bin(int *t,int k);

          参数:

          t[]:待查找数组

          k:查找关键字

          返回值:如果k在t[]中存在,输出i:t[i]=k,否则输出-1

          注意: 

           要求查找数组是有序升序序列

          源程序: 

           int search_bin(int *t,int k)

          {

              int low=1,high=10,mid;

              while (low<=high)

                  {

                  mid=(low+high)/2;

                  if (k==t[mid]) return mid;

                  else if (k<t[mid]) high=mid-1;

                  else low=mid+1;

                  }

              return -1;

          }

     

     

    七、数据结构

    1.顺序队列

          源程序: 

           #define maxsize 100

          typedef struct

          {

              int data[maxsize];

              int front;

              int rear;

          } sqqueue; 

          int sqinit(sqqueue *p) //队列初始化

          {

              p->front=0;

              p->rear=0;

              return 1;

          }

          int enqueue(sqqueue *q, int e) //入队

          {

              if((q->rear+1)%maxsize==q->front)

                  return 0;

              else

                  q->data[q->rear]=e;

              q->rear=(q->rear+1)%maxsize;

              return 1;

          }

          int dequeue(sqqueue *q) //出队

          {

              int e;

              if (q->front==q->rear)

                  return 0;

              e=q->data[q->front];

              q->front=(q->front+1)%maxsize;

              return e;

          }

          int empty(sqqueue *q)  //判空

          {

              int v;

              if (q->front==q->rear)

                  v=1;

              else

                  v=0;

               return v; 

          }

          int gethead(sqqueue *q)  //取得头元素

          {

              int e;

              if (q->front==q->rear) 

                  e=-1;

              else

                  e=q->data[q->front];

              return e;

          }

          void display(sqqueue *q) //显示所有元素

          {

              int s;

              s=q->front;

              printf("the sequeue is display: ");

              if (q->front==q->rear)

                  printf("the sequeue is empty!");

              else

                  {

                  while(s<q->rear)

                      {

                      printf("->%d", q->data[s]);

                      s=(s+1)%maxsize;

                      } 

              printf(" ");

          }

          }

          main(sqqueue *head)  //函数使用样例

          {

              int n,i,m,x,y,select,xq;

              printf("create a empty sequeue ");

              sqinit(head);

              printf("please input the sequeue length: "); 

              scanf("%d",&n);

              for (i=0;i<n;i++)

                  {

                  printf("please input a sequeue value: ");

                  scanf("%d",&m);

                  enqueue(head,m);

                 }

              printf("head->rear:%d ",head->rear);

              printf("head->front:%d ",head->front);

              display(head);

              printf("select 1 **** enqueue()  ");

              printf("select 2 **** dequeue()  ");

              printf("select 3 **** empty ()  ");

              printf("select 4 **** gethead()  ");

              printf("select 5 **** display()  ");

              printf("please select (1--5):");

              scanf("%d",&select);

              switch(select)

                  {

                  case 1:

                      { 

                      printf("please input a value :  ");

                      scanf("%d",&x);

                      enqueue(head,x);

                      display(head);

                      break;

                      }

                  case 2:

                      {

                      dequeue(head);

                      display(head);

                      break;

                      }

                  case 3:

                      {

                  if(empty(head))

                      printf("the sequeue is empty");

                  else

                      printf("the sequeue is full");

                      }

                  case 4:

                      {

                      y=gethead(head);

                      printf("output head value:%d ",y);

                      break;

                      }

                  case 5:

                      {

                      display(head);

                      break;

                      }

                  }

              }

          } 

     

     

    2.顺序栈

          源程序: 

           #define m 100

          typedef struct

          {

              int stack[m];

              int top;

          } stackstru; 

          init(stackstru *s) /*装入栈*/

          {

              s->top=0;

              return 1;

          }

          int push(stackstru *s,int x) /*入栈操作*/

          {

              if (s->top==m)

                  printf("the stack is overflow! ");

              else

                  {

                  s->top=s->top+1;

                  s->stack[s->top]=x;

                  }

          }

          void display(stackstru *s) /*显示栈所有数据*/

          {

              if(s->top==0)

                  printf("the stack is empty! ");

              else

                  {

                  while(s->top!=0)

                      {

                      printf("%d->",s->stack[s->top]);

                      s->top=s->top-1;

                      }

                  }

          }

          int pop(stackstru *s) /*出栈操作并返回被删除的那个记录*/

          {

              int y;

              if(s->top==0)

                  printf("the stack is empty! ");

              else

                  {

                  y=s->stack[s->top];

                  s->top=s->top-1;

                  return y;

                  }

          }

     

          int gettop(stackstru *s) /*得到栈顶数*/

          { 

              int e;

              if(s->top==0)

                  return 0;

              else 

                  e=s->stack[s->top];

              return e;

          }

          main(stackstru *p) //函数使用演示

          {

              int n,i,k,h,x1,x2,select;

              printf("create a empty stack! ");

              init(p);

              printf("input a stack length: ");

              scanf("%d",&n);

              for(i=0;i<n;i++)

                  {

                  printf("input a stack value: ");

                  scanf("%d",&k);

                  push(p,k);

                  }

              printf("select 1:display() ");

              printf("select 2:push() ");

              printf("select 3:pop() ");

              printf("select 4:gettop() ");

              printf("input a your select(1-4): ");

              scanf("%d",&select);

              switch(select)

                  {

                  case 1:

                      {

                      display(p);

                      break;

                      }

                  case 2:

                      {

                      printf("input a push a value: ");

                      scanf("%d",&h);

                      push(p,h);

                      display(p);

                      break;

                      }

                  case 3:

                      {

                      x1=pop(p);

                      printf("x1->%d ",x1);

                      display(p);

                      break;

                      }

                  case 4:

                      {

                      x2=gettop(p);

                      printf("x2->%d",x2);

                      break;

                      }

                  }

          }

     

     

    3.链表

          源程序: 

           # define null 0 

     

          typedef char ElemType; /* 字符型数据*/ 

     

          typedef struct LNode

          {

              ElemType data;

              struct LNode *next;

          };

     

          setnull(struct LNode **p);

          int length (struct LNode **p);

          ElemType get(struct LNode **p,int i);

          void insert(struct LNode **p,ElemType x,int i);

          int delete(struct LNode **p,int i);

          void display(struct LNode **p); 

          main()

          {

              struct LNode *head,*q; /*定义静态变量*/

              int select,x1,x2,x3,x4;

              int i,n; 

              int m,g;

              char e,y; 

     

              head=setnull(&head); /*建议链表并设置为空表*/

              printf("请输入数据长度: ");

              scanf("%d",&n);

              for(i=1;i<n;i++);

                  {

                  printf("将数据插入到单链表中: ");

                  scanf("%d",&y);

                  insert(&head,y,i);} /*插入数据到链表*/

                  display(&head); /*显示链表所有数据*/

     

                  printf("select 1 求长度 length() ");

                  printf("select 2 取结点 get() ");

                  printf("select 3 求值查找 locate() ");

                  printf("select 4 删除结点 delete() ");

                  printf("input your select: ");

                  scanf("%d",&select); 

                  switch(select)

                      {

                      case 1:

                          {

                          x1=length(&head);

                          printf("输出单链表的长度%d ",x1);

                          display(&head);

                          }break;

                      case 2:

                          {

                          printf("请输入要取得结点: ");

                          scanf("%d",&m);

                          x2=get(&head,m);

                          printf(x2);

                          display(&head);

                          }break;

                   case 3:

                          {

                          printf("请输入要查找的数据: ");

                          scanf("%d",&e);

                          x3=locate(&head,e);

                          printf(x3);

                          display(&head);

                          }break;

                   case 4:

                          {

                          printf("请输入要删除的结点: ");

                          scanf("%d",&g);

                          x4=delete(&head,g);

                          printf(x4);

                          display(&head);

                          }break;

                      }

                  }

          }

     

          setnull(struct LNode **p)

          {

              *p=null;

          }

          int length (struct LNode **p)

          {

              int n=0;

              struct LNode *q=*p;

              while (q!=null)

                  {

                  n++;

                  q=q->next;

                  }

              return(n);

          }

          ElemType get(struct LNode **p,int i)

          {

              int j=1;

              struct LNode *q=*p;

              while (j<i&&q!=null)

                  {

                  q=q->next;

                  j++;

                  }

                  if(q!=null)

                      return(q->data);

                  else

                      printf("位置参数不正确! ");

          }

          int locate(struct LNode **p,ElemType x)

              {

              int n=0;

              struct LNode *q=*p;

              while (q!=null&&q->data!=x)

                  {

                  q=q->next;

                  n++;

                  }

              if(q==null)

                  return(-1);

              else

                  return(n+1);

          }

          void insert(struct LNode **p,ElemType x,int i)

              {

              int j=1;

              struct LNode *s,*q;

              s=(struct LNode *)malloc(sizeof(struct LNode));

              s->data=x;

              q=*p;

              if(i==1)

                  {

                  s->next=q;

                  p=s;

                  }

              else

                  {

                  while(j<i-1&&q->next!=null)

                      {

                      q=q->next;

                      j++;

                      }

                  if(j==i-1)

                      {

                      s->next=q->next;

                      q->next=s;

                      }

                  else 

                      printf("位置参数不正确! ");

                  } 

          }

          int delete(struct LNode **p,int i)

          {

              int j=1;

              struct LNode *q=*p,*t;

              if(i==1)

                  {

                  t=q;

                  *p=q->next;

                  }

              else

                  {

                  while(j<i-1&&q->next!=null)

                      {

                      q=q->next;

                      j++;

                      }

                  if(q->next!=null&&j==i-1)

                      {

                      t=q->next;

                      q->next=t->next;

                      }

                  else 

                      printf("位置参数不正确! ");

                  }

              if(t=null) 

              free(t);

          }

          void display(struct LNode **p)

              { 

              struct LNode *q;

              q=*p;

              printf("单链表显示: ");

              if(q==null)

                  printf("链表为空!");

              else if (q->next==null)

                  printf("%c ",q->data);

              else

                  {

                  while(q->next!=null)

                      {

                      printf("%c->",q->data);

                      q=q->next;

                      }

                  printf("%c",q->data);

              }

              printf(" ");

          }

     

     

    4.链栈

          源程序: 

           # define null 0 

     

          typedef struct stacknode

          {

              int data;

              struct stacknode *next;

          } stacklink;

          typedef struct

          {

              stacklink *top;

              int stacksize;

              }stackk;

     

          initlink(stackk *s)

          {

             s->top=(stacklink *)malloc(sizeof(stacklink));

              s->top->data=0;

              s->top->next=null;

          } 

     

          int poplink(stackk *s)

          {

             stackk *p;int v;

              if(s->top->next==null) printf("the stackis empty ");

              else

                  {

                  v=s->top->next->data;

                   p=s->top->next;

                   s->top=s->top->next;

                  } 

              free(p);

              return v;

          }

          } 

          int pushlink(stackk *s,int x)

          {

             stackk *p;

              p=(stacklink *)malloc(sizeof(stacklink));

              p->data=x;

              p->next=s->top->next;

              s->top->next=p;

          }

          int gettop(stackk *s)

          {

             int e;

              if(s==null) printf("the stack is empty! ");

              e=s->top->next->data;

              return e;

          }

     

          display(stackk *s)

          {

             stackk *p;

              p=s->top->next;

              printf("display the stacklink: ");

              if (s->top=null) printf("the stacklink is empty! ");

              else

                 {

                 while(p)

                      {

                     printf("->%d",p->data);

                      p=p->next;

                     }

                  }

          }

     

          main(stacklink *p)

          {

             int n,k,i,select,h,x1,x2;

              printf("create a empty stacklink! ");

              initlink(p);

              printf("input a stacklink length: ");

              scanf("%d",&n);

              for (i=1;i<=n;i++)

                  {printf("input a stacklink value: ");

              scanf("%d",&k);

              pushlink(p,k);

                  }

              printf("select 1:display() ");

              printf("select 2:pushlink() ");

              printf("select 3:poplink() ");

              printf("select 4:gettop() ");

              printf("input a your select(1-4): ");

              scanf("%d",&select);

              switch(select)

                  {case 1:

                       {display(p);break;}

                  case 2:

                     {printf("input a push a value : ");

                      scanf("%d",&h);

                      pushlink(p,h);

                      display(p);

                      break;}

                  case 3:

                     {x1=poplink(p);printf("x1->%d ",x1);

                      display(p);

                      break;}

                  case 4:

                     {x2=gettop(p);printf("x2->%d",x2);

                      break;}

                  }

          }

     

     

    5.二叉树

          源程序: 

           typedef struct bitnode

          {

              char data;

              struct bitnode *lchild, *rchild;

          }bitnode, *bitree; 

          void createbitree(t,n)

          bitnode ** t;

          int *n;

          {

              char x;

              bitnode *q;

              *n=*n+1;

              printf("  Input %d DATA:",*n);

              x=getchar();

              if(x!=' ') getchar();

              if (x==' ')

                  return;

              q=(bitnode*)malloc(sizeof(bitnode));

              q->data=x;

              q->lchild=NULL;

              q->rchild=NULL;

              *t=q;

              printf(" This Address is: %o, Data is: %c,  Left Pointer is: %o, 

          Right Pointer is: %o",q,q->data,q->lchild,q->rchild);

              createbitree(&q->lchild,n);

              createbitree(&q->rchild,n);

              return;

          }

     

          void visit(e)

          bitnode *e;

          {

              printf(" Address: %o, Data: %c, Left Pointer: %o, Right Pointer: 

          %o ",e,e->data,e->lchild,e->rchild);

          }

     

          void preordertraverse(t)

          bitnode *t;

          {

              if(t)

                  {

                  visit(t);

                  preordertraverse(t->lchild);

                  preordertraverse(t->rchild);

                  return ;

                  }

             else

               return ;

          }

          void countleaf(t,c)

          bitnode *t;

          int *c;

          {

              if(t!=NULL)

                  {

                  if (t->lchild==NULL && t->rchild==NULL)

                  {*c=*c+1;

                  }

              countleaf(t->lchild,c);

              countleaf(t->rchild,c);

          }

          return;

          }

          int treehigh(t)

          bitnode *t;

          {

             int lh,rh,h;

              if(t==NULL)

                  h=0;

              else

                 {

                  lh=treehigh(t->lchild);

                  rh=treehigh(t->rchild);

                  h=(lh>rh ? lh:rh)+1;

                  }

              return h;

          }

     

          main()

          {

              bitnode *t; int count=0;

              int n=0;

             printf("  Please input TREE Data: ");

              createbitree(&t,&n);

             printf("  This is TREE struct:  ");

              preordertraverse(t);

             countleaf(t,&count);

              printf("  This TREE has %d leaves ",count);

             printf(" , High of The TREE is: %d ",treehigh(t));

          }

     

     

    八、高精度运算专题

    1.专题函数说明

          说明: 

           本栏为本专题所有程序的公用部分,调用本专题任何一个程序必须加上本栏的代码

           input/print为高精度数输入输出,调用格式为input(hp HightPoint,"123456")/print(hp 

          HighPoint)

           本栏为纯C++代码

          源程序: 

           #include <iostream> 

          using namespace std;

          #define maxsize 100

          struct hp

          {

             int len;

             int s[maxsize+1];

          };

     

          void input(hp &a,string str)

          {

             int i;

             while(str[0]=='0' && str.size()!=1)

                str.erase(0,1);

             a.len=(int)str.size();

             for(i=1;i<=a.len;++i)

                a.s[i]=str[a.len-i]-48;

             for (i=a.len+1;i<=maxsize;++i)

                a.s[i]=0;

          }

          void print(const hp &y)

          {

          int i;

          for(i=y.len;i>=1;i--)

             cout<<y.s[i];

          cout<<endl;

          }

     

     

    2.高精度数比较

          语法:int result=compare(const hp &a,const hp &b);

          参数:

          a,b:进行比较的高精度数字

          返回值:比较结果,a>b返回正数,a=b返回0,a<b返回负数

          源程序: 

           int compare(const hp &a,const hp &b)

          {

          int len;

          if(a.len>b.len)

             len=a.len;

          else

             len=b.len;

          while(len>0 && a.s[len]==b.s[len]) len--;

          if(len==0)

             return 0;

          else

             return a.s[len]-b.s[len];

          } 

     

     

    3.高精度数加法

          语法:plus(const hp &a,const hp &b,hp &c);

          参数:

          a,b:进行加法的高精度数字

          返回值:返回相加结果到c中

          源程序: 

           void plus(const hp &a,const hp &b,hp &c)

          {

          int i,len;

          for(i=1;i<=maxsize;i++) c.s[i]=0;

          if(a.len>b.len) len=a.len;

          else len=b.len;

          for(i=1;i<=len;i++)

             {

             c.s[i]+=a.s[i]+b.s[i];

             if(c.s[i]>=10)

                {

                c.s[i]-=10;

                c.s[i+1]++;

                }

             }

          if(c.s[len+1]>0) len++;

             c.len=len;

          }

     

     

    4.高精度数减法

          语法:subtract(const hp &a,const hp &b,hp &c);

          参数:

          a,b:进行减法的高精度数字,a是被减数,b是减数,不支持负数

          返回值:返回结果到c中

          源程序: 

           void subtract(const hp &a,const hp &b,hp &c)

          {

          int i,len;

          for(i=1;i<=maxsize;i++) c.s[i]=0;

          if(a.len>b.len) len=a.len;

          else len=b.len;

          for(i=1;i<=len;i++)

             {

             c.s[i]+=a.s[i]-b.s[i];

             if(c.s[i]<0)

                {

                c.s[i]+=10;

                c.s[i+1]--;

                }

             }

          while(len>1&&c.s[len]==0) len--;

             c.len=len;

          }

     

     

    5.高精度乘10 

          语法:multiply10(hp &a);

          参数:

          a:进行乘法的高精度数字

          返回值:返回结果到 a 中

          源程序: 

           void multiply10(hp &a)

          {

          int i;

          for(i=a.len;i>=1;i--)

             a.s[i+1]=a.s[i];

          a.s[1]=0;

          a.len++;

          while(a.len>1&&a.s[a.len]==0) a.len--;

          }

     

     

    6.高精度乘单精度

          语法:multiply(const hp &a,int b,hp &c);

          参数:

          a:进行乘法的高精度数字

          b:进行乘法的单精度数字

          返回值:返回结果到 c 中

          源程序: 

           void multiply(const hp &a,int b,hp &c)

          {

          int i,len;

          for(i=1;i<=maxsize;i++) c.s[i]=0;

          len=a.len;

          for(i=1;i<=len;i++)

             {

             c.s[i]+=a.s[i]*b;

             c.s[i+1]+=c.s[i]/10;

             c.s[i]%=10;

             }

          len++;

          while(c.s[len]>=10)

             {

             c.s[len+1]+=c.s[len]/10;

             c.s[len]%=10;

             len++;

             }

          while(len>1&&c.s[len]==0) len--;

          c.len=len;

          }

     

     

    7.高精度乘高精度

          语法:multiplyh(const hp &a,const hp &b,hp &c);

          参数:

          a,b:进行乘法的高精度数字

          返回值:返回结果到 c 中

          源程序: 

           void multiplyh(const hp &a,const hp &b,hp &c)

          {

          int i,j,len;

          for(i=1;i<=maxsize;i++) c.s[i]=0;

          for(i=1;i<=a.len;i++)

          for(j=1;j<=b.len;j++)

             {

             c.s[i+j-1]+=a.s[i]*b.s[j];

             c.s[i+j]+=c.s[i+j-1]/10;

             c.s[i+j-1]%=10;

             }

          len=a.len+b.len+1;

          while(len>1&&c.s[len]==0) len--;

          c.len=len;

          }

     

     

    8.高精度除单精度

          语法:divide(const hp &a,int b,hp &c,int &d);

          参数:

          a:进行除法的高精度数字

          返回值:返回商到 c 中,余数到 d 中

          源程序: 

           void divide(const hp &a,int b,hp &c,int &d)

          {

          int i,len;

          for(i=1;i<=maxsize;i++) c.s[i]=0;

          len=a.len;

          d=0;

          for(i=len;i>=1;i--)

             {

             d=d*10+a.s[i];

             c.s[i]=d/b;

             d%=b;

             }

          while(len>1&&c.s[len]==0) len--;

          c.len=len;

          }

     

     

    9.高精度除高精度

          语法:divideh(const hp &a,const hp &b,hp &c,hp &d);

          参数:

          a,b:进行除法的高精度数字

          返回值:返回商到 c 中,余数到 d 中

          注意: 

           需要compare、multiply10、subtract

          源程序: 

           void divideh(const hp &a,const hp &b,hp &c,hp &d)

          {

          hp e;

          int i,len;

          for(i=1;i<=maxsize;i++)

             {

             c.s[i]=0;

             d.s[i]=0;

             }

          len=a.len;

          d.len=1;

          for(i=len;i>=1;i--)

             {

             multiply10(d);

             d.s[1]=a.s[i];

             while(compare(d,b)>=0)

                {

                subtract(d,b,e);

                d=e;

                c.s[i]++;

                }

             }

          while(len>1&&c.s[len]==0) len--;

          c.len=len;

          } 

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

    C++

    #include<fstream.h>

    ifstream filein("file.in");

    ofstream fileout("file.out");

    int main(){

      int a,b;

      filein>>a>>b;

      fileout<<(a+b);

      return 0;

    }

     

    C:

    #include<stdio.h>

    int main(){

      freopen("file.in","r",stdin);

      freopen("file.out","w",stdout);

      int a,b;

      scanf("%d%d",&a,&b);

      printf("%d",a+b);

      fclose(stdin); fclose(stdout);

      return 0;

    }

     

    输入一开始就会说有N个Input Block,下面接着是N个Input Block。 

    如1526 

    Code: 

    cin >> n; 

    for( i=0 ; i<n ; i++ ) 

        .... 

     

    输入不说明有多少个Input Block,但以某个特殊输入为结束标志。 

    如1115 

    Code: 

    while( cin >> n && n != 0 ) 

        .... 

    输入不说明有多少个Input Block,以EOF为结束标志。 

    如1001 

    Code: 

    while( cin >> a >> b ) 

        .... 

     

    输入是一整行的字符串的 

    如1392 

    如果你用char buf[ 255 ]; 来保存的: 

    Code: 

    cin.getline( buf, 255 ); 

     

    如果你用string buf;来保存的: 

    Code: 

    getline( cin , buf ); 

     

    输出部分:

    一个Input Block对应一个Output Block,Output Block之间没有空行。 

    如1001 

    Code: 

        ... 

        cout << ans << endl; 

     

    一个Input Block对应一个Output Block,Output Block之间有空行。 

    如1152 

    Code: 

    int nCases = 0; 

    ... 

        if ( nCases++ ) cout << endl; 

        ... 

        cout << ans << endl; 

     

    一个Input Block对应一个Output Block,每个Output Block之后都有空行。 

    如1457 

    Code: 

        ... 

        cout << ans << endl << endl; }

     

    几何公式:

      1.长方体

      长方体的表面积=2×(a×b+b×c+c×a)

      长方体的体积=a×b×c(这里a、b、c分别表示长方体的长、宽、高)。

      2.正方体

      正方体的表面

    ACM小组内部预定函数

    数学问题:   

    1.精度计算——大数阶乘

    2.精度计算——乘法(大数乘小数)

    3.精度计算——乘法(大数乘大数)

    4.精度计算——加法

    5.精度计算——减法

    6.任意进制转换

    7.最大公约数、最小公倍数

    8.组合序列

    9.快速傅立叶变换(FFT) 

    10.Ronberg算法计算积分

    11.行列式计算

    12.求排列组合数

    13.求某一天星期几   

    字符串处理:

    1.字符串替换

    2.字符串查找

    3.字符串截取

    4.LCS—最大公共子串长度

    5.LCS-生成最大公共子串

    6.数字转化为字符  

    计算几何:   

     1.叉乘法求任意多边形面积

    2.求三角形面积

    3.两矢量间角度4.两点距离(2D、3D)

    5.射向法判断点是否在多边形内部

    6.判断点是否在线段上

    7.判断两线段是否相交

    8.判断线段与直线是否相交

    9.点到线段最短距离

    10.求两直线的交点

    11.判断一个封闭图形是凹集还是凸集

    12.Graham扫描法寻找凸包

    13.求两条线段的交点  

    数论:

    1.x的二进制长度

    2.返回x的二进制表示中从低到高的第i位

    3.模取幂运算

    4.求解模线性方程

    5.求解模线性方程组(中国余数定理)

    6.筛法素数产生器

    7.判断一个数是否素数 

    8.求子距阵最大和

     9.求一个数每一位之和

    10.质因数分解

    11.高斯消元法解线性方程组 

    图论:

     1.Prim算法求最小生成树

    2.Dijkstra算法求单源最短路径

    3.Bellman-ford算法求单源最短路径

    4.Floyd算法求每对节点间最短路径

    5.解欧拉图

    排序/查找:

    1.快速排序

    2.希尔排序

    3.选择法排序

    4.二分查找

    高精度运算专题:

    1.本专题公共函数说明

    2.高精度比较

    3.高精度加法

    4.高精度减法

    5.高精度乘10

    6.高精度乘单精度

    7.高精度乘高精度

    8.高精度除单精度

    9.高精度除高精度

    一、数学问题

    1.精度计算——大数阶乘

          语法:int result=factorial(int n);

          参数:

          n:n 的阶乘

          返回值:阶乘结果的位数

          注意: 

           本程序直接输出n!的结果,需要返回结果请保留long a[]

           需要 math.h

          源程序: 

           int factorial(int n)

          {

          long a[10000];

          int i,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(" %ld",a[m]); 

          for(i=m-1;i>=0;i--) printf("%4.4ld",a[i]);

          return w;

          } 

    2.精度计算——乘法(大数乘小数)

          语法:mult(char c[],char t[],int m);

          参数:

          c[]:被乘数,用字符串表示,位数不限

          t[]:结果,用字符串表示

          m:乘数,限定10以内

          返回值:null

          注意: 

           需要 string.h

          源程序: 

           void mult(char c[],char t[],int m)

          {

              int i,l,k,flag,add=0;

              char s[100];

              l=strlen(c);

              for (i=0;i<l;i++)

                  s[l-i-1]=c[i]-'0'; 

              for (i=0;i<l;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;

              for (i=0;i<l;i++)

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

              t[l]='';

          }

    3.精度计算——乘法(大数乘大数)

          语法:mult(char a[],char b[],char s[]);

          参数:

          a[]:被乘数,用字符串表示,位数不限

          b[]:乘数,用字符串表示,位数不限

          t[]:结果,用字符串表示

          返回值:null

          注意: 

           空间复杂度为 o(n^2)

           需要 string.h

          源程序: 

           void mult(char a[],char b[],char s[])

          {

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

              char result[65];

              alen=strlen(a);blen=strlen(b); 

              for (i=0;i<alen;i++)

              for (j=0;j<blen;j++) res[i][j]=(a[i]-'0')*(b[j]-'0');

              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<k;i++) result[i]+='0';

              for (i=k-1;i>=0;i--) s[i]=result[k-1-i];

              s[k]='';

              while(1)

                  {

                  if (strlen(s)!=strlen(a)&&s[0]=='0') 

                      strcpy(s,s+1);

                  else

                      break;

                  }

          }

     

     

    4.精度计算——加法

          语法:add(char a[],char b[],char s[]);

          参数:

          a[]:被乘数,用字符串表示,位数不限

          b[]:乘数,用字符串表示,位数不限

          t[]:结果,用字符串表示

          返回值:null

          注意: 

           空间复杂度为 o(n^2)

           需要 string.h

          源程序: 

           void add(char a[],char b[],char back[])

          {

              int i,j,k,up,x,y,z,l;

              char *c;

              if (strlen(a)>strlen(b)) l=strlen(a)+2; else l=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'; else x=a[i];

                      if(j<0) y='0'; else y=b[j];

                      z=x-'0'+y-'0';

                      if(up) z+=1;

                      if(z>9) {up=1;z%=10;} else up=0;

                      c[k++]=z+'0';

                      i--;j--;

                  }

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

              i=0;

              c[k]='';

              for(k-=1;k>=0;k--)

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

              back[i]='';

          } 

     

     

    5.精度计算——减法

          语法:sub(char s1[],char s2[],char t[]);

          参数:

          s1[]:被减数,用字符串表示,位数不限

          s2[]:减数,用字符串表示,位数不限

          t[]:结果,用字符串表示

          返回值:null

          注意: 

           默认s1>=s2,程序未处理负数情况

           需要 string.h

          源程序: 

           void sub(char s1[],char s2[],char t[])

          {

              int i,l2,l1,k;

              l2=strlen(s2);l1=strlen(s1);

              t[l1]='';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<l1-1;i++) t[i]=t[i+1];

                  t[l1-1]='';

                  goto loop;

                  }

              if (strlen(t)==0) {t[0]='0';t[1]='';}

          } 

     

     

    6.任意进制转换

          语法:conversion(char s1[],char s2[],char t[]);

          参数:

          s[]:转换前的数字

          s2[]:转换后的数字

          d1:原进制数

          d2:需要转换到的进制数

          返回值:null

          注意: 

           高于9的位数用大写'A'~'Z'表示,2~16位进制通过验证

          源程序: 

           void conversion(char s[],char s2[],long d1,long d2)

          {

              long i,j,t,num;

              char c;

              num=0;

              for (i=0;s[i]!='';i++)

                  {

                  if (s[i]<='9'&&s[i]>='0') t=s[i]-'0'; else t=s[i]-'A'+10;

                  num=num*d1+t;

                  }

              i=0;

              while(1)

                  {

                  t=num%d2;

                  if (t<=9) s2[i]=t+'0'; else s2[i]=t+'A'-10;

                  num/=d2;

                  if (num==0) break;

                  i++;

                  }

              for (j=0;j<i/2;j++)

                  {c=s2[j];s2[j]=s[i-j];s2[i-j]=c;}

              s2[i+1]='';

          }

     

     

    7.最大公约数、最小公倍数

          语法:resulet=hcf(int a,int b)、result=lcd(int a,int b)

          参数:

          a:int a,求最大公约数或最小公倍数

          b:int b,求最大公约数或最小公倍数

          返回值:返回最大公约数(hcf)或最小公倍数(lcd)

          注意: 

           lcd 需要连同 hcf 使用

          源程序: 

           int hcf(int a,int b)

          {

              int r=0;

              while(b!=0)

                  {

                  r=a%b;

                  a=b;

                  b=r;

                  }

              return(a);

          } 

          lcd(int u,int v,int h)

          {

              return(u*v/h);

          }

     

     

    8.组合序列

          语法:m_of_n(int m, int n1, int m1, int* a, int head)

          参数:

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

          源程序: 

           void m_of_n(int m, int n1, int m1, int* a, int head) 

          { 

              int i,t; 

              if(m1<0 || m1>n1) return; 

              if(m1==n1) 

                  { 

                  for(i=0;i<m;i++) cout<<a[i]<<' '; // 输出序列 

                  cout<<' '; 

                  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;

          } 

     

     

    9.快速傅立叶变换(FFT)

          语法:kkfft(double pr[],double pi[],int n,int k,double fr[],double fi[],int 

          l,int il);

          参数:

          pr[n]:输入的实部 

          pi[n]:数入的虚部

          n,k:满足n=2^k

          fr[n]:输出的实部

          fi[n]:输出的虚部

          l:逻辑开关,0 FFT,1 ifFT

          il:逻辑开关,0 输出按实部/虚部;1 输出按模/幅角 

          返回值:null

          注意: 

           需要 math.h

          源程序: 

           void kkfft(pr,pi,n,k,fr,fi,l,il) 

          int n,k,l,il; 

          double pr[],pi[],fr[],fi[]; 

          {

              int it,m,is,i,j,nv,l0; 

              double p,q,s,vr,vi,poddr,poddi; 

              for (it=0; it<=n-1; it++) 

                  {

                   m=it; is=0; 

                  for (i=0; i<=k-1; i++) 

                      {j=m/2; is=2*is+(m-2*j); m=j;}

                  fr[it]=pr[is]; fi[it]=pi[is]; 

                  } 

              pr[0]=1.0; pi[0]=0.0; 

              p=6.283185306/(1.0*n); 

              pr[1]=cos(p); pi[1]=-sin(p); 

              if (l!=0) pi[1]=-pi[1]; 

              for (i=2; i<=n-1; i++) 

                  {

                 p=pr[i-1]*pr[1];

                 q=pi[i-1]*pi[1]; 

                  s=(pr[i-1]+pi[i-1])*(pr[1]+pi[1]); 

                  pr[i]=p-q; pi[i]=s-p-q; 

                  } 

              for (it=0; it<=n-2; it=it+2) 

                  {

                 vr=fr[it]; vi=fi[it]; 

                  fr[it]=vr+fr[it+1]; fi[it]=vi+fi[it+1]; 

                  fr[it+1]=vr-fr[it+1]; fi[it+1]=vi-fi[it+1]; 

                  } 

              m=n/2; nv=2; 

              for (l0=k-2; l0>=0; l0--) 

                  {

                  m=m/2; nv=2*nv; 

                  for (it=0; it<=(m-1)*nv; it=it+nv) 

                      for (j=0; j<=(nv/2)-1; j++) 

                          {

                         p=pr[m*j]*fr[it+j+nv/2]; 

                          q=pi[m*j]*fi[it+j+nv/2]; 

                          s=pr[m*j]+pi[m*j]; 

                          s=s*(fr[it+j+nv/2]+fi[it+j+nv/2]); 

                          poddr=p-q; poddi=s-p-q; 

                          fr[it+j+nv/2]=fr[it+j]-poddr; 

                          fi[it+j+nv/2]=fi[it+j]-poddi; 

                          fr[it+j]=fr[it+j]+poddr; 

                          fi[it+j]=fi[it+j]+poddi; 

                          } 

                  } 

              if (l!=0) 

                  for (i=0; i<=n-1; i++) 

                      {

                     fr[i]=fr[i]/(1.0*n); 

                      fi[i]=fi[i]/(1.0*n); 

                      } 

              if (il!=0) 

                      for (i=0; i<=n-1; i++) 

                      {

                     pr[i]=sqrt(fr[i]*fr[i]+fi[i]*fi[i]); 

                      if (fabs(fr[i])<0.000001*fabs(fi[i])) 

                          {

                         if ((fi[i]*fr[i])>0) pi[i]=90.0; 

                          else pi[i]=-90.0; 

                          } 

                      else 

                          pi[i]=atan(fi[i]/fr[i])*360.0/6.283185306; 

                      } 

              return; 

          } 

     

     

    10.Ronberg算法计算积分

          语法:result=integral(double a,double b);

          参数:

          a:积分上限

          b:积分下限

          function f:积分函数

          返回值:f在(a,b)之间的积分值

          注意: 

           function f(x)需要自行修改,程序中用的是sina(x)/x

           需要 math.h

           默认精度要求是1e-5

          源程序: 

           double f(double x)

          { 

              return sin(x)/x; //在这里插入被积函数 

          }

     

          double integral(double a,double b) 

          { 

              double h=b-a; 

              double t1=(1+f(b))*h/2.0;

              int k=1; 

              double r1,r2,s1,s2,c1,c2,t2; 

          loop: 

              double s=0.0; 

              double x=a+h/2.0; 

              while(x<b) 

                  { 

                  s+=f(x); 

                  x+=h; 

                  } 

              t2=(t1+h*s)/2.0;

              s2=t2+(t2-t1)/3.0;

              if(k==1)

                { 

                  k++;h/=2.0;t1=t2;s1=s2;

                  goto loop; 

                  } 

              c2=s2+(s2-s1)/15.0; 

              if(k==2){ 

                  c1=c2;k++;h/=2.0; 

                  t1=t2;s1=s2; 

                  goto loop; 

                  } 

              r2=c2+(c2-c1)/63.0; 

              if(k==3){ 

                  r1=r2; c1=c2;k++; 

                  h/=2.0; 

                  t1=t2;s1=s2;

                  goto loop; 

                  } 

              while(fabs(1-r1/r2)>1e-5){ 

                  r1=r2;c1=c2;k++;

                  h/=2.0; 

                  t1=t2;s1=s2; 

                  goto loop; 

                  } 

              return r2;

          } 

     

     

    11.行列式计算

          语法:result=js(int s[][],int n)

          参数:

          s[][]:行列式存储数组

          n:行列式维数,递归用

          返回值:行列式值

          注意: 

           函数中常数N为行列式维度,需自行定义

          源程序: 

           int js(s,n) 

          int s[][N],n; 

          {

              int z,j,k,r,total=0; 

              int b[N][N];/*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<n-1;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); /*递归调用*/ 

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

                      total=total+r; 

                      } 

                  } 

              else if(n==2)

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

              return total; 

          } 

     

     

    12.求排列组合数

          语法:result=P(long n,long m); / result=long C(long n,long m);

          参数:

          m:排列组合的上系数

          n:排列组合的下系数

          返回值:排列组合数

          注意: 

           符合数学规则:m<=n

          源程序: 

           long P(long n,long m)

          {

              long p=1;

              while(m!=0)

                  {p*=n;n--;m--;}

              return p;

          } 

          long C(long n,long m)

          {

              long i,c=1;

              i=m;

              while(i!=0)

                  {c*=n;n--;i--;}

              while(m!=0)

                  {c/=m;m--;}

              return c;

          } 

     

     

    13.求某一天星期几

          语法:result=weekday(int N,int M,int d)

          参数:

          N,M,d:年月日,例如:2003,11,4

          返回值:0:星期天,1星期一……

          注意: 

           需要math.h

           适用于1582年10月15日之后, 因为罗马教皇格里高利十三世在这一天启用新历法.

          源程序: 

           int weekday(int N,int M,int d)

          {

          int m,n,c,y,w;

          m=(M-2)%12;

          if (M>=3) n=N;else n=N-1;

          c=n/100;

          y=n%100;

          w=(int)(d+floor(13*m/5)+y+floor(y/4)+floor(c/4)-2*c)%7;

          while(w<0) w+=7;

          return w;

          }

     

     

    二、字符串处理

    1.字符串替换

          语法:replace(char str[],char key[],char swap[]);

          参数:

          str[]:在此源字符串进行替换操作

          key[]:被替换的字符串,不能为空串

          swap[]:替换的字符串,可以为空串,为空串表示在源字符中删除key[]

          返回值:null

          注意: 

           默认str[]长度小于1000,如否,重新设定设定tmp大小

           需要 string.h

          源程序: 

           void replace(char str[],char key[],char swap[])

          {

              int l1,l2,l3,i,j,flag;

              char tmp[1000];

              l1=strlen(str);

              l2=strlen(key);

              l3=strlen(swap);

              for (i=0;i<=l1-l2;i++)

                  {

                  flag=1;

                  for (j=0;j<l2;j++)

                      if (str[i+j]!=key[j]) {flag=0;break;}

                  if (flag)

                      {

                      strcpy(tmp,str);

                      strcpy(&tmp[i],swap);

                      strcpy(&tmp[i+l3],&str[i+l2]);

                      strcpy(str,tmp);

                      i+=l3-1;

                      l1=strlen(str);

                      }

                  }

          }

     

     

    2.字符串查找

          语法:result=strfind(char str[],char key[]);

          参数:

          str[]:在此源字符串进行查找操作

          key[]:被查找的字符串,不能为空串

          返回值:如果查找成功,返回key在str中第一次出现的位置,否则返回-1

          注意: 

           需要 string.h

          源程序: 

           int strfind(char str[],char key[])

          {

              int l1,l2,i,j,flag;

              l1=strlen(str);

              l2=strlen(key);

              for (i=0;i<=l1-l2;i++)

                  {

                  flag=1;

                  for (j=0;j<l2;j++)

                      if (str[i+j]!=key[j]) {flag=0;break;}

                  if (flag) return i;

                  }

              return -1;

          } 

     

     

    3.字符串截取

          语法:mid(char str[],int start,int len,char strback[])

          参数:

          str[]:操作的目标字符串

          start:从第start个字符串开始,截取长度为len的字符

          len:从第start个字符串开始,截取长度为len的字符

          strback[]:截取的到的字符

          返回值:0:超出字符串长度,截取失败;1:截取成功

          注意: 

           需要 string.h

          源程序: 

           int mid(char str[],int start,int len,char strback[])

          {

              int l,i,k=0;

              l=strlen(str);

              if (start+len>l) return 0;

              for (i=start;i<start+len;i++)

                  strback[k++]=str[i];

              strback[k]='';

              return 1;

          } 

     

     

    4.LCS-最大公共子串长度

          语法:result=lcs_len(char *a, char *b);

          参数:

          a,b[]:根据a,b生成最大公共子串

          返回值:最大公共子串的长度

          注意: 

           需要 string.h

           M、N是a,b数组的最大可能长度

           如果不需要生成公共子串,c[M][N]不可设置为全局变量

          源程序: 

           #define M 20

          #define N 20

          int c[M][N]; 

          int lcs_len(char *a, char *b)

          {

          int m=strlen(a),n=strlen(b),i,j;

          for(i=0;i<=m;i++) c[i][0]=0;

          for(j=0;j<=n;j++) c[0][j]=0;

          for(i=1;i<=m;i++)

              for(j=1;j<=n;j++)

              {

              if(a[i-1]==b[j-1])

                  c[i][j]=c[i-1][j-1]+1;

              else if(c[i-1][j]>c[i][j-1])

                  c[i][j]=c[i-1][j];

              else

                  c[i][j]=c[i][j-1];

              }

          return c[m][n];

          }

     

     

    5.LCS-最大公共子串长度

          语法:result=build_lcs(char s[], char *a, int blen, int clen);

          参数:

          *a:生成公共子串的字符串a,b中的a

          s[]:接受返回结果的字符串数组

          blen:生成公共子串的字符串a,b中的b的长度

          clen:最大公共子串的长度,通过lcs_len函数求得

          返回值:最大公共子串的长度

          注意: 

           需要 string.h

           需要lcs_len函数求clen并且生成c[M][N]

           可通过result=build_lcs返回指针或者通过build_lcs(s,a,blen,clen),用s接受结果

          源程序: 

           char *build_lcs(char s[], char *a, int blen, int clen)

          {

          int k=clen,alen=strlen(a),i,j;

          s[k]='';

          i=alen,j=blen;

          while(k>0)

              {

              if(c[i][j]==c[i-1][j])

              i--;

              else if(c[i][j]==c[i][j-1])

              j--;

              else

                  {

                  s[--k]=a[i-1];

                  i--;j--;

                  }

              }

          return s;

          } 

     

     

    6.数字转换为字符

          语法:cstr(int k,char o[]);

          参数:

          k:转换的数字

          o[]:存储转换结果的字符串

          返回值:null

          注意: 

           需要 math.h

          源程序: 

           void cstr(int k,char o[])

          {

              int len,i,t;

              len=log10(k)+1;

              for (i=len;i>0;i--)

                  {

                  t=k%10;

                  k-=t;k/=10;

                  o[i-1]='0'+t;

                  }

              o[len]='';

          }

     

     

    三、计算几何

    1.叉乘法求任意多边形面积

          语法:result=polygonarea(Point *polygon,int N);

          参数:

          *polygon:多变形顶点数组

          N:多边形顶点数目

          返回值:多边形面积

          注意: 

           支持任意多边形,凹、凸皆可

           多边形顶点输入时按顺时针顺序排列

          源程序: 

           typedef struct {

              double x,y;

          } Point; 

          double polygonarea(Point *polygon,int N)

          {

              int i,j;

              double area = 0;

              for (i=0;i<N;i++) {

                  j = (i + 1) % N;

                  area += polygon[i].x * polygon[j].y;

                  area -= polygon[i].y * polygon[j].x;

                  }

              area /= 2;

              return(area < 0 ? -area : area);

          }

     

     

    2.求三角形面积

          语法:result=area3(float x1,float y1,float x2,float y2,float x3,float y3);

          参数:

          x1~3:三角形3个顶点x坐标

          y1~3:三角形3个顶点y坐标

          返回值:三角形面积

          注意: 

           需要 math.h

          源程序: 

           float area3(float x1,float y1,float x2,float y2,float x3,float y3)

          {

              float a,b,c,p,s;

              a=sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));

              b=sqrt((x1-x3)*(x1-x3)+(y1-y3)*(y1-y3));

              c=sqrt((x3-x2)*(x3-x2)+(y3-y2)*(y3-y2));

              p=(a+b+c)/2;

              s=sqrt(p*(p-a)*(p-b)*(p-c));

              return s;

          }

     

     

    3.两矢量间角度

          语法:result=angle(double x1, double y1, double x2, double y2);

          参数:

          x/y1~2:两矢量的坐标

          返回值:两的角度矢量

          注意: 

           返回角度为弧度制,并且以逆时针方向为正方向

           需要 math.h

          源程序: 

           #define PI 3.1415926

     

          double angle(double x1, double y1, double x2, double y2)

          {

              double dtheta,theta1,theta2; 

              theta1 = atan2(y1,x1);

              theta2 = atan2(y2,x2);

              dtheta = theta2 - theta1;

              while (dtheta > PI)

                  dtheta -= PI*2;

              while (dtheta < -PI)

                  dtheta += PI*2; 

              return(dtheta);

          }

     

     

    4.两点距离(2D、3D)

          语法:result=distance_2d(float x1,float x2,float y1,float y2);

          参数:

          x/y/z1~2:各点的x、y、z坐标

          返回值:两点之间的距离

          注意: 

           需要 math.h

          源程序: 

           float distance_2d(float x1,float x2,float y1,float y2) 

          {

              return(sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)));

          }

     

     

          float distance_3d(float x1,float x2,float y1,float y2,float z1,float z2)

          {

              return(sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)+(z1-z2)*(z1-z2)));

          }

     

     

    5.射向法判断点是否在多边形内部

          语法:result=insidepolygon(Point *polygon,int N,Point p);

          参数:

          *polygon:多边形顶点数组

          N:多边形顶点个数

          p:被判断点

          返回值:0:点在多边形内部;1:点在多边形外部

          注意: 

           若p点在多边形顶点或者边上,返回值不确定,需另行判断

           需要 math.h

          源程序: 

           #define MIN(x,y) (x < y ? x : y)

          #define MAX(x,y) (x > y ? x : y)

          typedef struct {

              double x,y;

          } Point;

          int insidepolygon(Point *polygon,int N,Point p)

          {

              int counter = 0;

              int i;

              double xinters;

              Point p1,p2;

              p1 = polygon[0];

              for (i=1;i<=N;i++) {

                  p2 = polygon[i % N];

                  if (p.y > MIN(p1.y,p2.y)) {

                      if (p.y <= MAX(p1.y,p2.y)) {

                          if (p.x <= MAX(p1.x,p2.x)) {

                              if (p1.y != p2.y) {

                                  xinters = (p.y-p1.y)*(p2.x-p1.x)/(p2.y-p1.y)+p1.x;

                                  if (p1.x == p2.x || p.x <= xinters)

                                      counter++;

                                  }

                              }

                          }

                      }

                      p1 = p2;

                  }

              if (counter % 2 == 0)

                  return(OUTSIDE);

              else

                  return(INSIDE);

          }

     

     

    6.判断点是否在线段上

          语法:result=Pointonline(Point p1,Point p2,Point p);

          参数:

          p1、p2:线段的两个端点

          p:被判断点

          返回值:0:点在不在线段上;1:点在线段上

          注意: 

           若p线段端点上返回1

           需要 math.h

          源程序: 

           #define MIN(x,y) (x < y ? x : y)

          #define MAX(x,y) (x > y ? x : y) 

          typedef struct {

          double x,y;

          } Point;

          int FC(double x1,double x2)

          {

              if (x1-x2<0.000002&&x1-x2>-0.000002) return 1; else return 0;

          }

     

     

          int Pointonline(Point p1,Point p2,Point p)

          {

              double x1,y1,x2,y2;

              x1=p.x-p1.x;

              x2=p2.x-p1.x;

              y1=p.y-p1.y;

              y2=p2.y-p1.y;

              if (FC(x1*y2-x2*y1,0)==0) return 0;

              if ((MIN(p1.x,p2.x)<=p.x&&p.x<=MAX(p1.x,p2.x))&&

                      (MIN(p1.y,p2.y)<=p.y&&p.y<=MAX(p1.y,p2.y)))

                  return 1; else return 0;

          }

     

     

    7.判断两线段是否相交

          语法:result=lineintersect(Point p1,Point p2,Point p3,Point p4);

          参数:

          p1~4:两条线段的四个端点

          返回值:0:两线段不相交;1:两线段相交;2两线段首尾相接

          注意: 

           p1!=p2;p3!=p4;

          源程序: 

           #define MIN(x,y) (x < y ? x : y)

          #define MAX(x,y) (x > y ? x : y) 

          typedef struct {

              double x,y;

          } Point;

          int lineintersect(Point p1,Point p2,Point p3,Point p4)

          {

              Point tp1,tp2,tp3;

              if 

          ((p1.x==p3.x&&p1.y==p3.y)||(p1.x==p4.x&&p1.y==p4.y)||(p2.x==p3.x&&p2.y==p3.y)||(p2.x==p4.x&&p2.y==p4.y))

                  return 2;

          //快速排斥试验

              if 

          ((MIN(p1.x,p2.x)<=p3.x&&p3.x<=MAX(p1.x,p2.x)&&MIN(p1.y,p2.y)<=p3.y&&p3.y<=MAX(p1.y,p2.y))||

                      

          (MIN(p1.x,p2.x)<=p4.x&&p4.x<=MAX(p1.x,p2.x)&&MIN(p1.y,p2.y)<=p4.y&&p4.y<=MAX(p1.y,p2.y)))

                  ;else return 0;

          //跨立试验

              tp1.x=p1.x-p3.x;

              tp1.y=p1.y-p3.y;

              tp2.x=p4.x-p3.x;

              tp2.y=p4.y-p3.y;

              tp3.x=p2.x-p3.x;

              tp3.y=p2.y-p3.y;

              if ((tp1.x*tp2.y-tp1.y*tp2.x)*(tp2.x*tp3.y-tp2.y*tp3.x)>=0) return 1; 

          else return 0;

          }

     

     

    8.判断线段与直线是否相交

          语法:result=lineintersect(Point p1,Point p2,Point p3,Point p4);

          参数:

          p1、p2:线段的两个端点

          p3、p4:直线上的两个点

          返回值:0:线段直线不相交;1:线段和直线相交

          注意: 

           如线段在直线上,返回 1

          源程序: 

           typedef struct {

              double x,y;

          } Point;

          int lineintersect(Point p1,Point p2,Point p3,Point p4)

          {

              Point tp1,tp2,tp3;

              tp1.x=p1.x-p3.x;

              tp1.y=p1.y-p3.y;

              tp2.x=p4.x-p3.x;

              tp2.y=p4.y-p3.y;

              tp3.x=p2.x-p3.x;

              tp3.y=p2.y-p3.y;

              if ((tp1.x*tp2.y-tp1.y*tp2.x)*(tp2.x*tp3.y-tp2.y*tp3.x)>=0) return 1; 

          else return 0;

          }

     

     

    9.点到线段最短距离

          语法:result=mindistance(Point p1,Point p2,Point q);

          参数:

          p1、p2:线段的两个端点

          q:判断点

          返回值:点q到线段p1p2的距离

          注意: 

           需要 math.h

          源程序: 

           #define MIN(x,y) (x < y ? x : y)

          #define MAX(x,y) (x > y ? x : y)

          typedef struct {

              double x,y;

          } Point;

          double mindistance(Point p1,Point p2,Point q)

          {

              int flag=1;

              double k;

              Point s;

              if (p1.x==p2.x) {s.x=p1.x;s.y=q.y;flag=0;}

              if (p1.y==p2.y) {s.x=q.x;s.y=p1.y;flag=0;}

              if (flag)

                  {

                  k=(p2.y-p1.y)/(p2.x-p1.x);

                  s.x=(k*k*p1.x+k*(q.y-p1.y)+q.x)/(k*k+1);

                  s.y=k*(s.x-p1.x)+p1.y;

                  }

              if (MIN(p1.x,p2.x)<=s.x&&s.x<=MAX(p1.x,p2.x))

                  return sqrt((q.x-s.x)*(q.x-s.x)+(q.y-s.y)*(q.y-s.y));

              else

                  return 

          MIN(sqrt((q.x-p1.x)*(q.x-p1.x)+(q.y-p1.y)*(q.y-p1.y)),sqrt((q.x-p2.x)*(q.x-p2.x)+(q.y-p2.y)*(q.y-p2.y)));

          }

     

     

    10.求两直线的交点

          语法:result=mindistance(Point p1,Point p2,Point q);

          参数:

          p1~p4:直线上不相同的两点

          *p:通过指针返回结果

          返回值:1:两直线相交;2:两直线平行

          注意: 

           如需要判断两线段交点,检验k和对应k1(注释中)的值是否在0~1之间,用在0~1之间的那个求交点

          源程序: 

           typedef struct {

             double x,y;

          } Point;

          int linecorss(Point p1,Point p2,Point p3,Point p4,Point *p)

          {

             double k;

             if ((p4.y-p3.y)*(p2.x-p1.x)-(p4.x-p3.x)*(p2.y-p1.y)==0) return 0;

            if ((p4.x-p3.x)*(p1.y-p3.y)-(p4.y-p3.y)*(p1.x-p3.x)==0&&

                     (p2.x-p1.x)*(p1.y-p3.y)-(p2.y-p1.y)*(p1.x-p3.x)==0) return 0;

              

          k=((p4.x-p3.x)*(p1.y-p3.y)-(p4.y-p3.y)*(p1.x-p3.x))/((p4.y-p3.y)*(p2.x-p1.x)-(p4.x-p3.x)*(p2.y-p1.y));

          //k1=((p2.x-p1.x)*(p1.y-p3.y)-(p2.y-p1.y)*(p1.x-p3.x))/((p4.y-p3.y)*(p2.x-p1.x)-(p4.x-p3.x)*(p2.y-p1.y));

             (*p).x=p1.x+k*(p2.x-p1.x);

             (*p).y=p1.y+k*(p2.y-p1.y);

             return 1;

          }

     

     

    11.判断一个封闭图形是凹集还是凸集

          语法:result=convex(Point *p,int n);

          参数:

          *p:封闭曲线顶点数组

          n:封闭曲线顶点个数

          返回值:1:凸集;-1:凹集;0:曲线不符合要求无法计算

          注意: 

           默认曲线为简单曲线:无交叉、无圈

          源程序: 

           typedef struct {

              double x,y;

          } Point;

          int convex(Point *p,int n)

          {

              int i,j,k;

              int flag = 0;

              double z;

              if (n < 3)

                  return(0);

              for (i=0;i<n;i++) {

                  j = (i + 1) % n;

                  k = (i + 2) % n;

                  z = (p[j].x - p[i].x) * (p[k].y - p[j].y);

                  z -= (p[j].y - p[i].y) * (p[k].x - p[j].x);

                  if (z < 0)

                      flag |= 1;

                  else if (z > 0)

                      flag |= 2;

                  if (flag == 3)

                      return -1; //CONCAVE

                  }

              if (flag != 0)

                  return 1; //CONVEX

              else

              return 0;

          }

     

     

    12.Graham扫描法寻找凸包

          语法:Graham_scan(Point PointSet[],Point ch[],int n,int &len);

          参数:

          PointSet[]:输入的点集

          ch[]:输出的凸包上的点集,按照逆时针方向排列

          n:PointSet中的点的数目

          len:输出的凸包上的点的个数

          返回值:null

          源程序: 

           struct Point{

              float x,y;

          }; 

          float multiply(Point p1,Point p2,Point p0)

          {

              return((p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y)); 

          }

          float distance(Point p1,Point p2)

          {

              return(sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y))); 

          }

          void Graham_scan(Point PointSet[],Point ch[],int n,int &len)

          {

              int i,j,k=0,top=2;

              Point tmp;

     

             for(i=1;i<n;i++)

              if 

          ((PointSet[i].y<PointSet[k].y)||((PointSet[i].y==PointSet[k].y)&&(PointSet[i].x<PointSet[k].x)))

              k=i;

              tmp=PointSet[0];

              PointSet[0]=PointSet[k];

              PointSet[k]=tmp; 

              for (i=1;i<n-1;i++)

                  {

                  k=i;

                  for (j=i+1;j<n;j++)

                      if ( (multiply(PointSet[j],PointSet[k],PointSet[0])>0) ||

                               ((multiply(PointSet[j],PointSet[k],PointSet[0])==0)

                                   

          &&(distance(PointSet[0],PointSet[j])<distance(PointSet[0],PointSet[k])))   

          )

                          k=j;

                  tmp=PointSet[i];

                  PointSet[i]=PointSet[k];

                  PointSet[k]=tmp;

                  }

              ch[0]=PointSet[0];

              ch[1]=PointSet[1];

              ch[2]=PointSet[2]; 

              for (i=3;i<n;i++)

                  {

                  while (multiply(PointSet[i],ch[top],ch[top-1])>=0) top--;

                  ch[++top]=PointSet[i];

                  }

              len=top+1;

          }

     

     

    13.求两条线段的交点

          语法:Result=IntersectPoint (Point p1,Point p2,Point p3,Point p4,Point &p);

          参数:

          P1~P4:两条线断4个端点

          P:线段交点

          返回值:如果两条线段平行无交点,返回 0,否则返回 1

          源程序: 

           struct Point{

              float x,y;

          }; 

     

          int IntersectPoint (Point p1,Point p2,Point p3,Point p4,Point &p)

          {

          float a,b,c,d,e,f;

          a=p2.y-p1.y;

          b=p1.x-p2.x;

          c=p1.y*(p2.x-p1.x)+p1.x*(p2.y-p1.y);

          d=p4.y-p3.y;

          e=p3.x-p4.x;

          f=p3.y*(p4.x-p3.x)+p1.x*(p4.y-p3.y); 

          if (a*e==b*d)

              return 0;

          else

              {

              p.x=(e*c-b*f)/(b*d-a*e);

              p.y=(d*c-a*f)/(a*e-b*d);

              return 1;

              }

          }

     

     

    四、数论

    1.x的二进制长度

          语法:result=BitLength(int x);

          参数:

          x:测长的x

          返回值:x的二进制长度

          源程序: 

           int BitLength(int x)

          {

              int d = 0;

              while (x > 0) {

                  x >>= 1;

                  d++;

              }

              return d;

          }

     

     

    2.返回x的二进制表示中从低到高的第i位

          语法:result=BitAt(int x, int i);

          参数:

          x:十进制 x

          i:要求二进制的第i位

          返回值:返回x的二进制表示中从低到高的第i位

          注意: 

           最低位为第一位

          源程序: 

           int BitAt(int x, int i)

          {

              return ( x & (1 << (i-1)) );

          }

     

     

    3.模取幂运算

          语法:result=Modular_Expoent(int a,int b,int n);

          参数:

          a、b、n:a^b mod n 的对应参数

          返回值:a^b mod n 的值

          注意: 

           需要BitLength和BitAt

          源程序: 

           int Modular_Expoent(int a,int b,int n)

          {

              int i, y=1;

              for (i = BitLength(b); i > 0; i--)

                  { 

                  y = (y*y)%n;

                  if (BitAt(b,i) > 0) 

                  y = (y*a)%n;

                  }

              return y;

          }

     

     

    4.求解模线性方程

          语法:result=modular_equation(int a,int b,int n);

          参数:

          a、b、n:ax=b (mod n) 的对应参数

          返回值:方程的解

          源程序: 

           int ext_euclid(int a,int b,int &x,int &y)  //求gcd(a,b)=ax+by

          {

              int t,d;

              if (b==0) {x=1;y=0;return a;}

              d=ext_euclid(b,a %b,x,y);

              t=x;

              x=y;

              y=t-a/b*y;

              return d;

          }

     

          void modular_equation(int a,int b,int n)

          {

              int e,i,d;

              int x,y;

              d=ext_euclid(a,n,x,y);

              if (b%d>0)

                 printf("No answer! ");

              else

                  {

                 e=(x*(b/d))%n;

                  for (i=0;i<d;i++)

                      printf("The %dth answer is : %ld ",i+1,(e+i*(n/d))%n); 

                  }

          }

     

     

    5.求解模线性方程组(中国余数定理)

          语法:result=Modular_Expoent(int a,int b,int n);

          参数:

          B[]、W[]:a=B[] (mod W[]) 的对应参数

          返回值:a 的值

          注意: 

           其中W[],B[]已知,W[i]>0且W[i]与W[j]互质, 求a

          源程序: 

           int ext_euclid(int a,int b,int &x,int &y)  //求gcd(a,b)=ax+by

          {

              int t,d;

              if (b==0) {x=1;y=0;return a;}

              d=ext_euclid(b,a %b,x,y);

              t=x;

              x=y;

              y=t-a/b*y;

              return d;

          }

     

     

          int China(int B[],int W[],int k)

          {

             int i;

              int d,x,y,a=0,m,n=1;

              for (i=0;i<k;i++)

                  n*=W[i];

              for (i=0;i<k;i++)

                 {

                 m=n/W[i];

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

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

                  }

              if (a>0) return a;

              else return(a+n);

          }

     

     

    6.筛法素数产生器

          语法:result=prime(int a[],int n);

          参数:

          a[]:用于返回素数的数组

          n:产生n以内的素数,按升序放入a[]中

          返回值:n以内素数的个数

          注意: 

           其中W[],B[]已知,W[i]>0且W[i]与W[j]互质, 求a

          源程序: 

           int prime(int a[],int n)

          {

              int i,j,k,x,num,*b;

              n++;

              n/=2;

              b=new int[(n+1)*2];

              a[0]=2;a[1]=3;num=2;

              for(i=1;i<=2*n;i++)

                  b[i]=0;

              for(i=3;i<=n;i+=3)

                  for(j=0;j<2;j++)

                      {

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

                      while(b[x]==0)

                          {

                          a[num++]=x;

                          for(k=x;k<=2*n;k+=x)

                              b[k]=1;

                          }

                      }

              return num;

          }

     

     

    7.判断一个数是否素数

          语法:result=comp(int n);

          参数:

          n:判断n是否素数

          返回值:素数返回1,否则返回0

          源程序: 

           //传统方法

          int comp(int n){ 

             if(n<2)return 0; 

             if(n%2==0)return 0; 

             for(int i=3;i<=sqrt(n);i+=2) if(n%i==0) return 0; 

             return 1; 

          }

           

          //大数素数判定,(1/4)^K出错概率

          int powermod(int a,int b,int n)

          {//get (a^b)%n 

             i64 d=1, t=a; 

             while(b>0){ 

                if(t==1)return d; 

                if(b%2==1)d=(t*d)%n; 

                b/=2; t=(t*t)%n; 

             } 

             return d; 

          } 

          int isprime(int n,int k){ 

                   int a; 

             while(k--){ 

                            a=rand(); 

                            a%=n-3; a+=2; 

                if(powermod(k+2,n-1,n)!=1)return 0; 

             } 

             return 1; 

          }

     

     

    8.求距阵最大和

          语法:result=maxsum2(int n);

          参数:

          a:距阵

          n,m:距阵行列数

          返回值:一维,二维距阵最大和

          源程序: 

           int a[101][101]; 

          int maxsum(int a[],int n)//一维最大串 

          { 

              int sum=-10000000,b=0; 

              int i; 

              for(i=0;i<n;i++) 

                  { 

            if (b>0) 

             b+=a[i]; 

            else 

             b=a[i]; 

            if(b>sum) 

             sum=b; 

            } 

           return sum; 

          } 

          int maxsum2(int m,int n)//二维最大串 

          { 

           int sum = -10000000; 

           int i,j,k,max; 

           int* b = new int[n+1]; 

           for (i=0;i<m;i++) 

            { 

            for(k=0;k<n;k++) 

             b[k]=a[i][k]; 

            max = maxsum(b,n);//第i列的一维最大串 

            if(max>sum) 

             sum=max; 

            for(j=i+1;j<m;j++) 

             { 

             for (k=0;k<=n;k++)b[k]+=a[j][k]; 

             max = maxsum(b,n);//类似maxsum,通过每列相加求二维最大串 

             if(max>sum)sum=max; 

             } 

            } 

           delete []b; 

           return sum; 

          } 

     

     

    8.求一个数每一位相加之和

          语法:result=digadd(int n)

          参数:

          n:待求数字

          返回值:各数字之和

          源程序: 

           int digadd(int n)

          {

          int i=0,k=0;

          while(i=n%10,n/=10)  k+=i;

          return k+i;

          }

     

     

    10.质因数分解

          语法:result=int reduce(int prime[],int pn,int n,int rest[])

          参数:

          Prime[]:素数表,至少需要达到sqrt(n)

          pn:素数表的元素个数

          N:待分解的数

          Rest:分解结果,按照升序排列

          返回值:分解因子个数

          源程序: 

           int reduce(int prime[],int pn,int n,int rest[])

          {

          int i,k=0;

          for(i=0;i<pn;i++)

               {

               if (n==1) break;

               if (prime[i]*prime[i]>n) {rest[k++]=n;break;}

               while(n%prime[i]==0)

                   {

                   n/=prime[i];

                   rest[k++]=prime[i];

                   }

               }

          return k;

          }

     

     

    11.高斯消元法解线性方程组

          语法:gauss(int n,double ** a)

          参数:

          N:变量个数

          Rest:变量系数行列式

          源程序: 

           void gauss(int n,double **a)

          {

           int i, j, k;

           double client, temp = 0.0;

           

           for(k = 0; k < n - 1; k++)

            for(i = k + 1; i < n; i++)

            {

             client = a[i][k]/a[k][k];

             for(j = k + 1; j < n; j++)

              a[i][j] = a[i][j] - client * a[k][j];

             a[i][n] = a[j - 1][n] - client * a[k][n]; 

            }

           a[n - 1][n] = a[n - 1][n]/a[n - 1][n - 1];

           for(i = n - 2; i >= 0; i--)

           {

            for (j = i + 1; j < n; j++)

             temp += a[i][j] * a[j][n];

            a[i][n] = (a[i][n] - temp) / a[i][i];

           }

          }

           

          //打印

          //for(i = 0; i < n; i++)

          // printf("X%d = %lf ", i + 1, a[i][n]);

     

     

    五、图论

    1.Prim算法求最小生成树

          语法:prim(Graph G,int vcount,int father[]);

          参数:

          G:图,用邻接矩阵表示

          vcount:表示图的顶点个数

          father[]:用来记录每个节点的父节点

          返回值:null

          注意: 

           常数max_vertexes为图最大节点数

           常数infinity为无穷大

          源程序: 

           #define infinity 1000000

          #define max_vertexes 5 

     

          typedef int Graph[max_vertexes][max_vertexes];

     

          void prim(Graph G,int vcount,int father[])

          {

              int i,j,k;

              int lowcost[max_vertexes],closeset[max_vertexes],used[max_vertexes];

              for (i=0;i<vcount;i++)

                  {

                  lowcost[i]=G[0][i];

                  closeset[i]=0; 

                  used[i]=0;

                  father[i]=-1; 

                  }

              used[0]=1; 

              for (i=1;i<vcount;i++)

                  {

                  j=0;

                  while (used[j]) j++;

                  for (k=0;k<vcount;k++)

                      if ((!used[k])&&(lowcost[k]<lowcost[j])) j=k;

                  father[j]=closeset[j]; 

                  used[j]=1;

                  for (k=0;k<vcount;k++)

                      if (!used[k]&&(G[j][k]<lowcost[k]))

                          { lowcost[k]=G[j][k];

                          closeset[k]=j; }

                  }

          }

     

     

    2.Dijkstra算法求单源最短路径

          语法:result=Dijkstra(Graph G,int n,int s,int t, int path[]);

          参数:

          G:图,用邻接矩阵表示

          n:图的顶点个数

          s:开始节点

          t:目标节点

          path[]:用于返回由开始节点到目标节点的路径

          返回值:最短路径长度

          注意: 

           输入的图的权必须非负

           顶点标号从0开始

           用如下方法打印路径:

              i=t;

              while (i!=s)

                  {

                  printf("%d<--",i+1);

                  i=path[i];

                  }

              printf("%d ",s+1); 

          源程序: 

           int Dijkstra(Graph G,int n,int s,int t, int path[])

          {

              int i,j,w,minc,d[max_vertexes],mark[max_vertexes];

              for (i=0;i<n;i++) mark[i]=0;

              for (i=0;i<n;i++)

                  { d[i]=G[s][i];

                  path[i]=s; }

              mark[s]=1;path[s]=0;d[s]=0;

              for (i=1;i<n;i++)

                  {

                 minc=infinity;

                  w=0;

                  for (j=0;j<n;j++)

                      if ((mark[j]==0)&&(minc>=d[j])) {minc=d[j];w=j;}

                  mark[w]=1;

                  for (j=0;j<n;j++)

                  if ((mark[j]==0)&&(G[w][j]!=infinity)&&(d[j]>d[w]+G[w][j]))

                      { d[j]=d[w]+G[w][j];

                      path[j]=w; }

                  }

              return d[t];

          }

     

     

    3.Bellman-ford算法求单源最短路径

          语法:result=Bellman_ford(Graph G,int n,int s,int t,int path[],int success);

          参数:

          G:图,用邻接矩阵表示

          n:图的顶点个数

          s:开始节点

          t:目标节点

          path[]:用于返回由开始节点到目标节点的路径

          success:函数是否执行成功

          返回值:最短路径长度

          注意: 

           输入的图的权可以为负,如果存在一个从源点可达的权为负的回路则success=0

           顶点标号从0开始

           用如下方法打印路径:

              i=t;

              while (i!=s)

                  {

                  printf("%d<--",i+1);

                  i=path[i];

                  }

              printf("%d ",s+1); 

          源程序: 

           int Bellman_ford(Graph G,int n,int s,int t,int path[],int success)

          {

              int i,j,k,d[max_vertexes];

              for (i=0;i<n;i++) {d[i]=infinity;path[i]=0;}

              d[s]=0;

              for (k=1;k<n;k++)

                  for (i=0;i<n;i++)

                      for (j=0;j<n;j++)

                          if (d[j]>d[i]+G[i][j]) {d[j]=d[i]+G[i][j];path[j]=i;}

              success=0;

              for (i=0;i<n;i++)

                  for (j=0;j<n;j++)

                      if (d[j]>d[i]+G[i][j]) return 0;

              success=1;

              return d[t];

          }

     

     

    4.Floyd-Warshall算法求每对节点间最短路径

          语法:Floyd_Washall(Graph G,int n,Graph D,Graph P);

          参数:

          G:图,用邻接矩阵表示

          n:图的顶点个数

          D:D[i,j]表示从i到j的最短距离

          P:P[i,j]表示从i到j的最短路径上j 的父节点 

          返回值:null

          源程序: 

           void Floyd_Washall(Graph G,int n,Graph D,Graph P)

          {

              int i,j,k;

              for (i=0;i<n;i++)

                  for (j=0;j<n;j++)

                      { D[i][j]=G[i][j];

                          P[i][j]=i; }

              for (i=0;i<n;i++) { D[i][i]=0;P[i][i]=0; }

              for (k=0;k<n;k++)

                  for (i=0;i<n;i++)

                      for (j=0;j<n;j++)

                          if (D[i][j]>D[i][k]+D[k][j])

                              { D[i][j]=D[i][k]+D[k][j];

                                  P[i][j]=P[k][j]; }

          }

     

     

    5.解欧拉图

          语法:int Eular(int graph[8][8], int v, int *path)

          参数:

          graph:图,用邻接矩阵表示

          v:图的顶点个数

          path:D[i,j]表示从i到j的最短距离

          注意: 

           此函数会删除图中的边

          返回值:若找到欧拉回路则返回路径长度,否则返回-1

          源程序: 

           int Eular(int graph[8][8], int v, int *path)

          {

               int start,a,b,count=0, deg,i;

               int s[1000], sp=0;//栈,大小可根据需要改变     

           

               start=0;

               while(true)

               {

                   a=start;

                   s[sp++]=a;

                   for(b=-1,i=0;i<v;i++) if (graph[i][a]&& a!=i) {b=i;break;}

                   for(;b!=start&&b!=-1;)

                   {

                        s[sp++]=b;

                        graph[a][b]=graph[b][a]=0;

                        a=b;

                        for(b=-1,i=0;i<v;i++) if (graph[i][a]&& a!=i) {b=i;break;}

                   }

                   if (b==-1) return(-1);//若找不到Eular回路返回-1

                   s[sp++]=b;

                   graph[a][b]=graph[b][a]=0;

               

                   while(sp>0)

                   {             

                        b=s[--sp];

                        for(i=0,deg=0;i<v;i++) if (graph[i][b]==1) {deg++; break;}

                        if (deg>0) break;

                        path[count++]=b;

                   }

                   if (sp==0) return(count);

                   start=b;      

               }

           

          }

     

     

    六、排序/查找

    1.快速排序

          语法:quicksort(int l,int r,int b[]);

          参数:

          l:排序上界,开始时l=0

          r:排序下界,开始时r=数组元素个数

          b[]:被排序的元素

          返回值:null

          注意: 

           输出升序序列

          源程序: 

           void quicksort(int l,int r,int b[])

          {

              int i,j,x;

              if(l>=r) return;

              i=l;

              j=r;

              x=b[i];

              while(i!=j)

                  {

                  while(b[j]>x&&j>i) j--;

                  if(i<j)

                      {

                      b[i]=b[j];

                      i++;

                      }

                  while(b[i]<x&&j>i)i++;

                      if(i<j)

                          {

                          b[j]=b[i];

                          j--;

                          }

                  }

              b[i]=x;

              quicksort(l,j-1,b);

              quicksort(i+1,r,b);

          }

     

     

    2.希尔排序

          语法:shellsort(int a[],int n);

          参数:

          n:数组元素个数

          a[]:待排序数组

          返回值:null

          注意: 

           输出升序序列

          源程序: 

           void shellsort(int a[],int n)

          {

              int i,j,g;

              int temp,k;

              g=n/2;

              while(g!=0)

                  {

                  for(i=g+1;i<=n;i++)

                      {

                      temp=a[i];

                      j=i-g;

                      while(j>0)

                          {

                          k=j+g;

                          if(a[j]<=a[k])

                              j=0;

                          else

                              {

                              temp=a[j];a[j]=a[k];a[k]=temp;

                              }

                          j=j-g;

                          }

                      }

                  g=g/2;

                  }

          }

     

     

    3.选择法排序

          语法:sort(int t[],int n);

          参数:

          t[]:待排序数组

          n:数组t[]元素的个数

          返回值:null

          注意: 

           输出升序序列

           小规模排序用

          源程序: 

           void sort(int t[],int n)

          {

             int i,j,k,temp;

              for (i=0;i<n;i++)

                  {

                  k=i;

                  for (j=i;j<n;j++) if (t[j]<t[k]) k=j;

                  temp=t[i];t[i]=t[k];t[k]=temp;

                  }

          }

     

     

    4.二分查找

          语法:result=search_bin(int *t,int k);

          参数:

          t[]:待查找数组

          k:查找关键字

          返回值:如果k在t[]中存在,输出i:t[i]=k,否则输出-1

          注意: 

           要求查找数组是有序升序序列

          源程序: 

           int search_bin(int *t,int k)

          {

              int low=1,high=10,mid;

              while (low<=high)

                  {

                  mid=(low+high)/2;

                  if (k==t[mid]) return mid;

                  else if (k<t[mid]) high=mid-1;

                  else low=mid+1;

                  }

              return -1;

          }

     

     

    七、数据结构

    1.顺序队列

          源程序: 

           #define maxsize 100

          typedef struct

          {

              int data[maxsize];

              int front;

              int rear;

          } sqqueue; 

          int sqinit(sqqueue *p) //队列初始化

          {

              p->front=0;

              p->rear=0;

              return 1;

          }

          int enqueue(sqqueue *q, int e) //入队

          {

              if((q->rear+1)%maxsize==q->front)

                  return 0;

              else

                  q->data[q->rear]=e;

              q->rear=(q->rear+1)%maxsize;

              return 1;

          }

          int dequeue(sqqueue *q) //出队

          {

              int e;

              if (q->front==q->rear)

                  return 0;

              e=q->data[q->front];

              q->front=(q->front+1)%maxsize;

              return e;

          }

          int empty(sqqueue *q)  //判空

          {

              int v;

              if (q->front==q->rear)

                  v=1;

              else

                  v=0;

               return v; 

          }

          int gethead(sqqueue *q)  //取得头元素

          {

              int e;

              if (q->front==q->rear) 

                  e=-1;

              else

                  e=q->data[q->front];

              return e;

          }

          void display(sqqueue *q) //显示所有元素

          {

              int s;

              s=q->front;

              printf("the sequeue is display: ");

              if (q->front==q->rear)

                  printf("the sequeue is empty!");

              else

                  {

                  while(s<q->rear)

                      {

                      printf("->%d", q->data[s]);

                      s=(s+1)%maxsize;

                      } 

              printf(" ");

          }

          }

          main(sqqueue *head)  //函数使用样例

          {

              int n,i,m,x,y,select,xq;

              printf("create a empty sequeue ");

              sqinit(head);

              printf("please input the sequeue length: "); 

              scanf("%d",&n);

              for (i=0;i<n;i++)

                  {

                  printf("please input a sequeue value: ");

                  scanf("%d",&m);

                  enqueue(head,m);

                 }

              printf("head->rear:%d ",head->rear);

              printf("head->front:%d ",head->front);

              display(head);

              printf("select 1 **** enqueue()  ");

              printf("select 2 **** dequeue()  ");

              printf("select 3 **** empty ()  ");

              printf("select 4 **** gethead()  ");

              printf("select 5 **** display()  ");

              printf("please select (1--5):");

              scanf("%d",&select);

              switch(select)

                  {

                  case 1:

                      { 

                      printf("please input a value :  ");

                      scanf("%d",&x);

                      enqueue(head,x);

                      display(head);

                      break;

                      }

                  case 2:

                      {

                      dequeue(head);

                      display(head);

                      break;

                      }

                  case 3:

                      {

                  if(empty(head))

                      printf("the sequeue is empty");

                  else

                      printf("the sequeue is full");

                      }

                  case 4:

                      {

                      y=gethead(head);

                      printf("output head value:%d ",y);

                      break;

                      }

                  case 5:

                      {

                      display(head);

                      break;

                      }

                  }

              }

          } 

     

     

    2.顺序栈

          源程序: 

           #define m 100

          typedef struct

          {

              int stack[m];

              int top;

          } stackstru; 

          init(stackstru *s) /*装入栈*/

          {

              s->top=0;

              return 1;

          }

          int push(stackstru *s,int x) /*入栈操作*/

          {

              if (s->top==m)

                  printf("the stack is overflow! ");

              else

                  {

                  s->top=s->top+1;

                  s->stack[s->top]=x;

                  }

          }

          void display(stackstru *s) /*显示栈所有数据*/

          {

              if(s->top==0)

                  printf("the stack is empty! ");

              else

                  {

                  while(s->top!=0)

                      {

                      printf("%d->",s->stack[s->top]);

                      s->top=s->top-1;

                      }

                  }

          }

          int pop(stackstru *s) /*出栈操作并返回被删除的那个记录*/

          {

              int y;

              if(s->top==0)

                  printf("the stack is empty! ");

              else

                  {

                  y=s->stack[s->top];

                  s->top=s->top-1;

                  return y;

                  }

          }

     

          int gettop(stackstru *s) /*得到栈顶数*/

          { 

              int e;

              if(s->top==0)

                  return 0;

              else 

                  e=s->stack[s->top];

              return e;

          }

          main(stackstru *p) //函数使用演示

          {

              int n,i,k,h,x1,x2,select;

              printf("create a empty stack! ");

              init(p);

              printf("input a stack length: ");

              scanf("%d",&n);

              for(i=0;i<n;i++)

                  {

                  printf("input a stack value: ");

                  scanf("%d",&k);

                  push(p,k);

                  }

              printf("select 1:display() ");

              printf("select 2:push() ");

              printf("select 3:pop() ");

              printf("select 4:gettop() ");

              printf("input a your select(1-4): ");

              scanf("%d",&select);

              switch(select)

                  {

                  case 1:

                      {

                      display(p);

                      break;

                      }

                  case 2:

                      {

                      printf("input a push a value: ");

                      scanf("%d",&h);

                      push(p,h);

                      display(p);

                      break;

                      }

                  case 3:

                      {

                      x1=pop(p);

                      printf("x1->%d ",x1);

                      display(p);

                      break;

                      }

                  case 4:

                      {

                      x2=gettop(p);

                      printf("x2->%d",x2);

                      break;

                      }

                  }

          }

     

     

    3.链表

          源程序: 

           # define null 0 

     

          typedef char ElemType; /* 字符型数据*/ 

     

          typedef struct LNode

          {

              ElemType data;

              struct LNode *next;

          };

     

          setnull(struct LNode **p);

          int length (struct LNode **p);

          ElemType get(struct LNode **p,int i);

          void insert(struct LNode **p,ElemType x,int i);

          int delete(struct LNode **p,int i);

          void display(struct LNode **p); 

          main()

          {

              struct LNode *head,*q; /*定义静态变量*/

              int select,x1,x2,x3,x4;

              int i,n; 

              int m,g;

              char e,y; 

     

              head=setnull(&head); /*建议链表并设置为空表*/

              printf("请输入数据长度: ");

              scanf("%d",&n);

              for(i=1;i<n;i++);

                  {

                  printf("将数据插入到单链表中: ");

                  scanf("%d",&y);

                  insert(&head,y,i);} /*插入数据到链表*/

                  display(&head); /*显示链表所有数据*/

     

                  printf("select 1 求长度 length() ");

                  printf("select 2 取结点 get() ");

                  printf("select 3 求值查找 locate() ");

                  printf("select 4 删除结点 delete() ");

                  printf("input your select: ");

                  scanf("%d",&select); 

                  switch(select)

                      {

                      case 1:

                          {

                          x1=length(&head);

                          printf("输出单链表的长度%d ",x1);

                          display(&head);

                          }break;

                      case 2:

                          {

                          printf("请输入要取得结点: ");

                          scanf("%d",&m);

                          x2=get(&head,m);

                          printf(x2);

                          display(&head);

                          }break;

                   case 3:

                          {

                          printf("请输入要查找的数据: ");

                          scanf("%d",&e);

                          x3=locate(&head,e);

                          printf(x3);

                          display(&head);

                          }break;

                   case 4:

                          {

                          printf("请输入要删除的结点: ");

                          scanf("%d",&g);

                          x4=delete(&head,g);

                          printf(x4);

                          display(&head);

                          }break;

                      }

                  }

          }

     

          setnull(struct LNode **p)

          {

              *p=null;

          }

          int length (struct LNode **p)

          {

              int n=0;

              struct LNode *q=*p;

              while (q!=null)

                  {

                  n++;

                  q=q->next;

                  }

              return(n);

          }

          ElemType get(struct LNode **p,int i)

          {

              int j=1;

              struct LNode *q=*p;

              while (j<i&&q!=null)

                  {

                  q=q->next;

                  j++;

                  }

                  if(q!=null)

                      return(q->data);

                  else

                      printf("位置参数不正确! ");

          }

          int locate(struct LNode **p,ElemType x)

              {

              int n=0;

              struct LNode *q=*p;

              while (q!=null&&q->data!=x)

                  {

                  q=q->next;

                  n++;

                  }

              if(q==null)

                  return(-1);

              else

                  return(n+1);

          }

          void insert(struct LNode **p,ElemType x,int i)

              {

              int j=1;

              struct LNode *s,*q;

              s=(struct LNode *)malloc(sizeof(struct LNode));

              s->data=x;

              q=*p;

              if(i==1)

                  {

                  s->next=q;

                  p=s;

                  }

              else

                  {

                  while(j<i-1&&q->next!=null)

                      {

                      q=q->next;

                      j++;

                      }

                  if(j==i-1)

                      {

                      s->next=q->next;

                      q->next=s;

                      }

                  else 

                      printf("位置参数不正确! ");

                  } 

          }

          int delete(struct LNode **p,int i)

          {

              int j=1;

              struct LNode *q=*p,*t;

              if(i==1)

                  {

                  t=q;

                  *p=q->next;

                  }

              else

                  {

                  while(j<i-1&&q->next!=null)

                      {

                      q=q->next;

                      j++;

                      }

                  if(q->next!=null&&j==i-1)

                      {

                      t=q->next;

                      q->next=t->next;

                      }

                  else 

                      printf("位置参数不正确! ");

                  }

              if(t=null) 

              free(t);

          }

          void display(struct LNode **p)

              { 

              struct LNode *q;

              q=*p;

              printf("单链表显示: ");

              if(q==null)

                  printf("链表为空!");

              else if (q->next==null)

                  printf("%c ",q->data);

              else

                  {

                  while(q->next!=null)

                      {

                      printf("%c->",q->data);

                      q=q->next;

                      }

                  printf("%c",q->data);

              }

              printf(" ");

          }

     

     

    4.链栈

          源程序: 

           # define null 0 

     

          typedef struct stacknode

          {

              int data;

              struct stacknode *next;

          } stacklink;

          typedef struct

          {

              stacklink *top;

              int stacksize;

              }stackk;

     

          initlink(stackk *s)

          {

             s->top=(stacklink *)malloc(sizeof(stacklink));

              s->top->data=0;

              s->top->next=null;

          } 

     

          int poplink(stackk *s)

          {

             stackk *p;int v;

              if(s->top->next==null) printf("the stackis empty ");

              else

                  {

                  v=s->top->next->data;

                   p=s->top->next;

                   s->top=s->top->next;

                  } 

              free(p);

              return v;

          }

          } 

          int pushlink(stackk *s,int x)

          {

             stackk *p;

              p=(stacklink *)malloc(sizeof(stacklink));

              p->data=x;

              p->next=s->top->next;

              s->top->next=p;

          }

          int gettop(stackk *s)

          {

             int e;

              if(s==null) printf("the stack is empty! ");

              e=s->top->next->data;

              return e;

          }

     

          display(stackk *s)

          {

             stackk *p;

              p=s->top->next;

              printf("display the stacklink: ");

              if (s->top=null) printf("the stacklink is empty! ");

              else

                 {

                 while(p)

                      {

                     printf("->%d",p->data);

                      p=p->next;

                     }

                  }

          }

     

          main(stacklink *p)

          {

             int n,k,i,select,h,x1,x2;

              printf("create a empty stacklink! ");

              initlink(p);

              printf("input a stacklink length: ");

              scanf("%d",&n);

              for (i=1;i<=n;i++)

                  {printf("input a stacklink value: ");

              scanf("%d",&k);

              pushlink(p,k);

                  }

              printf("select 1:display() ");

              printf("select 2:pushlink() ");

              printf("select 3:poplink() ");

              printf("select 4:gettop() ");

              printf("input a your select(1-4): ");

              scanf("%d",&select);

              switch(select)

                  {case 1:

                       {display(p);break;}

                  case 2:

                     {printf("input a push a value : ");

                      scanf("%d",&h);

                      pushlink(p,h);

                      display(p);

                      break;}

                  case 3:

                     {x1=poplink(p);printf("x1->%d ",x1);

                      display(p);

                      break;}

                  case 4:

                     {x2=gettop(p);printf("x2->%d",x2);

                      break;}

                  }

          }

     

     

    5.二叉树

          源程序: 

           typedef struct bitnode

          {

              char data;

              struct bitnode *lchild, *rchild;

          }bitnode, *bitree; 

          void createbitree(t,n)

          bitnode ** t;

          int *n;

          {

              char x;

              bitnode *q;

              *n=*n+1;

              printf("  Input %d DATA:",*n);

              x=getchar();

              if(x!=' ') getchar();

              if (x==' ')

                  return;

              q=(bitnode*)malloc(sizeof(bitnode));

              q->data=x;

              q->lchild=NULL;

              q->rchild=NULL;

              *t=q;

              printf(" This Address is: %o, Data is: %c,  Left Pointer is: %o, 

          Right Pointer is: %o",q,q->data,q->lchild,q->rchild);

              createbitree(&q->lchild,n);

              createbitree(&q->rchild,n);

              return;

          }

     

          void visit(e)

          bitnode *e;

          {

              printf(" Address: %o, Data: %c, Left Pointer: %o, Right Pointer: 

          %o ",e,e->data,e->lchild,e->rchild);

          }

     

          void preordertraverse(t)

          bitnode *t;

          {

              if(t)

                  {

                  visit(t);

                  preordertraverse(t->lchild);

                  preordertraverse(t->rchild);

                  return ;

                  }

             else

               return ;

          }

          void countleaf(t,c)

          bitnode *t;

          int *c;

          {

              if(t!=NULL)

                  {

                  if (t->lchild==NULL && t->rchild==NULL)

                  {*c=*c+1;

                  }

              countleaf(t->lchild,c);

              countleaf(t->rchild,c);

          }

          return;

          }

          int treehigh(t)

          bitnode *t;

          {

             int lh,rh,h;

              if(t==NULL)

                  h=0;

              else

                 {

                  lh=treehigh(t->lchild);

                  rh=treehigh(t->rchild);

                  h=(lh>rh ? lh:rh)+1;

                  }

              return h;

          }

     

          main()

          {

              bitnode *t; int count=0;

              int n=0;

             printf("  Please input TREE Data: ");

              createbitree(&t,&n);

             printf("  This is TREE struct:  ");

              preordertraverse(t);

             countleaf(t,&count);

              printf("  This TREE has %d leaves ",count);

             printf(" , High of The TREE is: %d ",treehigh(t));

          }

     

     

    八、高精度运算专题

    1.专题函数说明

          说明: 

           本栏为本专题所有程序的公用部分,调用本专题任何一个程序必须加上本栏的代码

           input/print为高精度数输入输出,调用格式为input(hp HightPoint,"123456")/print(hp 

          HighPoint)

           本栏为纯C++代码

          源程序: 

           #include <iostream> 

          using namespace std;

          #define maxsize 100

          struct hp

          {

             int len;

             int s[maxsize+1];

          };

     

          void input(hp &a,string str)

          {

             int i;

             while(str[0]=='0' && str.size()!=1)

                str.erase(0,1);

             a.len=(int)str.size();

             for(i=1;i<=a.len;++i)

                a.s[i]=str[a.len-i]-48;

             for (i=a.len+1;i<=maxsize;++i)

                a.s[i]=0;

          }

          void print(const hp &y)

          {

          int i;

          for(i=y.len;i>=1;i--)

             cout<<y.s[i];

          cout<<endl;

          }

     

     

    2.高精度数比较

          语法:int result=compare(const hp &a,const hp &b);

          参数:

          a,b:进行比较的高精度数字

          返回值:比较结果,a>b返回正数,a=b返回0,a<b返回负数

          源程序: 

           int compare(const hp &a,const hp &b)

          {

          int len;

          if(a.len>b.len)

             len=a.len;

          else

             len=b.len;

          while(len>0 && a.s[len]==b.s[len]) len--;

          if(len==0)

             return 0;

          else

             return a.s[len]-b.s[len];

          } 

     

     

    3.高精度数加法

          语法:plus(const hp &a,const hp &b,hp &c);

          参数:

          a,b:进行加法的高精度数字

          返回值:返回相加结果到c中

          源程序: 

           void plus(const hp &a,const hp &b,hp &c)

          {

          int i,len;

          for(i=1;i<=maxsize;i++) c.s[i]=0;

          if(a.len>b.len) len=a.len;

          else len=b.len;

          for(i=1;i<=len;i++)

             {

             c.s[i]+=a.s[i]+b.s[i];

             if(c.s[i]>=10)

                {

                c.s[i]-=10;

                c.s[i+1]++;

                }

             }

          if(c.s[len+1]>0) len++;

             c.len=len;

          }

     

     

    4.高精度数减法

          语法:subtract(const hp &a,const hp &b,hp &c);

          参数:

          a,b:进行减法的高精度数字,a是被减数,b是减数,不支持负数

          返回值:返回结果到c中

          源程序: 

           void subtract(const hp &a,const hp &b,hp &c)

          {

          int i,len;

          for(i=1;i<=maxsize;i++) c.s[i]=0;

          if(a.len>b.len) len=a.len;

          else len=b.len;

          for(i=1;i<=len;i++)

             {

             c.s[i]+=a.s[i]-b.s[i];

             if(c.s[i]<0)

                {

                c.s[i]+=10;

                c.s[i+1]--;

                }

             }

          while(len>1&&c.s[len]==0) len--;

             c.len=len;

          }

     

     

    5.高精度乘10 

          语法:multiply10(hp &a);

          参数:

          a:进行乘法的高精度数字

          返回值:返回结果到 a 中

          源程序: 

           void multiply10(hp &a)

          {

          int i;

          for(i=a.len;i>=1;i--)

             a.s[i+1]=a.s[i];

          a.s[1]=0;

          a.len++;

          while(a.len>1&&a.s[a.len]==0) a.len--;

          }

     

     

    6.高精度乘单精度

          语法:multiply(const hp &a,int b,hp &c);

          参数:

          a:进行乘法的高精度数字

          b:进行乘法的单精度数字

          返回值:返回结果到 c 中

          源程序: 

           void multiply(const hp &a,int b,hp &c)

          {

          int i,len;

          for(i=1;i<=maxsize;i++) c.s[i]=0;

          len=a.len;

          for(i=1;i<=len;i++)

             {

             c.s[i]+=a.s[i]*b;

             c.s[i+1]+=c.s[i]/10;

             c.s[i]%=10;

             }

          len++;

          while(c.s[len]>=10)

             {

             c.s[len+1]+=c.s[len]/10;

             c.s[len]%=10;

             len++;

             }

          while(len>1&&c.s[len]==0) len--;

          c.len=len;

          }

     

     

    7.高精度乘高精度

          语法:multiplyh(const hp &a,const hp &b,hp &c);

          参数:

          a,b:进行乘法的高精度数字

          返回值:返回结果到 c 中

          源程序: 

           void multiplyh(const hp &a,const hp &b,hp &c)

          {

          int i,j,len;

          for(i=1;i<=maxsize;i++) c.s[i]=0;

          for(i=1;i<=a.len;i++)

          for(j=1;j<=b.len;j++)

             {

             c.s[i+j-1]+=a.s[i]*b.s[j];

             c.s[i+j]+=c.s[i+j-1]/10;

             c.s[i+j-1]%=10;

             }

          len=a.len+b.len+1;

          while(len>1&&c.s[len]==0) len--;

          c.len=len;

          }

     

     

    8.高精度除单精度

          语法:divide(const hp &a,int b,hp &c,int &d);

          参数:

          a:进行除法的高精度数字

          返回值:返回商到 c 中,余数到 d 中

          源程序: 

           void divide(const hp &a,int b,hp &c,int &d)

          {

          int i,len;

          for(i=1;i<=maxsize;i++) c.s[i]=0;

          len=a.len;

          d=0;

          for(i=len;i>=1;i--)

             {

             d=d*10+a.s[i];

             c.s[i]=d/b;

             d%=b;

             }

          while(len>1&&c.s[len]==0) len--;

          c.len=len;

          }

     

     

    9.高精度除高精度

          语法:divideh(const hp &a,const hp &b,hp &c,hp &d);

          参数:

          a,b:进行除法的高精度数字

          返回值:返回商到 c 中,余数到 d 中

          注意: 

           需要compare、multiply10、subtract

          源程序: 

           void divideh(const hp &a,const hp &b,hp &c,hp &d)

          {

          hp e;

          int i,len;

          for(i=1;i<=maxsize;i++)

             {

             c.s[i]=0;

             d.s[i]=0;

             }

          len=a.len;

          d.len=1;

          for(i=len;i>=1;i--)

             {

             multiply10(d);

             d.s[1]=a.s[i];

             while(compare(d,b)>=0)

                {

                subtract(d,b,e);

                d=e;

                c.s[i]++;

                }

             }

          while(len>1&&c.s[len]==0) len--;

          c.len=len;

          } 

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

    C++

    #include<fstream.h>

    ifstream filein("file.in");

    ofstream fileout("file.out");

    int main(){

      int a,b;

      filein>>a>>b;

      fileout<<(a+b);

      return 0;

    }

     

    C:

    #include<stdio.h>

    int main(){

      freopen("file.in","r",stdin);

      freopen("file.out","w",stdout);

      int a,b;

      scanf("%d%d",&a,&b);

      printf("%d",a+b);

      fclose(stdin); fclose(stdout);

      return 0;

    }

     

    输入一开始就会说有N个Input Block,下面接着是N个Input Block。 

    如1526 

    Code: 

    cin >> n; 

    for( i=0 ; i<n ; i++ ) 

        .... 

     

    输入不说明有多少个Input Block,但以某个特殊输入为结束标志。 

    如1115 

    Code: 

    while( cin >> n && n != 0 ) 

        .... 

    输入不说明有多少个Input Block,以EOF为结束标志。 

    如1001 

    Code: 

    while( cin >> a >> b ) 

        .... 

     

    输入是一整行的字符串的 

    如1392 

    如果你用char buf[ 255 ]; 来保存的: 

    Code: 

    cin.getline( buf, 255 ); 

     

    如果你用string buf;来保存的: 

    Code: 

    getline( cin , buf ); 

     

    输出部分:

    一个Input Block对应一个Output Block,Output Block之间没有空行。 

    如1001 

    Code: 

        ... 

        cout << ans << endl; 

     

    一个Input Block对应一个Output Block,Output Block之间有空行。 

    如1152 

    Code: 

    int nCases = 0; 

    ... 

        if ( nCases++ ) cout << endl; 

        ... 

        cout << ans << endl; 

     

    一个Input Block对应一个Output Block,每个Output Block之后都有空行。 

    如1457 

    Code: 

        ... 

        cout << ans << endl << endl; }

     

    几何公式:

      1.长方体

      长方体的表面积=2×(a×b+b×c+c×a)

      长方体的体积=a×b×c(这里a、b、c分别表示长方体的长、宽、高)。

      2.正方体

      正方体的表面积=6×a2

      正方体的体积=a3(这里a为正方体的棱长)。

      3.圆柱体

      圆柱体的侧面积=2πRh

      圆柱体的全面积=2πRh+2πR2=2πR(h+R)

      圆柱体的体积=πR2h(这里R表示圆柱体底面圆的半径,h表示圆柱的高)。

      4.圆锥体

      圆锥体的侧面积=πRl

      圆锥体的全面积=πRl+πR2

         母线长与高)。

     

    积=6×a2

      正方体的体积=a3(这里a为正方体的棱长)。

      3.圆柱体

      圆柱体的侧面积=2πRh

      圆柱体的全面积=2πRh+2πR2=2πR(h+R)

      圆柱体的体积=πR2h(这里R表示圆柱体底面圆的半径,h表示圆柱的高)。

      4.圆锥体

      圆锥体的侧面积=πRl

      圆锥体的全面积=πRl+πR2

         母线长与高)。

     

  • 相关阅读:
    iptables防火墙-SNAT和DNAT
    exists & in
    系统演化之路
    promethue 采集traefik指标列表
    Grafana中变量
    Wireshark抓包
    http协议格式 基于ABNF语义定义
    Prometheus 管理常用知识点
    python时间转换
    通过salt-api获取minion的ip地址
  • 原文地址:https://www.cnblogs.com/SSYYGAM/p/4215309.html
Copyright © 2020-2023  润新知