ACM

   1 目录
   2 一、数学问题    4
   3 1.精度计算——大数阶乘    4
   4 2.精度计算——乘法(大数乘小数)    4
   5 3.精度计算——乘法(大数乘大数)    5
   6 4.精度计算——加法    6
   7 5.精度计算——减法    7
   8 6.任意进制转换    8
   9 7.最大公约数、最小公倍数    9
  10 8.组合序列    10
  11 9.快速傅立叶变换(FFT)    10
  12 10.Ronberg算法计算积分    12
  13 11.行列式计算    14
  14 12.求排列组合数    15
  15 13.求某一天星期几    15
  16 14.卡特兰 (Catalan) 数列 原理    16
  17 15.杨辉三角    16
  18 16.全排列    17
  19 17.匈牙利算法----最大匹配问题.    18
  20 18.最佳匹配KM算法    20
  21 二、字符串处理    22
  22 1.字符串替换    22
  23 2.字符串查找    23
  24 3.字符串截取    24
  25 4.LCS-最大公共子串长度    24
  26 5.LCS-最大公共子串长度    25
  27 6.数字转换为字符    26
  28 三、计算几何    27
  29 1.叉乘法求任意多边形面积    27
  30 2.求三角形面积    27
  31 3.两矢量间角度    28
  32 4.两点距离(2D、3D)    28
  33 5.射向法判断点是否在多边形内部    29
  34 6.判断点是否在线段上    30
  35 7.判断两线段是否相交    31
  36 8.判断线段与直线是否相交    32
  37 9.点到线段最短距离    32
  38 10.求两直线的交点    33
  39 11.判断一个封闭图形是凹集还是凸集    34
  40 12.Graham扫描法寻找凸包    35
  41 13.求两条线段的交点    36
  42 四、数论    37
  43 1.x的二进制长度    37
  44 2.返回x的二进制表示中从低到高的第i位    38
  45 3.模取幂运算    38
  46 4.求解模线性方程    39
  47 5.求解模线性方程组(中国余数定理)    39
  48 6.筛法素数产生器    40
  49 7.判断一个数是否素数    41
  50 8.求距阵最大和    42
  51 8.求一个数每一位相加之和    43
  52 10.质因数分解    43
  53 11.高斯消元法解线性方程组    44
  54 五、图论    45
  55 1.Prim算法求最小生成树    45
  56 2.Dijkstra算法求单源最短路径    46
  57 3.Bellman-ford算法求单源最短路径    47
  58 4.Floyd-Warshall算法求每对节点间最短路径    48
  59 5.解欧拉图    49
  60 六、排序/查找    50
  61 1.快速排序    50
  62 2.希尔排序    51
  63 3.选择法排序    52
  64 4.二分查找    52
  65 七、数据结构    53
  66 1.顺序队列    53
  67 2.顺序栈    56
  68 3.链表    59
  69 4.链栈    63
  70 5.二叉树    66
  71 八、高精度运算专题    68
  72 1.专题函数说明    68
  73 2.高精度数比较    69
  74 3.高精度数加法    69
  75 4.高精度数减法    70
  76 5.高精度乘10    71
  77 6.高精度乘单精度    71
  78 7.高精度乘高精度    72
  79 8.高精度除单精度    72
  80 9.高精度除高精度    73
  81 九、标准模板库的使用    74
  82 1.计算求和    74
  83 2.求数组中的最大值    76
  84 3. sort和qsort    76
  85 九、其他    78
  86 1.运行时间计算.    78
  87 
  88  
  89 
  90 一、数学问题
  91 1.精度计算——大数阶乘
  92       语法:int result=factorial(int n);
  93       参数:
  94       n:n 的阶乘
  95       返回值:阶乘结果的位数
  96       注意: 
  97        本程序直接输出n!的结果,需要返回结果请保留long a[]
  98        需要 math.h
  99       源程序: 
 100        int factorial(int n)
 101       {
 102       long a[10000];
 103       int i,j,l,c,m=0,w; 
 104       a[0]=1; 
 105       for(i=1;i<=n;i++)
 106           { 
 107           c=0; 
 108           for(j=0;j<=m;j++)
 109               { 
 110               a[j]=a[j]*i+c; 
 111               c=a[j]/10000; 
 112               a[j]=a[j]%10000; 
 113           } 
 114           if(c>0) {m++;a[m]=c;} 
 115       } 
 116 
 117       w=m*4+log10(a[m])+1;
 118       printf("\n%ld",a[m]); 
 119       for(i=m-1;i>=0;i--) printf("%4.4ld",a[i]);
 120       return w;
 121       } 
 122 2.精度计算——乘法(大数乘小数)
 123       语法:mult(char c[],char t[],int m);
 124       参数:
 125       c[]:被乘数,用字符串表示,位数不限
 126       t[]:结果,用字符串表示
 127       m:乘数,限定10以内
 128       返回值:null
 129       注意: 
 130        需要 string.h
 131       源程序: 
 132        void mult(char c[],char t[],int m)
 133       {
 134           int i,l,k,flag,add=0;
 135           char s[100];
 136           l=strlen(c);
 137           for (i=0;i<l;i++)
 138               s[l-i-1]=c[i]-'0'; 
 139           for (i=0;i<l;i++)
 140                  {
 141                  k=s[i]*m+add;
 142                  if (k>=10) {s[i]=k%10;add=k/10;flag=1;} else 
 143       {s[i]=k;flag=0;add=0;}
 144                  }
 145           if (flag) {l=i+1;s[i]=add;} else l=i;
 146           for (i=0;i<l;i++)
 147               t[l-1-i]=s[i]+'0';
 148           t[l]='\0';
 149       }
 150 3.精度计算——乘法(大数乘大数)
 151       语法:mult(char a[],char b[],char s[]);
 152       参数:
 153       a[]:被乘数,用字符串表示,位数不限
 154       b[]:乘数,用字符串表示,位数不限
 155       t[]:结果,用字符串表示
 156       返回值:null
 157       注意: 
 158        空间复杂度为 o(n^2)
 159        需要 string.h
 160       源程序: 
 161        void mult(char a[],char b[],char s[])
 162       {
 163           int i,j,k=0,alen,blen,sum=0,res[65][65]={0},flag=0;
 164           char result[65];
 165           alen=strlen(a);blen=strlen(b); 
 166           for (i=0;i<alen;i++)
 167           for (j=0;j<blen;j++) res[i][j]=(a[i]-'0')*(b[j]-'0');
 168           for (i=alen-1;i>=0;i--)
 169               {
 170                   for (j=blen-1;j>=0;j--) sum=sum+res[i+blen-j-1][j];
 171                   result[k]=sum%10;
 172                   k=k+1;
 173                   sum=sum/10;
 174               }
 175           for (i=blen-2;i>=0;i--)
 176               {
 177                   for (j=0;j<=i;j++) sum=sum+res[i-j][j];
 178                   result[k]=sum%10;
 179                   k=k+1;
 180                   sum=sum/10;
 181               }
 182           if (sum!=0) {result[k]=sum;k=k+1;}
 183           for (i=0;i<k;i++) result[i]+='0';
 184           for (i=k-1;i>=0;i--) s[i]=result[k-1-i];
 185           s[k]='\0';
 186           while(1)
 187               {
 188               if (strlen(s)!=strlen(a)&&s[0]=='0') 
 189                   strcpy(s,s+1);
 190               else
 191                   break;
 192               }
 193       }
 194 
 195  
 196 4.精度计算——加法
 197       语法:add(char a[],char b[],char s[]);
 198       参数:
 199       a[]:被加数,用字符串表示,位数不限
 200       b[]:加数,用字符串表示,位数不限
 201       s[]:结果,用字符串表示
 202       返回值:null
 203       注意: 
 204        空间复杂度为 o(n^2)
 205        需要 string.h
 206       源程序: 
 207        void add(char a[],char b[],char back[])
 208       {
 209           int i,j,k,up,x,y,z,l;
 210           char *c;
 211           if (strlen(a)>strlen(b)) l=strlen(a)+2; else l=strlen(b)+2;
 212           c=(char *) malloc(l*sizeof(char));
 213           i=strlen(a)-1;
 214           j=strlen(b)-1;
 215           k=0;up=0;
 216           while(i>=0||j>=0)
 217               {
 218                   if(i<0) x='0'; else x=a[i];
 219                   if(j<0) y='0'; else y=b[j];
 220                   z=x-'0'+y-'0';
 221                   if(up) z+=1;
 222                   if(z>9) {up=1;z%=10;} else up=0;
 223                   c[k++]=z+'0';
 224                   i--;j--;
 225               }
 226           if(up) c[k++]='1';
 227           i=0;
 228           c[k]='\0';
 229           for(k-=1;k>=0;k--)
 230               back[i++]=c[k];
 231           back[i]='\0';
 232       } 
 233 
 234  
 235 5.精度计算——减法
 236       语法:sub(char s1[],char s2[],char t[]);
 237       参数:
 238       s1[]:被减数,用字符串表示,位数不限
 239       s2[]:减数,用字符串表示,位数不限
 240       t[]:结果,用字符串表示
 241       返回值:null
 242       注意: 
 243        默认s1>=s2,程序未处理负数情况
 244        需要 string.h
 245       源程序: 
 246        void sub(char s1[],char s2[],char t[])
 247       {
 248           int i,l2,l1,k;
 249           l2=strlen(s2);l1=strlen(s1);
 250           t[l1]='\0';l1--;
 251           for (i=l2-1;i>=0;i--,l1--)
 252               {
 253               if (s1[l1]-s2[i]>=0) 
 254                   t[l1]=s1[l1]-s2[i]+'0';
 255               else
 256                   {
 257                   t[l1]=10+s1[l1]-s2[i]+'0';
 258                   s1[l1-1]=s1[l1-1]-1;
 259                   }
 260               }
 261           k=l1;
 262           while(s1[k]<0) {s1[k]+=10;s1[k-1]-=1;k--;}
 263           while(l1>=0) {t[l1]=s1[l1];l1--;}
 264       loop:
 265           if (t[0]=='0') 
 266               {
 267               l1=strlen(s1);
 268               for (i=0;i<l1-1;i++) t[i]=t[i+1];
 269               t[l1-1]='\0';
 270               goto loop;
 271               }
 272           if (strlen(t)==0) {t[0]='0';t[1]='\0';}
 273       } 
 274 
 275  
 276 6.任意进制转换
 277       语法:conversion(char s1[],char s2[],char t[]);
 278       参数:
 279       s[]:转换前的数字
 280       s2[]:转换后的数字
 281       d1:原进制数
 282       d2:需要转换到的进制数
 283       返回值:null
 284       注意: 
 285        高于9的位数用大写'A''Z'表示,2~16位进制通过验证
 286       源程序: 
 287        void conversion(char s[],char s2[],long d1,long d2)
 288       {
 289           long i,j,t,num;
 290           char c;
 291           num=0;
 292           for (i=0;s[i]!='\0';i++)
 293               {
 294               if (s[i]<='9'&&s[i]>='0') t=s[i]-'0'; else t=s[i]-'A'+10;
 295               num=num*d1+t;
 296               }
 297           i=0;
 298           while(1)
 299               {
 300               t=num%d2;
 301               if (t<=9) s2[i]=t+'0'; else s2[i]=t+'A'-10;
 302               num/=d2;
 303               if (num==0) break;
 304               i++;
 305               }
 306           for (j=0;j<i/2;j++)
 307               {c=s2[j];s2[j]=s[i-j];s2[i-j]=c;}
 308           s2[i+1]='\0';
 309       }
 310 
 311  
 312 7.最大公约数、最小公倍数
 313       语法:resulet=hcf(int a,int b)、result=lcd(int a,int b)
 314       参数:
 315       a:int a,求最大公约数或最小公倍数
 316       b:int b,求最大公约数或最小公倍数
 317       返回值:返回最大公约数(hcf)或最小公倍数(lcd)
 318       注意: 
 319        lcd 需要连同 hcf 使用
 320       源程序: 
 321        int hcf(int a,int b)
 322       {
 323           int r=0;
 324           while(b!=0)
 325               {
 326               r=a%b;
 327               a=b;
 328               b=r;
 329               }
 330           return(a);
 331       } 
 332       lcd(int u,int v,int h)
 333       {
 334           return(u*v/h);
 335       }
 336 
 337  
 338 8.组合序列
 339       语法:m_of_n(int m, int n1, int m1, int* a, int head)
 340       参数:
 341       m:组合数C的上参数
 342       n1:组合数C的下参数
 343       m1:组合数C的上参数,递归之用
 344       *a:1~n的整数序列数组
 345       head:头指针
 346       返回值:null
 347       注意: 
 348        *a需要自行产生
 349        初始调用时,m=m1、head=0
 350        调用例子:求C(m,n)序列:m_of_n(m,n,m,a,0);
 351       源程序: 
 352        void m_of_n(int m, int n1, int m1, int* a, int head) 
 353       { 
 354           int i,t; 
 355           if(m1<0 || m1>n1) return; 
 356           if(m1==n1) 
 357               { 
 358               return; 
 359               } 
 360           m_of_n(m,n1-1,m1,a,head); // 递归调用 
 361           t=a[head];a[head]=a[n1-1+head];a[n1-1+head]=t;
 362           m_of_n(m,n1-1,m1-1,a,head+1); // 再次递归调用 
 363           t=a[head];a[head]=a[n1-1+head];a[n1-1+head]=t;
 364       } 
 365 
 366  
 367 9.快速傅立叶变换(FFT)
 368       语法:kkfft(double pr[],double pi[],int n,int k,double fr[],double fi[],int 
 369       l,int il);
 370       参数:
 371       pr[n]:输入的实部 
 372       pi[n]:数入的虚部
 373       n,k:满足n=2^k
 374       fr[n]:输出的实部
 375       fi[n]:输出的虚部
 376       l:逻辑开关,0 FFT,1 ifFT
 377       il:逻辑开关,0 输出按实部/虚部;1 输出按模/幅角 
 378       返回值:null
 379       注意: 
 380        需要 math.h
 381       源程序: 
 382        void kkfft(pr,pi,n,k,fr,fi,l,il) 
 383       int n,k,l,il; 
 384       double pr[],pi[],fr[],fi[]; 
 385       {
 386           int it,m,is,i,j,nv,l0; 
 387           double p,q,s,vr,vi,poddr,poddi; 
 388           for (it=0; it<=n-1; it++) 
 389               {
 390                m=it; is=0; 
 391               for (i=0; i<=k-1; i++) 
 392                   {j=m/2; is=2*is+(m-2*j); m=j;}
 393               fr[it]=pr[is]; fi[it]=pi[is]; 
 394               } 
 395           pr[0]=1.0; pi[0]=0.0; 
 396           p=6.283185306/(1.0*n); 
 397           pr[1]=cos(p); pi[1]=-sin(p); 
 398           if (l!=0) pi[1]=-pi[1]; 
 399           for (i=2; i<=n-1; i++) 
 400               {
 401              p=pr[i-1]*pr[1];
 402              q=pi[i-1]*pi[1]; 
 403               s=(pr[i-1]+pi[i-1])*(pr[1]+pi[1]); 
 404               pr[i]=p-q; pi[i]=s-p-q; 
 405               } 
 406           for (it=0; it<=n-2; it=it+2) 
 407               {
 408              vr=fr[it]; vi=fi[it]; 
 409               fr[it]=vr+fr[it+1]; fi[it]=vi+fi[it+1]; 
 410               fr[it+1]=vr-fr[it+1]; fi[it+1]=vi-fi[it+1]; 
 411               } 
 412           m=n/2; nv=2; 
 413           for (l0=k-2; l0>=0; l0--) 
 414               {
 415               m=m/2; nv=2*nv; 
 416               for (it=0; it<=(m-1)*nv; it=it+nv) 
 417                   for (j=0; j<=(nv/2)-1; j++) 
 418                       {
 419                      p=pr[m*j]*fr[it+j+nv/2]; 
 420                       q=pi[m*j]*fi[it+j+nv/2]; 
 421                       s=pr[m*j]+pi[m*j]; 
 422                       s=s*(fr[it+j+nv/2]+fi[it+j+nv/2]); 
 423                       poddr=p-q; poddi=s-p-q; 
 424                       fr[it+j+nv/2]=fr[it+j]-poddr; 
 425                       fi[it+j+nv/2]=fi[it+j]-poddi; 
 426                       fr[it+j]=fr[it+j]+poddr; 
 427                       fi[it+j]=fi[it+j]+poddi; 
 428                       } 
 429               } 
 430           if (l!=0) 
 431               for (i=0; i<=n-1; i++) 
 432                   {
 433                  fr[i]=fr[i]/(1.0*n); 
 434                   fi[i]=fi[i]/(1.0*n); 
 435                   } 
 436           if (il!=0) 
 437                   for (i=0; i<=n-1; i++) 
 438                   {
 439                  pr[i]=sqrt(fr[i]*fr[i]+fi[i]*fi[i]); 
 440                   if (fabs(fr[i])<0.000001*fabs(fi[i])) 
 441                       {
 442                      if ((fi[i]*fr[i])>0) pi[i]=90.0; 
 443                       else pi[i]=-90.0; 
 444                       } 
 445                   else 
 446                       pi[i]=atan(fi[i]/fr[i])*360.0/6.283185306; 
 447                   } 
 448           return; 
 449       } 
 450 
 451  
 452 10.Ronberg算法计算积分
 453       语法:result=integral(double a,double b);
 454       参数:
 455       a:积分上限
 456       b:积分下限
 457       function f:积分函数
 458       返回值:f在(a,b)之间的积分值
 459       注意: 
 460        function f(x)需要自行修改,程序中用的是sina(x)/x
 461        需要 math.h
 462        默认精度要求是1e-5
 463       源程序: 
 464        double f(double x)
 465       { 
 466           return sin(x)/x; //在这里插入被积函数 
 467       }
 468 
 469       double integral(double a,double b) 
 470       { 
 471           double h=b-a; 
 472           double t1=(1+f(b))*h/2.0;
 473           int k=1; 
 474           double r1,r2,s1,s2,c1,c2,t2; 
 475       loop: 
 476           double s=0.0; 
 477           double x=a+h/2.0; 
 478           while(x<b) 
 479               { 
 480               s+=f(x); 
 481               x+=h; 
 482               } 
 483           t2=(t1+h*s)/2.0;
 484           s2=t2+(t2-t1)/3.0;
 485           if(k==1)
 486             { 
 487               k++;h/=2.0;t1=t2;s1=s2;
 488               goto loop; 
 489               } 
 490           c2=s2+(s2-s1)/15.0; 
 491           if(k==2){ 
 492               c1=c2;k++;h/=2.0; 
 493               t1=t2;s1=s2; 
 494               goto loop; 
 495               } 
 496           r2=c2+(c2-c1)/63.0; 
 497           if(k==3){ 
 498               r1=r2; c1=c2;k++; 
 499               h/=2.0; 
 500               t1=t2;s1=s2;
 501               goto loop; 
 502               } 
 503           while(fabs(1-r1/r2)>1e-5){ 
 504               r1=r2;c1=c2;k++;
 505               h/=2.0; 
 506               t1=t2;s1=s2; 
 507               goto loop; 
 508               } 
 509           return r2;
 510       } 
 511 
 512  
 513 11.行列式计算
 514       语法:result=js(int s[][],int n)
 515       参数:
 516       s[][]:行列式存储数组
 517       n:行列式维数,递归用
 518       返回值:行列式值
 519       注意: 
 520        函数中常数N为行列式维度,需自行定义
 521       源程序: 
 522        int js(s,n) 
 523       int s[][N],n; 
 524       {
 525           int z,j,k,r,total=0; 
 526           int b[N][N];/*b[N][N]用于存放,在矩阵s[N][N]中元素s[0]的余子式*/ 
 527           if(n>2)
 528               {
 529               for(z=0;z<n;z++) 
 530                   {
 531                   for(j=0;j<n-1;j++) 
 532                        for(k=0;k<n-1;k++) 
 533                               if(k>=z) b[j][k]=s[j+1][k+1];  else 
 534       b[j][k]=s[j+1][k]; 
 535                   if(z%2==0) r=s[0][z]*js(b,n-1); /*递归调用*/ 
 536                   else r=(-1)*s[0][z]*js(b,n-1); 
 537                   total=total+r; 
 538                   } 
 539               } 
 540           else if(n==2)
 541              total=s[0][0]*s[1][1]-s[0][1]*s[1][0]; 
 542           return total; 
 543       } 
 544 
 545  
 546 12.求排列组合数
 547       语法:result=P(long n,long m); / result=long C(long n,long m);
 548       参数:
 549       m:排列组合的上系数
 550       n:排列组合的下系数
 551       返回值:排列组合数
 552       注意: 
 553        符合数学规则:m<=n
 554       源程序: 
 555        long P(long n,long m)
 556       {
 557           long p=1;
 558           while(m!=0)
 559               {p*=n;n--;m--;}
 560           return p;
 561       } 
 562       long C(long n,long m)
 563       {
 564           long i,c=1;
 565           i=m;
 566           while(i!=0)
 567               {c*=n;n--;i--;}
 568           while(m!=0)
 569               {c/=m;m--;}
 570           return c;
 571       } 
 572 
 573  
 574 13.求某一天星期几
 575       语法:result=weekday(int N,int M,int d)
 576       参数:
 577       N,M,d:年月日,例如:2003,11,4
 578       返回值:0:星期天,1星期一……
 579       注意: 
 580        需要math.h
 581        适用于1582年10月15日之后, 因为罗马教皇格里高利十三世在这一天启用新历法.
 582       源程序: 
 583        int weekday(int N,int M,int d)
 584       {
 585       int m,n,c,y,w;
 586       m=(M-2)%12;
 587       if (M>=3) n=N;else n=N-1;
 588       c=n/100;
 589       y=n%100;
 590       w=(int)(d+floor(13*m/5)+y+floor(y/4)+floor(c/4)-2*c)%7;
 591       while(w<0) w+=7;
 592       return w;
 593       }
 594 14.卡特兰 (Catalan) 数列 原理
 595 令h(1)=1,catalan数满足递归式:
 596 h(n)= h(1)*h(n-1) + h(2)*h(n-2) + ... + h(n-1)h(1) (其中n>=2)
 597 该递推关系的解为:h(n)=c(2n-2,n-1)/n (n=1,2,3,...) 
 598 1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, 208012, 742900, 2674440, 9694845, 35357670, 129644790, 477638700, 1767263190, 6564120420, 24466267020, 91482563640, 343059613650, 1289904147324, 4861946401452, …
 599 1.括号化问题。 
 600 矩阵链乘: P=a1×a2×a3×……×an,依据乘法结合律,不改变其顺序,只用括号表示成对的乘积,试问有几种括号化的方案?(h(n)种) 
 601 2.出栈次序问题。
 602 一个栈(无穷大)的进栈序列为1,2,3,..n,有多少个不同的出栈序列? 
 603 类似:有2n个人排成一行进入剧场。入场费5元。其中只有n个人有一张5元钞票,另外n人只有10元钞票,剧院无其它钞票,问有多少中方法使得只要有10元的人买票,售票处就有5元的钞票找零?(将持5元者到达视作将5元入栈,持10元者到达视作使栈中某5元出栈) 
 604 3.将多边行划分为三角形问题。
 605 将一个凸多边形区域分成三角形区域的方法数? 
 606 类似:一位大城市的律师在她住所以北n个街区和以东n个街区处工作。每天她走2n个街区去上班。如果他
 607 从不穿越(但可以碰到)从家到办公室的对角线,那么有多少条可能的道路? 
 608 类似:在圆上选择2n个点,将这些点成对连接起来使得所得到的n条线段不相交的方法数?
 609  15.杨辉三角
 610 语法: void gen()
 611 预置:
 612 Const int Max;
 613 注意: (Max一般不能超过22,否则要用高精度计算)
 614     int inta[Max][Max];
 615 结果:inta为杨辉三角序列.inta[1][1]=1;inta[2][1]=1;inta[2][2]=1 616 void gen()
 617 {
 618          int i ,j;
 619          for( i =1 ;i <= Max ;i++)
 620          {
 621                  inta[i][1] = 1 ;
 622                  inta[i][i] = 1 ;
 623          }
 624          inta[2][2] = 1   ;
 625          for( i = 3 ; i<=Max ;i++)
 626          {
 627                  for(j =2 ;j<i ; j++ )
 628                  {
 629                          inta[i][j] = inta[i-1][j-1] + inta[i-1][j] ;
 630                  }
 631          }
 632 }
 633 前十行:
 634 1
 635 1 1
 636 1 2 1
 637 1 3 3 1
 638 1 4 6 4 1
 639 1 5 10 10 5 1
 640 1 6 15 20 15 6 1
 641 1 7 21 35 35 21 7 1
 642 1 8 28 56 70 56 28 8 1
 643 1 9 36 84 126 126 84 36 9 1
 644 
 645 16.全排列
 646 语法: void qp(int Array[],int begin,int end);
 647 注意:当参与全排列的数字稍大的时候将会有很大的计算量
 648 
 649 #include<iostream>
 650 using namespace std;
 651 const int MaxNum=20;
 652 static int a[MaxNum];
 653 void qp(int Array[],int begin,int end);
 654 int main()
 655 {
 656     int i;
 657     for(i=0;i<MaxNum;i++)
 658         a[i]=i+1;    
 659     //初始化数组为:1,2,3..
 660     qp(a,0,10);
 661     return 0;
 662 }
 663 void qp(int Array[],int begin,int end)
 664 {
 665     int i;
 666     if(begin>=end)
 667     {
 668         for(i=0;i<end;i++)
 669             cout<<Array[i]<<"\t";
 670         cout<<endl;
 671     }
 672     else for(i=begin;i<end;i++)
 673     {
 674         swap(a[begin],a[i]);
 675         qp(a,begin+1,end);
 676         swap(a[begin],a[i]);    
 677     }
 678 }
 679 
 680 
 681 //stl里面的全排列生成函数next_permutation
 682 #include<iostream>
 683 #include <algorithm>
 684 using namespace std;
 685 
 686 int main()
 687 {
 688     int i;
 689     int A[] = {0,1,2,3};
 690     while(next_permutation(A, A+4)==true)    //prev_permutation(A, A+4);
 691 
 692     {
 693         for(i=0;i<4;i++)
 694             cout<<A[i]<<"\t";
 695         cout<<endl;
 696 
 697     }
 698 }
 699 17.匈牙利算法----最大匹配问题.
 700 #include<stdio.h>
 701 #include<string.h>
 702 bool g[201][201];            //为边之间的关系,如g[0][1]==true表示为左边0点可与右边1点相连.
 703 int n,m,ans;                //n左边的点,m右边的点,ans为最大匹配的边数.
 704 bool b[201];                //b[i]表示该点是否有左边的点连上
 705 int link[201];
 706 bool init()
 707 {
 708     int _x,_y;
 709     memset(g,0,sizeof(g));            //对二维数组也可以这样初始化!
 710     memset(link,0,sizeof(link));
 711     ans=0;
 712     if(scanf("%d%d",&n,&m)==EOF)return false;
 713     for(int i=1;i<=n;i++)        //n左边的点,m右边的点
 714     {
 715         scanf("%d",&_x);
 716         for(int j=0;j<_x;j++)
 717         {
 718             scanf("%d",&_y);
 719             g[ i ][_y]=true;
 720         }
 721     }
 722     return true;
 723 }
 724 bool find(int a)
 725 {
 726     for(int i=1;i<=m;i++)
 727     {
 728         if(g[a][ i ]==true&&!b[ i ])
 729         {
 730             b[ i ]=true;
 731             if(link[ i ]==0||find(link[ i ]))
 732             {
 733                 link[ i ]=a;
 734                 return true;
 735             }
 736         }
 737     }
 738     return false;
 739 }
 740 int main()
 741 {
 742     while(init())
 743     {
 744         for(int i=1;i<=n;i++)        
 745         {
 746             memset(b,0,sizeof(b));    //
 747             if(find(i))
 748                 ans++;
 749         }
 750         printf("%d\n",ans);
 751         }
 752 }
 753 18.最佳匹配KM算法
 754 #include <cstdio> 
 755 #include <queue> 
 756 #include <algorithm> 
 757 using namespace std; 
 758 const int N = 301; 
 759 const int INF = 10000; 
 760   
 761 class Graph 
 762 { 
 763 private: 
 764    bool xckd[N], yckd[N]; 
 765    int n, edge[N][N], xmate[N], ymate[N]; 
 766    int lx[N], ly[N], slack[N], prev[N]; 
 767    queue<int> Q; 
 768    bool bfs(); 
 769    void agument(int); 
 770 public: 
 771    bool make(); 
 772    int KMMatch(); 
 773 }; 
 774 bool Graph::make()
 775 { 
 776     int i, j;
 777 while(scanf("%d", &n) != EOF)
 778     {
 779         for(i = 0; i < n; i++) 
 780         {  
 781             for(j = 0; j < n; j++)
 782             {   
 783                 scanf("%d", &edge[i][j]);     
 784             } 
 785         }
 786         return true;
 787     }
 788     return false;
 789 } 
 790 bool Graph::bfs() { 
 791    while(!Q.empty()) { 
 792       int p = Q.front(), u = p>>1; Q.pop(); 
 793       if(p&1) { 
 794          if(ymate[u] == -1) { agument(u); return true; } 
 795          else { xckd[ymate[u]] = true; Q.push(ymate[u]<<1); } 
 796       } else { 
 797          for(int i = 0; i < n; i++) 
 798             if(yckd[i]) continue; 
 799             else if(lx[u]+ly[i] != edge[u][i]) { 
 800                int ex = lx[u]+ly[i]-edge[u][i]; 
 801                if(slack[i] > ex) { slack[i] = ex; prev[i] = u; } 
 802             } else { 
 803                yckd[i] = true; prev[i] = u; 
 804                Q.push((i<<1)|1); 
 805             } 
 806       } 
 807    } 
 808    return false; 
 809 } 
 810 void Graph::agument(int u) { 
 811    while(u != -1) { 
 812       int pv = xmate[prev[u]]; 
 813       ymate[u] = prev[u]; xmate[prev[u]] = u; 
 814       u = pv; 
 815    } 
 816 } 
 817 int Graph::KMMatch() 
 818 { 
 819     int i, j;
 820    memset(ly, 0, sizeof(ly)); 
 821    for(i = 0; i < n; i++) { 
 822       lx[i] = -INF; 
 823       for(j = 0; j < n; j++) 
 824           lx[i] =  lx[i] > edge[i][j] ? lx[i] : edge[i][j]; 
 825    } 
 826    memset(xmate, -1, sizeof(xmate)); memset(ymate, -1, sizeof(ymate)); 
 827    bool agu = true; 
 828    for(int mn = 0; mn < n; mn++) { 
 829       if(agu) { 
 830          memset(xckd, false, sizeof(xckd)); 
 831          memset(yckd, false, sizeof(yckd)); 
 832          for(i = 0; i < n; i++) slack[i] = INF; 
 833          while(!Q.empty()) Q.pop(); 
 834          xckd[mn] = true; Q.push(mn<<1); 
 835       } 
 836       if(bfs()) { agu = true; continue; } 
 837       int ex = INF; mn--; agu = false; 
 838       for(i = 0; i < n; i++) 
 839           if(!yckd[i]) ex = ex < slack[i] ? ex : slack[i]; 
 840       for(i = 0; i < n; i++) { 
 841          if(xckd[i]) lx[i] -= ex; 
 842          if(yckd[i]) ly[i] += ex; 
 843          slack[i] -= ex; 
 844       } 
 845       for(int i = 0; i < n; i++) 
 846          if(!yckd[i] && slack[i] == 0) { yckd[i] = true; Q.push((i<<1)|1); } 
 847    } 
 848    int cost = 0; 
 849    for(i = 0; i < n; i++) cost += edge[i][xmate[i]]; 
 850    return cost; 
 851 } 
 852 int main() 
 853 {
 854    Graph g; 
 855    while(g.make())
 856    {
 857        printf("%d\n", g.KMMatch()); 
 858    }
 859    return 0;
 860 }
 861 二、字符串处理
 862 1.字符串替换
 863       语法:replace(char str[],char key[],char swap[]);
 864       参数:
 865       str[]:在此源字符串进行替换操作
 866       key[]:被替换的字符串,不能为空串
 867       swap[]:替换的字符串,可以为空串,为空串表示在源字符中删除key[]
 868       返回值:null
 869       注意: 
 870        默认str[]长度小于1000,如否,重新设定设定tmp大小
 871        需要 string.h
 872       源程序: 
 873        void replace(char str[],char key[],char swap[])
 874       {
 875           int l1,l2,l3,i,j,flag;
 876           char tmp[1000];
 877           l1=strlen(str);
 878           l2=strlen(key);
 879           l3=strlen(swap);
 880           for (i=0;i<=l1-l2;i++)
 881               {
 882               flag=1;
 883               for (j=0;j<l2;j++)
 884                   if (str[i+j]!=key[j]) {flag=0;break;}
 885               if (flag)
 886                   {
 887                   strcpy(tmp,str);
 888                   strcpy(&tmp[i],swap);
 889                   strcpy(&tmp[i+l3],&str[i+l2]);
 890                   strcpy(str,tmp);
 891                   i+=l3-1;
 892                   l1=strlen(str);
 893                   }
 894               }
 895       }
 896 
 897 
 898 2.字符串查找
 899       语法:result=strfind(char str[],char key[]);
 900       参数:
 901       str[]:在此源字符串进行查找操作
 902       key[]:被查找的字符串,不能为空串
 903       返回值:如果查找成功,返回key在str中第一次出现的位置,否则返回-1
 904       注意: 
 905        需要 string.h
 906       源程序: 
 907        int strfind(char str[],char key[])
 908       {
 909           int l1,l2,i,j,flag;
 910           l1=strlen(str);
 911           l2=strlen(key);
 912           for (i=0;i<=l1-l2;i++)
 913               {
 914               flag=1;
 915               for (j=0;j<l2;j++)
 916                   if (str[i+j]!=key[j]) {flag=0;break;}
 917               if (flag) return i;
 918               }
 919           return -1;
 920       } 
 921 
 922  
 923 3.字符串截取
 924       语法:mid(char str[],int start,int len,char strback[])
 925       参数:
 926       str[]:操作的目标字符串
 927       start:从第start个字符串开始,截取长度为len的字符
 928       len:从第start个字符串开始,截取长度为len的字符
 929       strback[]:截取的到的字符
 930       返回值:0:超出字符串长度,截取失败;1:截取成功
 931       注意: 
 932        需要 string.h
 933       源程序: 
 934        int mid(char str[],int start,int len,char strback[])
 935       {
 936           int l,i,k=0;
 937           l=strlen(str);
 938           if (start+len>l) return 0;
 939           for (i=start;i<start+len;i++)
 940               strback[k++]=str[i];
 941           strback[k]='\0';
 942           return 1;
 943       } 
 944 
 945  
 946 4.LCS-最大公共子串长度
 947       语法:result=lcs_len(char *a, char *b);
 948       参数:
 949       a,b[]:根据a,b生成最大公共子串
 950       返回值:最大公共子串的长度
 951       注意: 
 952        需要 string.h
 953        M、N是a,b数组的最大可能长度
 954        如果不需要生成公共子串,c[M][N]不可设置为全局变量
 955       源程序: 
 956        #define M 20
 957       #define N 20
 958       int c[M][N]; 
 959       int lcs_len(char *a, char *b)
 960       {
 961       int m=strlen(a),n=strlen(b),i,j;
 962       for(i=0;i<=m;i++) c[i][0]=0;
 963       for(j=0;j<=n;j++) c[0][j]=0;
 964       for(i=1;i<=m;i++)
 965           for(j=1;j<=n;j++)
 966           {
 967           if(a[i-1]==b[j-1])
 968               c[i][j]=c[i-1][j-1]+1;
 969           else if(c[i-1][j]>c[i][j-1])
 970               c[i][j]=c[i-1][j];
 971           else
 972               c[i][j]=c[i][j-1];
 973           }
 974       return c[m][n];
 975       }
 976 
 977  
 978 5.LCS-最大公共子串长度
 979       语法:result=build_lcs(char s[], char *a, int blen, int clen);
 980       参数:
 981       *a:生成公共子串的字符串a,b中的a
 982       s[]:接受返回结果的字符串数组
 983       blen:生成公共子串的字符串a,b中的b的长度
 984       clen:最大公共子串的长度,通过lcs_len函数求得
 985       返回值:最大公共子串的长度
 986       注意: 
 987        需要 string.h
 988        需要lcs_len函数求clen并且生成c[M][N]
 989        可通过result=build_lcs返回指针或者通过build_lcs(s,a,blen,clen),用s接受结果
 990       源程序: 
 991        char *build_lcs(char s[], char *a, int blen, int clen)
 992       {
 993       int k=clen,alen=strlen(a),i,j;
 994       s[k]='\0';
 995       i=alen,j=blen;
 996       while(k>0)
 997           {
 998           if(c[i][j]==c[i-1][j])
 999           i--;
1000           else if(c[i][j]==c[i][j-1])
1001           j--;
1002           else
1003               {
1004               s[--k]=a[i-1];
1005               i--;j--;
1006               }
1007           }
1008       return s;
1009       } 
1010 
1011  
1012 6.数字转换为字符
1013       语法:cstr(int k,char o[]);
1014       参数:
1015       k:转换的数字
1016       o[]:存储转换结果的字符串
1017       返回值:null
1018       注意: 
1019        需要 math.h
1020       源程序: 
1021        void cstr(int k,char o[])
1022       {
1023           int len,i,t;
1024           len=log10(k)+1;
1025           for (i=len;i>0;i--)
1026               {
1027               t=k%10;
1028               k-=t;k/=10;
1029               o[i-1]='0'+t;
1030               }
1031           o[len]='\0';
1032       }
1033 
1034  
1035 三、计算几何
1036 1.叉乘法求任意多边形面积
1037       语法:result=polygonarea(Point *polygon,int N);
1038       参数:
1039       *polygon:多变形顶点数组
1040       N:多边形顶点数目
1041       返回值:多边形面积
1042       注意: 
1043        支持任意多边形,凹、凸皆可
1044        多边形顶点输入时按顺时针顺序排列
1045       源程序: 
1046        typedef struct {
1047           double x,y;
1048       } Point; 
1049       double polygonarea(Point *polygon,int N)
1050       {
1051           int i,j;
1052           double area = 0;
1053           for (i=0;i<N;i++) {
1054               j = (i + 1) % N;
1055               area += polygon[i].x * polygon[j].y;
1056               area -= polygon[i].y * polygon[j].x;
1057               }
1058           area /= 2;
1059           return(area < 0 ? -area : area);
1060       }
1061 
1062 
1063 2.求三角形面积
1064       语法:result=area3(float x1,float y1,float x2,float y2,float x3,float y3);
1065       参数:
1066       x1~3:三角形3个顶点x坐标
1067       y1~3:三角形3个顶点y坐标
1068       返回值:三角形面积
1069       注意: 
1070        需要 math.h
1071       源程序: 
1072        float area3(float x1,float y1,float x2,float y2,float x3,float y3)
1073       {
1074           float a,b,c,p,s;
1075           a=sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
1076           b=sqrt((x1-x3)*(x1-x3)+(y1-y3)*(y1-y3));
1077           c=sqrt((x3-x2)*(x3-x2)+(y3-y2)*(y3-y2));
1078           p=(a+b+c)/2;
1079           s=sqrt(p*(p-a)*(p-b)*(p-c));
1080           return s;
1081       }
1082 
1083  
1084 3.两矢量间角度
1085       语法:result=angle(double x1, double y1, double x2, double y2);
1086       参数:
1087       x/y1~2:两矢量的坐标
1088       返回值:两的角度矢量
1089       注意: 
1090        返回角度为弧度制,并且以逆时针方向为正方向
1091        需要 math.h
1092       源程序: 
1093        #define PI 3.1415926
1094 
1095       double angle(double x1, double y1, double x2, double y2)
1096       {
1097           double dtheta,theta1,theta2; 
1098           theta1 = atan2(y1,x1);
1099           theta2 = atan2(y2,x2);
1100           dtheta = theta2 - theta1;
1101           while (dtheta > PI)
1102               dtheta -= PI*2;
1103           while (dtheta < -PI)
1104               dtheta += PI*2; 
1105           return(dtheta);
1106       }
1107 
1108  
1109 4.两点距离(2D、3D)
1110       语法:result=distance_2d(float x1,float x2,float y1,float y2);
1111       参数:
1112       x/y/z1~2:各点的x、y、z坐标
1113       返回值:两点之间的距离
1114       注意: 
1115        需要 math.h
1116       源程序: 
1117        float distance_2d(float x1,float x2,float y1,float y2) 
1118       {
1119           return(sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)));
1120       }
1121 
1122 
1123       float distance_3d(float x1,float x2,float y1,float y2,float z1,float z2)
1124       {
1125           return(sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)+(z1-z2)*(z1-z2)));
1126       }
1127 
1128  
1129 5.射向法判断点是否在多边形内部
1130       语法:result=insidepolygon(Point *polygon,int N,Point p);
1131       参数:
1132       *polygon:多边形顶点数组
1133       N:多边形顶点个数
1134       p:被判断点
1135       返回值:0:点在多边形内部;1:点在多边形外部
1136       注意: 
1137        若p点在多边形顶点或者边上,返回值不确定,需另行判断
1138        需要 math.h
1139       源程序: 
1140        #define MIN(x,y) (x < y ? x : y)
1141       #define MAX(x,y) (x > y ? x : y)
1142       typedef struct {
1143           double x,y;
1144       } Point;
1145       int insidepolygon(Point *polygon,int N,Point p)
1146       {
1147           int counter = 0;
1148           int i;
1149           double xinters;
1150           Point p1,p2;
1151           p1 = polygon[0];
1152           for (i=1;i<=N;i++) {
1153               p2 = polygon[i % N];
1154               if (p.y > MIN(p1.y,p2.y)) {
1155                   if (p.y <= MAX(p1.y,p2.y)) {
1156                       if (p.x <= MAX(p1.x,p2.x)) {
1157                           if (p1.y != p2.y) {
1158                               xinters = (p.y-p1.y)*(p2.x-p1.x)/(p2.y-p1.y)+p1.x;
1159                               if (p1.x == p2.x || p.x <= xinters)
1160                                   counter++;
1161                               }
1162                           }
1163                       }
1164                   }
1165                   p1 = p2;
1166               }
1167           if (counter % 2 == 0)
1168               return(OUTSIDE);
1169           else
1170               return(INSIDE);
1171       }
1172 
1173  
1174 6.判断点是否在线段上
1175       语法:result=Pointonline(Point p1,Point p2,Point p);
1176       参数:
1177       p1、p2:线段的两个端点
1178       p:被判断点
1179       返回值:0:点在不在线段上;1:点在线段上
1180       注意: 
1181        若p线段端点上返回1
1182        需要 math.h
1183       源程序: 
1184        #define MIN(x,y) (x < y ? x : y)
1185       #define MAX(x,y) (x > y ? x : y) 
1186       typedef struct {
1187       double x,y;
1188       } Point;
1189       int FC(double x1,double x2)
1190       {
1191           if (x1-x2<0.000002&&x1-x2>-0.000002) return 1; else return 0;
1192       }
1193 
1194 
1195       int Pointonline(Point p1,Point p2,Point p)
1196       {
1197           double x1,y1,x2,y2;
1198           x1=p.x-p1.x;
1199           x2=p2.x-p1.x;
1200           y1=p.y-p1.y;
1201           y2=p2.y-p1.y;
1202           if (FC(x1*y2-x2*y1,0)==0) return 0;
1203           if ((MIN(p1.x,p2.x)<=p.x&&p.x<=MAX(p1.x,p2.x))&&
1204                   (MIN(p1.y,p2.y)<=p.y&&p.y<=MAX(p1.y,p2.y)))
1205               return 1; else return 0;
1206       }
1207 
1208  
1209 7.判断两线段是否相交
1210       语法:result=lineintersect(Point p1,Point p2,Point p3,Point p4);
1211       参数:
1212       p1~4:两条线段的四个端点
1213       返回值:0:两线段不相交;1:两线段相交;2两线段首尾相接
1214       注意: 
1215        p1!=p2;p3!=p4;
1216       源程序: 
1217        #define MIN(x,y) (x < y ? x : y)
1218       #define MAX(x,y) (x > y ? x : y) 
1219       typedef struct {
1220           double x,y;
1221       } Point;
1222       int lineintersect(Point p1,Point p2,Point p3,Point p4)
1223       {
1224           Point tp1,tp2,tp3;
1225           if 
1226       ((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))
1227               return 2;
1228       //快速排斥试验
1229           if 
1230       ((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))||
1231                   
1232       (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)))
1233               ;else return 0;
1234       //跨立试验
1235           tp1.x=p1.x-p3.x;
1236           tp1.y=p1.y-p3.y;
1237           tp2.x=p4.x-p3.x;
1238           tp2.y=p4.y-p3.y;
1239           tp3.x=p2.x-p3.x;
1240           tp3.y=p2.y-p3.y;
1241           if ((tp1.x*tp2.y-tp1.y*tp2.x)*(tp2.x*tp3.y-tp2.y*tp3.x)>=0) return 1; 
1242       else return 0;
1243       }
1244 
1245  
1246 8.判断线段与直线是否相交
1247       语法:result=lineintersect(Point p1,Point p2,Point p3,Point p4);
1248       参数:
1249       p1、p2:线段的两个端点
1250       p3、p4:直线上的两个点
1251       返回值:0:线段直线不相交;1:线段和直线相交
1252       注意: 
1253        如线段在直线上,返回 1
1254       源程序: 
1255        typedef struct {
1256           double x,y;
1257       } Point;
1258       int lineintersect(Point p1,Point p2,Point p3,Point p4)
1259       {
1260           Point tp1,tp2,tp3;
1261           tp1.x=p1.x-p3.x;
1262           tp1.y=p1.y-p3.y;
1263           tp2.x=p4.x-p3.x;
1264           tp2.y=p4.y-p3.y;
1265           tp3.x=p2.x-p3.x;
1266           tp3.y=p2.y-p3.y;
1267           if ((tp1.x*tp2.y-tp1.y*tp2.x)*(tp2.x*tp3.y-tp2.y*tp3.x)>=0) return 1; 
1268       else return 0;
1269       }
1270 
1271  
1272 9.点到线段最短距离
1273       语法:result=mindistance(Point p1,Point p2,Point q);
1274       参数:
1275       p1、p2:线段的两个端点
1276       q:判断点
1277       返回值:点q到线段p1p2的距离
1278       注意: 
1279        需要 math.h
1280       源程序: 
1281        #define MIN(x,y) (x < y ? x : y)
1282       #define MAX(x,y) (x > y ? x : y)
1283       typedef struct {
1284           double x,y;
1285       } Point;
1286       double mindistance(Point p1,Point p2,Point q)
1287       {
1288           int flag=1;
1289           double k;
1290           Point s;
1291           if (p1.x==p2.x) {s.x=p1.x;s.y=q.y;flag=0;}
1292           if (p1.y==p2.y) {s.x=q.x;s.y=p1.y;flag=0;}
1293           if (flag)
1294               {
1295               k=(p2.y-p1.y)/(p2.x-p1.x);
1296               s.x=(k*k*p1.x+k*(q.y-p1.y)+q.x)/(k*k+1);
1297               s.y=k*(s.x-p1.x)+p1.y;
1298               }
1299           if (MIN(p1.x,p2.x)<=s.x&&s.x<=MAX(p1.x,p2.x))
1300               return sqrt((q.x-s.x)*(q.x-s.x)+(q.y-s.y)*(q.y-s.y));
1301           else
1302               return 
1303       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)));
1304       }
1305 
1306  
1307 10.求两直线的交点
1308       语法:result=mindistance(Point p1,Point p2,Point q);
1309       参数:
1310       p1~p4:直线上不相同的两点
1311       *p:通过指针返回结果
1312       返回值:1:两直线相交;2:两直线平行
1313       注意: 
1314        如需要判断两线段交点,检验k和对应k1(注释中)的值是否在0~1之间,用在0~1之间的那个求交点
1315       源程序: 
1316        typedef struct {
1317          double x,y;
1318       } Point;
1319       int linecorss(Point p1,Point p2,Point p3,Point p4,Point *p)
1320       {
1321          double k;
1322          if ((p4.y-p3.y)*(p2.x-p1.x)-(p4.x-p3.x)*(p2.y-p1.y)==0) return 0;
1323         if ((p4.x-p3.x)*(p1.y-p3.y)-(p4.y-p3.y)*(p1.x-p3.x)==0&&
1324                  (p2.x-p1.x)*(p1.y-p3.y)-(p2.y-p1.y)*(p1.x-p3.x)==0) return 0;
1325           
1326       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));
1327       //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));
1328          (*p).x=p1.x+k*(p2.x-p1.x);
1329          (*p).y=p1.y+k*(p2.y-p1.y);
1330          return 1;
1331       }
1332 
1333  
1334 11.判断一个封闭图形是凹集还是凸集
1335       语法:result=convex(Point *p,int n);
1336       参数:
1337       *p:封闭曲线顶点数组
1338       n:封闭曲线顶点个数
1339       返回值:1:凸集;-1:凹集;0:曲线不符合要求无法计算
1340       注意: 
1341        默认曲线为简单曲线:无交叉、无圈
1342       源程序: 
1343        typedef struct {
1344           double x,y;
1345       } Point;
1346       int convex(Point *p,int n)
1347       {
1348           int i,j,k;
1349           int flag = 0;
1350           double z;
1351           if (n < 3)
1352               return(0);
1353           for (i=0;i<n;i++) {
1354               j = (i + 1) % n;
1355               k = (i + 2) % n;
1356               z = (p[j].x - p[i].x) * (p[k].y - p[j].y);
1357               z -= (p[j].y - p[i].y) * (p[k].x - p[j].x);
1358               if (z < 0)
1359                   flag |= 1;
1360               else if (z > 0)
1361                   flag |= 2;
1362               if (flag == 3)
1363                   return1; //CONCAVE
1364               }
1365           if (flag != 0)
1366               return 1; //CONVEX
1367           else
1368           return 0;
1369       }
1370 
1371  
1372 12.Graham扫描法寻找凸包
1373       语法:Graham_scan(Point PointSet[],Point ch[],int n,int &len);
1374       参数:
1375       PointSet[]:输入的点集
1376       ch[]:输出的凸包上的点集,按照逆时针方向排列
1377       n:PointSet中的点的数目
1378       len:输出的凸包上的点的个数
1379       返回值:null
1380       源程序: 
1381        struct Point{
1382           float x,y;
1383       }; 
1384       float multiply(Point p1,Point p2,Point p0)
1385       {
1386           return((p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y)); 
1387       }
1388       float distance(Point p1,Point p2)
1389       {
1390           return(sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y))); 
1391       }
1392       void Graham_scan(Point PointSet[],Point ch[],int n,int &len)
1393       {
1394           int i,j,k=0,top=2;
1395           Point tmp;
1396 
1397          for(i=1;i<n;i++)
1398           if 
1399       ((PointSet[i].y<PointSet[k].y)||((PointSet[i].y==PointSet[k].y)&&(PointSet[i].x<PointSet[k].x)))
1400           k=i;
1401           tmp=PointSet[0];
1402           PointSet[0]=PointSet[k];
1403           PointSet[k]=tmp; 
1404           for (i=1;i<n-1;i++)
1405               {
1406               k=i;
1407               for (j=i+1;j<n;j++)
1408                   if ( (multiply(PointSet[j],PointSet[k],PointSet[0])>0) ||
1409                            ((multiply(PointSet[j],PointSet[k],PointSet[0])==0)
1410                                
1411       &&(distance(PointSet[0],PointSet[j])<distance(PointSet[0],PointSet[k])))   
1412       )
1413                       k=j;
1414               tmp=PointSet[i];
1415               PointSet[i]=PointSet[k];
1416               PointSet[k]=tmp;
1417               }
1418           ch[0]=PointSet[0];
1419           ch[1]=PointSet[1];
1420           ch[2]=PointSet[2]; 
1421           for (i=3;i<n;i++)
1422               {
1423               while (multiply(PointSet[i],ch[top],ch[top-1])>=0) top--;
1424               ch[++top]=PointSet[i];
1425               }
1426           len=top+1;
1427       }
1428 
1429  
1430 13.求两条线段的交点
1431       语法:Result=IntersectPoint (Point p1,Point p2,Point p3,Point p4,Point &p);
1432       参数:
1433       P1~P4:两条线断4个端点
1434       P:线段交点
1435       返回值:如果两条线段平行无交点,返回 0,否则返回 1
1436       源程序: 
1437        struct Point{
1438           float x,y;
1439       }; 
1440 
1441       int IntersectPoint (Point p1,Point p2,Point p3,Point p4,Point &p)
1442       {
1443       float a,b,c,d,e,f;
1444       a=p2.y-p1.y;
1445       b=p1.x-p2.x;
1446       c=p1.y*(p2.x-p1.x)+p1.x*(p2.y-p1.y);
1447       d=p4.y-p3.y;
1448       e=p3.x-p4.x;
1449       f=p3.y*(p4.x-p3.x)+p1.x*(p4.y-p3.y); 
1450       if (a*e==b*d)
1451           return 0;
1452       else
1453           {
1454           p.x=(e*c-b*f)/(b*d-a*e);
1455           p.y=(d*c-a*f)/(a*e-b*d);
1456           return 1;
1457           }
1458       }
1459 
1460  
1461 四、数论
1462 1.x的二进制长度
1463       语法:result=BitLength(int x);
1464       参数:
1465       x:测长的x
1466       返回值:x的二进制长度
1467       源程序: 
1468        int BitLength(int x)
1469       {
1470           int d = 0;
1471           while (x > 0) {
1472               x >>= 1;
1473               d++;
1474           }
1475           return d;
1476       }
1477 
1478 
1479 2.返回x的二进制表示中从低到高的第i位
1480       语法:result=BitAt(int x, int i);
1481       参数:
1482       x:十进制 x
1483       i:要求二进制的第i位
1484       返回值:返回x的二进制表示中从低到高的第i位
1485       注意: 
1486        最低位为第一位
1487       源程序: 
1488        int BitAt(int x, int i)
1489       {
1490           return ( x & (1 << (i-1)) );
1491       }
1492 
1493  
1494 3.模取幂运算
1495       语法:result=Modular_Expoent(int a,int b,int n);
1496       参数:
1497       a、b、n:a^b mod n 的对应参数
1498       返回值:a^b mod n 的值
1499       注意: 
1500        需要BitLength和BitAt
1501       源程序: 
1502        int Modular_Expoent(int a,int b,int n)
1503       {
1504           int i, y=1;
1505           for (i = BitLength(b); i > 0; i--)
1506               { 
1507               y = (y*y)%n;
1508               if (BitAt(b,i) > 0) 
1509               y = (y*a)%n;
1510               }
1511           return y;
1512       }
1513 
1514  
1515 4.求解模线性方程
1516       语法:result=modular_equation(int a,int b,int n);
1517       参数:
1518       a、b、n:ax=b (mod n) 的对应参数
1519       返回值:方程的解
1520       源程序: 
1521        int ext_euclid(int a,int b,int &x,int &y)  //求gcd(a,b)=ax+by
1522       {
1523           int t,d;
1524           if (b==0) {x=1;y=0;return a;}
1525           d=ext_euclid(b,a %b,x,y);
1526           t=x;
1527           x=y;
1528           y=t-a/b*y;
1529           return d;
1530       }
1531 
1532       void modular_equation(int a,int b,int n)
1533       {
1534           int e,i,d;
1535           int x,y;
1536           d=ext_euclid(a,n,x,y);
1537           if (b%d>0)
1538              printf("No answer!\n");
1539           else
1540               {
1541              e=(x*(b/d))%n;
1542               for (i=0;i<d;i++)
1543                   printf("The %dth answer is : %ld\n",i+1,(e+i*(n/d))%n); 
1544               }
1545       }
1546 
1547  
1548 5.求解模线性方程组(中国余数定理)
1549       语法:result=Modular_Expoent(int a,int b,int n);
1550       参数:
1551       B[]、W[]:a=B[] (mod W[]) 的对应参数
1552       返回值:a 的值
1553       注意: 
1554        其中W[],B[]已知,W[i]>0且W[i]与W[j]互质, 求a
1555       源程序: 
1556        int ext_euclid(int a,int b,int &x,int &y)  //求gcd(a,b)=ax+by
1557       {
1558           int t,d;
1559           if (b==0) {x=1;y=0;return a;}
1560           d=ext_euclid(b,a %b,x,y);
1561           t=x;
1562           x=y;
1563           y=t-a/b*y;
1564           return d;
1565       }
1566 
1567 
1568       int China(int B[],int W[],int k)
1569       {
1570          int i;
1571           int d,x,y,a=0,m,n=1;
1572           for (i=0;i<k;i++)
1573               n*=W[i];
1574           for (i=0;i<k;i++)
1575              {
1576              m=n/W[i];
1577               d=ext_euclid(W[i],m,x,y);
1578               a=(a+y*m*B[i])%n;
1579               }
1580           if (a>0) return a;
1581           else return(a+n);
1582       }
1583 
1584  
1585 6.筛法素数产生器
1586       语法:result=prime(int a[],int n);
1587       参数:
1588       a[]:用于返回素数的数组
1589       n:产生n以内的素数,按升序放入a[]中
1590       返回值:n以内素数的个数
1591       注意: 
1592        其中W[],B[]已知,W[i]>0且W[i]与W[j]互质, 求a
1593       源程序: 
1594        int prime(int a[],int n)
1595       {
1596           int i,j,k,x,num,*b;
1597           n++;
1598           n/=2;
1599           b=new int[(n+1)*2];
1600           a[0]=2;a[1]=3;num=2;
1601           for(i=1;i<=2*n;i++)
1602               b[i]=0;
1603           for(i=3;i<=n;i+=3)
1604               for(j=0;j<2;j++)
1605                   {
1606                   x=2*(i+j)-1;
1607                   while(b[x]==0)
1608                       {
1609                       a[num++]=x;
1610                       for(k=x;k<=2*n;k+=x)
1611                           b[k]=1;
1612                       }
1613                   }
1614           return num;
1615       }
1616 
1617  
1618 7.判断一个数是否素数
1619       语法:result=comp(int n);
1620       参数:
1621       n:判断n是否素数
1622       返回值:素数返回1,否则返回0
1623       源程序: 
1624        //传统方法
1625       int comp(int n){ 
1626          if(n<2)return 0; 
1627          if(n%2==0)return 0; 
1628          for(int i=3;i<=sqrt(n);i+=2) if(n%i==0) return 0; 
1629          return 1; 
1630       }
1631        
1632       //大数素数判定,(1/4)^K出错概率
1633       int powermod(int a,int b,int n)
1634       {//get (a^b)%n 
1635          i64 d=1, t=a; 
1636          while(b>0){ 
1637             if(t==1)return d; 
1638             if(b%2==1)d=(t*d)%n; 
1639             b/=2; t=(t*t)%n; 
1640          } 
1641          return d; 
1642       } 
1643       int isprime(int n,int k){ 
1644                int a; 
1645          while(k--){ 
1646                         a=rand(); 
1647                         a%=n-3; a+=2; 
1648             if(powermod(k+2,n-1,n)!=1)return 0; 
1649          } 
1650          return 1; 
1651       }
1652 
1653  
1654 8.求距阵最大和
1655       语法:result=maxsum2(int n);
1656       参数:
1657       a:距阵
1658       n,m:距阵行列数
1659       返回值:一维,二维距阵最大和
1660       源程序: 
1661        int a[101][101]; 
1662       int maxsum(int a[],int n)//一维最大串 
1663       { 
1664           int sum=-10000000,b=0; 
1665           int i; 
1666           for(i=0;i<n;i++) 
1667               { 
1668         if (b>0) 
1669          b+=a[i]; 
1670         else 
1671          b=a[i]; 
1672         if(b>sum) 
1673          sum=b; 
1674         } 
1675        return sum; 
1676       } 
1677       int maxsum2(int m,int n)//二维最大串 
1678       { 
1679        int sum = -10000000; 
1680        int i,j,k,max; 
1681        int* b = new int[n+1]; 
1682        for (i=0;i<m;i++) 
1683         { 
1684         for(k=0;k<n;k++) 
1685          b[k]=a[i][k]; 
1686         max = maxsum(b,n);//第i列的一维最大串 
1687         if(max>sum) 
1688          sum=max; 
1689         for(j=i+1;j<m;j++) 
1690          { 
1691          for (k=0;k<=n;k++)b[k]+=a[j][k]; 
1692          max = maxsum(b,n);//类似maxsum,通过每列相加求二维最大串 
1693          if(max>sum)sum=max; 
1694          } 
1695         } 
1696        delete []b; 
1697        return sum; 
1698       } 
1699 
1700  
1701 8.求一个数每一位相加之和
1702       语法:result=digadd(int n)
1703       参数:
1704       n:待求数字
1705       返回值:各数字之和
1706       源程序: 
1707        int digadd(int n)
1708       {
1709       int i=0,k=0;
1710       while(i=n%10,n/=10)  k+=i;
1711       return k+i;
1712       }
1713 
1714  
1715 10.质因数分解
1716       语法:result=int reduce(int prime[],int pn,int n,int rest[])
1717       参数:
1718       Prime[]:素数表,至少需要达到sqrt(n)
1719       pn:素数表的元素个数
1720       N:待分解的数
1721       Rest:分解结果,按照升序排列
1722       返回值:分解因子个数
1723       源程序: 
1724        int reduce(int prime[],int pn,int n,int rest[])
1725       {
1726       int i,k=0;
1727       for(i=0;i<pn;i++)
1728            {
1729            if (n==1) break;
1730            if (prime[i]*prime[i]>n) {rest[k++]=n;break;}
1731            while(n%prime[i]==0)
1732                {
1733                n/=prime[i];
1734                rest[k++]=prime[i];
1735                }
1736            }
1737       return k;
1738       }
1739 
1740  
1741 11.高斯消元法解线性方程组
1742       语法:gauss(int n,double ** a)
1743       参数:
1744       N:变量个数
1745       Rest:变量系数行列式
1746       源程序: 
1747        void gauss(int n,double **a)
1748       {
1749        int i, j, k;
1750        double client, temp = 0.0;
1751        
1752        for(k = 0; k < n - 1; k++)
1753         for(i = k + 1; i < n; i++)
1754         {
1755          client = a[i][k]/a[k][k];
1756          for(j = k + 1; j < n; j++)
1757           a[i][j] = a[i][j] - client * a[k][j];
1758          a[i][n] = a[j - 1][n] - client * a[k][n]; 
1759         }
1760        a[n - 1][n] = a[n - 1][n]/a[n - 1][n - 1];
1761        for(i = n - 2; i >= 0; i--)
1762        {
1763         for (j = i + 1; j < n; j++)
1764          temp += a[i][j] * a[j][n];
1765         a[i][n] = (a[i][n] - temp) / a[i][i];
1766        }
1767       }
1768        
1769       //打印
1770       //for(i = 0; i < n; i++)
1771       // printf("X%d = %lf\n", i + 1, a[i][n]);
1772 
1773  
1774 五、图论
1775 1.Prim算法求最小生成树
1776       语法:prim(Graph G,int vcount,int father[]);
1777       参数:
1778       G:图,用邻接矩阵表示
1779       vcount:表示图的顶点个数
1780       father[]:用来记录每个节点的父节点
1781       返回值:null
1782       注意: 
1783        常数max_vertexes为图最大节点数
1784        常数infinity为无穷大
1785       源程序: 
1786        #define infinity 1000000
1787       #define max_vertexes 5 
1788 
1789       typedef int Graph[max_vertexes][max_vertexes];
1790 
1791       void prim(Graph G,int vcount,int father[])
1792       {
1793           int i,j,k;
1794           int lowcost[max_vertexes],closeset[max_vertexes],used[max_vertexes];
1795           for (i=0;i<vcount;i++)
1796               {
1797               lowcost[i]=G[0][i];
1798               closeset[i]=0; 
1799               used[i]=0;
1800               father[i]=-1; 
1801               }
1802           used[0]=1; 
1803           for (i=1;i<vcount;i++)
1804               {
1805               j=0;
1806               while (used[j]) j++;
1807               for (k=0;k<vcount;k++)
1808                   if ((!used[k])&&(lowcost[k]<lowcost[j])) j=k;
1809               father[j]=closeset[j]; 
1810               used[j]=1;
1811               for (k=0;k<vcount;k++)
1812                   if (!used[k]&&(G[j][k]<lowcost[k]))
1813                       { lowcost[k]=G[j][k];
1814                       closeset[k]=j; }
1815               }
1816       }
1817 
1818 
1819 2.Dijkstra算法求单源最短路径
1820       语法:result=Dijkstra(Graph G,int n,int s,int t, int path[]);
1821       参数:
1822       G:图,用邻接矩阵表示
1823       n:图的顶点个数
1824       s:开始节点
1825       t:目标节点
1826       path[]:用于返回由开始节点到目标节点的路径
1827       返回值:最短路径长度
1828       注意: 
1829        输入的图的权必须非负
1830        顶点标号从0开始
1831        用如下方法打印路径:
1832           i=t;
1833           while (i!=s)
1834               {
1835               printf("%d<--",i+1);
1836               i=path[i];
1837               }
1838           printf("%d\n",s+1); 
1839       源程序: 
1840        int Dijkstra(Graph G,int n,int s,int t, int path[])
1841       {
1842           int i,j,w,minc,d[max_vertexes],mark[max_vertexes];
1843           for (i=0;i<n;i++) mark[i]=0;
1844           for (i=0;i<n;i++)
1845               { d[i]=G[s][i];
1846               path[i]=s; }
1847           mark[s]=1;path[s]=0;d[s]=0;
1848           for (i=1;i<n;i++)
1849               {
1850              minc=infinity;
1851               w=0;
1852               for (j=0;j<n;j++)
1853                   if ((mark[j]==0)&&(minc>=d[j])) {minc=d[j];w=j;}
1854               mark[w]=1;
1855               for (j=0;j<n;j++)
1856               if ((mark[j]==0)&&(G[w][j]!=infinity)&&(d[j]>d[w]+G[w][j]))
1857                   { d[j]=d[w]+G[w][j];
1858                   path[j]=w; }
1859               }
1860           return d[t];
1861       }
1862 
1863  
1864 3.Bellman-ford算法求单源最短路径
1865       语法:result=Bellman_ford(Graph G,int n,int s,int t,int path[],int success);
1866       参数:
1867       G:图,用邻接矩阵表示
1868       n:图的顶点个数
1869       s:开始节点
1870       t:目标节点
1871       path[]:用于返回由开始节点到目标节点的路径
1872       success:函数是否执行成功
1873       返回值:最短路径长度
1874       注意: 
1875        输入的图的权可以为负,如果存在一个从源点可达的权为负的回路则success=0
1876        顶点标号从0开始
1877        用如下方法打印路径:
1878           i=t;
1879           while (i!=s)
1880               {
1881               printf("%d<--",i+1);
1882               i=path[i];
1883               }
1884           printf("%d\n",s+1); 
1885       源程序: 
1886        int Bellman_ford(Graph G,int n,int s,int t,int path[],int success)
1887       {
1888           int i,j,k,d[max_vertexes];
1889           for (i=0;i<n;i++) {d[i]=infinity;path[i]=0;}
1890           d[s]=0;
1891           for (k=1;k<n;k++)
1892               for (i=0;i<n;i++)
1893                   for (j=0;j<n;j++)
1894                       if (d[j]>d[i]+G[i][j]) {d[j]=d[i]+G[i][j];path[j]=i;}
1895           success=0;
1896           for (i=0;i<n;i++)
1897               for (j=0;j<n;j++)
1898                   if (d[j]>d[i]+G[i][j]) return 0;
1899           success=1;
1900           return d[t];
1901       }
1902 
1903  
1904 4.Floyd-Warshall算法求每对节点间最短路径
1905       语法:Floyd_Washall(Graph G,int n,Graph D,Graph P);
1906       参数:
1907       G:图,用邻接矩阵表示
1908       n:图的顶点个数
1909       D:D[i,j]表示从i到j的最短距离
1910       P:P[i,j]表示从i到j的最短路径上j 的父节点 
1911       自定义:MaxN;
1912       返回值:null
1913 注意:此算法允许图中带有负权的弧,但不允许有路径长度为负值的回路.
1914       源程序: 
1915        void Floyd(int G[][MaxN],int n,int D[][MaxN],int P[][MaxN])
1916       {
1917           int i,j,k;
1918           for (i=0;i<n;i++)
1919               for (j=0;j<n;j++)
1920                   { D[i][j]=G[i][j];
1921                       P[i][j]=i; }
1922           for (i=0;i<n;i++) { D[i][i]=0;P[i][i]=0; }
1923           for (k=0;k<n;k++)
1924               for (i=0;i<n;i++)
1925                   for (j=0;j<n;j++)
1926                       if (D[i][j]>D[i][k]+D[k][j])
1927                           { D[i][j]=D[i][k]+D[k][j];
1928                               P[i][j]=P[k][j]; }
1929       }
1930     void Floyd(int n,int D[][MaxN])            //G不用再输出的情况下.
1931       {
1932           int i,j,k;
1933           for (i=0;i<n;i++) { D[i][i]=0; }
1934           for (k=0;k<n;k++)
1935               for (i=0;i<n;i++)
1936                   for (j=0;j<n;j++)
1937                       if (D[i][j]>D[i][k]+D[k][j])
1938                           { D[i][j]=D[i][k]+D[k][j];
1939                                }
1940       }
1941  
1942 5.解欧拉图
1943       语法:int Eular(int graph[8][8], int v, int *path)
1944       参数:
1945       graph:图,用邻接矩阵表示
1946       v:图的顶点个数
1947       path:D[i,j]表示从i到j的最短距离
1948       注意: 
1949        此函数会删除图中的边
1950       返回值:若找到欧拉回路则返回路径长度,否则返回-1
1951       源程序: 
1952        int Eular(int graph[8][8], int v, int *path)
1953       {
1954            int start,a,b,count=0, deg,i;
1955            int s[1000], sp=0;//栈,大小可根据需要改变     
1956        
1957            start=0;
1958            while(true)
1959            {
1960                a=start;
1961                s[sp++]=a;
1962                for(b=-1,i=0;i<v;i++) if (graph[i][a]&& a!=i) {b=i;break;}
1963                for(;b!=start&&b!=-1;)
1964                {
1965                     s[sp++]=b;
1966                     graph[a][b]=graph[b][a]=0;
1967                     a=b;
1968                     for(b=-1,i=0;i<v;i++) if (graph[i][a]&& a!=i) {b=i;break;}
1969                }
1970                if (b==-1) return(-1);//若找不到Eular回路返回-1
1971                s[sp++]=b;
1972                graph[a][b]=graph[b][a]=0;
1973            
1974                while(sp>0)
1975                {             
1976                     b=s[--sp];
1977                     for(i=0,deg=0;i<v;i++) if (graph[i][b]==1) {deg++; break;}
1978                     if (deg>0) break;
1979                     path[count++]=b;
1980                }
1981                if (sp==0) return(count);
1982                start=b;      
1983            }
1984        
1985       }
1986 
1987  
1988 六、排序/查找
1989 1.快速排序
1990       语法:quicksort(int l,int r,int b[]);
1991       参数:
1992       l:排序上界,开始时l=0
1993       r:排序下界,开始时r=数组元素个数
1994       b[]:被排序的元素
1995       返回值:null
1996       注意: 
1997        输出升序序列
1998       源程序: 
1999        void quicksort(int l,int r,int b[])
2000       {
2001           int i,j,x;
2002           if(l>=r) return;
2003           i=l;
2004           j=r;
2005           x=b[i];
2006           while(i!=j)
2007               {
2008               while(b[j]>x&&j>i) j--;
2009               if(i<j)
2010                   {
2011                   b[i]=b[j];
2012                   i++;
2013                   }
2014               while(b[i]<x&&j>i)i++;
2015                   if(i<j)
2016                       {
2017                       b[j]=b[i];
2018                       j--;
2019                       }
2020               }
2021           b[i]=x;
2022           quicksort(l,j-1,b);
2023           quicksort(i+1,r,b);
2024       }
2025 
2026 
2027 2.希尔排序
2028       语法:shellsort(int a[],int n);
2029       参数:
2030       n:数组元素个数
2031       a[]:待排序数组
2032       返回值:null
2033       注意: 
2034        输出升序序列
2035       源程序: 
2036        void shellsort(int a[],int n)
2037       {
2038           int i,j,g;
2039           int temp,k;
2040           g=n/2;
2041           while(g!=0)
2042               {
2043               for(i=g+1;i<=n;i++)
2044                   {
2045                   temp=a[i];
2046                   j=i-g;
2047                   while(j>0)
2048                       {
2049                       k=j+g;
2050                       if(a[j]<=a[k])
2051                           j=0;
2052                       else
2053                           {
2054                           temp=a[j];a[j]=a[k];a[k]=temp;
2055                           }
2056                       j=j-g;
2057                       }
2058                   }
2059               g=g/2;
2060               }
2061       }
2062 
2063  
2064 3.选择法排序
2065       语法:sort(int t[],int n);
2066       参数:
2067       t[]:待排序数组
2068       n:数组t[]元素的个数
2069       返回值:null
2070       注意: 
2071        输出升序序列
2072        小规模排序用
2073       源程序: 
2074        void sort(int t[],int n)
2075       {
2076          int i,j,k,temp;
2077           for (i=0;i<n;i++)
2078               {
2079               k=i;
2080               for (j=i;j<n;j++) if (t[j]<t[k]) k=j;
2081               temp=t[i];t[i]=t[k];t[k]=temp;
2082               }
2083       }
2084 
2085  
2086 4.二分查找
2087       语法:result=search_bin(int *t,int k);
2088       参数:
2089       t[]:待查找数组
2090       k:查找关键字
2091       返回值:如果k在t[]中存在,输出i:t[i]=k,否则输出-1
2092       注意: 
2093        要求查找数组是有序升序序列
2094       源程序: 
2095        int search_bin(int *t,int k)
2096       {
2097           int low=1,high=10,mid;
2098           while (low<=high)
2099               {
2100               mid=(low+high)/2;
2101               if (k==t[mid]) return mid;
2102               else if (k<t[mid]) high=mid-1;
2103               else low=mid+1;
2104               }
2105           return -1;
2106       }
2107 
2108  
2109 七、数据结构
2110 1.顺序队列
2111       源程序: 
2112        #define maxsize 100
2113       typedef struct
2114       {
2115           int data[maxsize];
2116           int front;
2117           int rear;
2118       } sqqueue; 
2119       int sqinit(sqqueue *p) //队列初始化
2120       {
2121           p->front=0;
2122           p->rear=0;
2123           return 1;
2124       }
2125       int enqueue(sqqueue *q, int e) //入队
2126       {
2127           if((q->rear+1)%maxsize==q->front)
2128               return 0;
2129           else
2130               q->data[q->rear]=e;
2131           q->rear=(q->rear+1)%maxsize;
2132           return 1;
2133       }
2134       int dequeue(sqqueue *q) //出队
2135       {
2136           int e;
2137           if (q->front==q->rear)
2138               return 0;
2139           e=q->data[q->front];
2140           q->front=(q->front+1)%maxsize;
2141           return e;
2142       }
2143       int empty(sqqueue *q)  //判空
2144       {
2145           int v;
2146           if (q->front==q->rear)
2147               v=1;
2148           else
2149               v=0;
2150            return v; 
2151       }
2152       int gethead(sqqueue *q)  //取得头元素
2153       {
2154           int e;
2155           if (q->front==q->rear) 
2156               e=-1;
2157           else
2158               e=q->data[q->front];
2159           return e;
2160       }
2161       void display(sqqueue *q) //显示所有元素
2162       {
2163           int s;
2164           s=q->front;
2165           printf("the sequeue is display:\n");
2166           if (q->front==q->rear)
2167               printf("the sequeue is empty!");
2168           else
2169               {
2170               while(s<q->rear)
2171                   {
2172                   printf("->%d", q->data[s]);
2173                   s=(s+1)%maxsize;
2174                   } 
2175           printf("\n");
2176       }
2177       }
2178       main(sqqueue *head)  //函数使用样例
2179       {
2180           int n,i,m,x,y,select,xq;
2181           printf("create a empty sequeue\n");
2182           sqinit(head);
2183           printf("please input the sequeue length:\n"); 
2184           scanf("%d",&n);
2185           for (i=0;i<n;i++)
2186               {
2187               printf("please input a sequeue value:\n");
2188               scanf("%d",&m);
2189               enqueue(head,m);
2190              }
2191           printf("head->rear:%d\n",head->rear);
2192           printf("head->front:%d\n",head->front);
2193           display(head);
2194           printf("select 1 **** enqueue() \n");
2195           printf("select 2 **** dequeue() \n");
2196           printf("select 3 **** empty () \n");
2197           printf("select 4 **** gethead() \n");
2198           printf("select 5 **** display() \n");
2199           printf("please select (1--5):");
2200           scanf("%d",&select);
2201           switch(select)
2202               {
2203               case 1:
2204                   { 
2205                   printf("please input a value :\n ");
2206                   scanf("%d",&x);
2207                   enqueue(head,x);
2208                   display(head);
2209                   break;
2210                   }
2211               case 2:
2212                   {
2213                   dequeue(head);
2214                   display(head);
2215                   break;
2216                   }
2217               case 3:
2218                   {
2219               if(empty(head))
2220                   printf("the sequeue is empty");
2221               else
2222                   printf("the sequeue is full");
2223                   }
2224               case 4:
2225                   {
2226                   y=gethead(head);
2227                   printf("output head value:%d\n",y);
2228                   break;
2229                   }
2230               case 5:
2231                   {
2232                   display(head);
2233                   break;
2234                   }
2235               }
2236           }
2237       } 
2238 
2239 
2240 2.顺序栈
2241       源程序: 
2242        #define m 100
2243       typedef struct
2244       {
2245           int stack[m];
2246           int top;
2247       } stackstru; 
2248       init(stackstru *s) /*装入栈*/
2249       {
2250           s->top=0;
2251           return 1;
2252       }
2253       int push(stackstru *s,int x) /*入栈操作*/
2254       {
2255           if (s->top==m)
2256               printf("the stack is overflow!\n");
2257           else
2258               {
2259               s->top=s->top+1;
2260               s->stack[s->top]=x;
2261               }
2262       }
2263       void display(stackstru *s) /*显示栈所有数据*/
2264       {
2265           if(s->top==0)
2266               printf("the stack is empty!\n");
2267           else
2268               {
2269               while(s->top!=0)
2270                   {
2271                   printf("%d->",s->stack[s->top]);
2272                   s->top=s->top-1;
2273                   }
2274               }
2275       }
2276       int pop(stackstru *s) /*出栈操作并返回被删除的那个记录*/
2277       {
2278           int y;
2279           if(s->top==0)
2280               printf("the stack is empty!\n");
2281           else
2282               {
2283               y=s->stack[s->top];
2284               s->top=s->top-1;
2285               return y;
2286               }
2287       }
2288 
2289       int gettop(stackstru *s) /*得到栈顶数*/
2290       { 
2291           int e;
2292           if(s->top==0)
2293               return 0;
2294           else 
2295               e=s->stack[s->top];
2296           return e;
2297       }
2298       main(stackstru *p) //函数使用演示
2299       {
2300           int n,i,k,h,x1,x2,select;
2301           printf("create a empty stack!\n");
2302           init(p);
2303           printf("input a stack length:\n");
2304           scanf("%d",&n);
2305           for(i=0;i<n;i++)
2306               {
2307               printf("input a stack value:\n");
2308               scanf("%d",&k);
2309               push(p,k);
2310               }
2311           printf("select 1:display()\n");
2312           printf("select 2:push()\n");
2313           printf("select 3:pop()\n");
2314           printf("select 4:gettop()\n");
2315           printf("input a your select(1-4):\n");
2316           scanf("%d",&select);
2317           switch(select)
2318               {
2319               case 1:
2320                   {
2321                   display(p);
2322                   break;
2323                   }
2324               case 2:
2325                   {
2326                   printf("input a push a value:\n");
2327                   scanf("%d",&h);
2328                   push(p,h);
2329                   display(p);
2330                   break;
2331                   }
2332               case 3:
2333                   {
2334                   x1=pop(p);
2335                   printf("x1->%d\n",x1);
2336                   display(p);
2337                   break;
2338                   }
2339               case 4:
2340                   {
2341                   x2=gettop(p);
2342                   printf("x2->%d",x2);
2343                   break;
2344                   }
2345               }
2346       }
2347 
2348  
2349 3.链表
2350       源程序: 
2351        # define null 0 
2352 
2353       typedef char ElemType; /* 字符型数据*/ 
2354 
2355       typedef struct LNode
2356       {
2357           ElemType data;
2358           struct LNode *next;
2359       };
2360 
2361       setnull(struct LNode **p);
2362       int length (struct LNode **p);
2363       ElemType get(struct LNode **p,int i);
2364       void insert(struct LNode **p,ElemType x,int i);
2365       int delete(struct LNode **p,int i);
2366       void display(struct LNode **p); 
2367       main()
2368       {
2369           struct LNode *head,*q; /*定义静态变量*/
2370           int select,x1,x2,x3,x4;
2371           int i,n; 
2372           int m,g;
2373           char e,y; 
2374 
2375           head=setnull(&head); /*建议链表并设置为空表*/
2376           printf("请输入数据长度: ");
2377           scanf("%d",&n);
2378           for(i=1;i<n;i++);
2379               {
2380               printf("将数据插入到单链表中: ");
2381               scanf("%d",&y);
2382               insert(&head,y,i);} /*插入数据到链表*/
2383               display(&head); /*显示链表所有数据*/
2384 
2385               printf("select 1 求长度 length()\n");
2386               printf("select 2 取结点 get()\n");
2387               printf("select 3 求值查找 locate()\n");
2388               printf("select 4 删除结点 delete()\n");
2389               printf("input your select: ");
2390               scanf("%d",&select); 
2391               switch(select)
2392                   {
2393                   case 1:
2394                       {
2395                       x1=length(&head);
2396                       printf("输出单链表的长度%d ",x1);
2397                       display(&head);
2398                       }break;
2399                   case 2:
2400                       {
2401                       printf("请输入要取得结点: ");
2402                       scanf("%d",&m);
2403                       x2=get(&head,m);
2404                       printf(x2);
2405                       display(&head);
2406                       }break;
2407                case 3:
2408                       {
2409                       printf("请输入要查找的数据: ");
2410                       scanf("%d",&e);
2411                       x3=locate(&head,e);
2412                       printf(x3);
2413                       display(&head);
2414                       }break;
2415                case 4:
2416                       {
2417                       printf("请输入要删除的结点: ");
2418                       scanf("%d",&g);
2419                       x4=delete(&head,g);
2420                       printf(x4);
2421                       display(&head);
2422                       }break;
2423                   }
2424               }
2425       }
2426 
2427       setnull(struct LNode **p)
2428       {
2429           *p=null;
2430       }
2431       int length (struct LNode **p)
2432       {
2433           int n=0;
2434           struct LNode *q=*p;
2435           while (q!=null)
2436               {
2437               n++;
2438               q=q->next;
2439               }
2440           return(n);
2441       }
2442       ElemType get(struct LNode **p,int i)
2443       {
2444           int j=1;
2445           struct LNode *q=*p;
2446           while (j<i&&q!=null)
2447               {
2448               q=q->next;
2449               j++;
2450               }
2451               if(q!=null)
2452                   return(q->data);
2453               else
2454                   printf("位置参数不正确!\n");
2455       }
2456       int locate(struct LNode **p,ElemType x)
2457           {
2458           int n=0;
2459           struct LNode *q=*p;
2460           while (q!=null&&q->data!=x)
2461               {
2462               q=q->next;
2463               n++;
2464               }
2465           if(q==null)
2466               return(-1);
2467           else
2468               return(n+1);
2469       }
2470       void insert(struct LNode **p,ElemType x,int i)
2471           {
2472           int j=1;
2473           struct LNode *s,*q;
2474           s=(struct LNode *)malloc(sizeof(struct LNode));
2475           s->data=x;
2476           q=*p;
2477           if(i==1)
2478               {
2479               s->next=q;
2480               p=s;
2481               }
2482           else
2483               {
2484               while(j<i-1&&q->next!=null)
2485                   {
2486                   q=q->next;
2487                   j++;
2488                   }
2489               if(j==i-1)
2490                   {
2491                   s->next=q->next;
2492                   q->next=s;
2493                   }
2494               else 
2495                   printf("位置参数不正确!\n");
2496               } 
2497       }
2498       int delete(struct LNode **p,int i)
2499       {
2500           int j=1;
2501           struct LNode *q=*p,*t;
2502           if(i==1)
2503               {
2504               t=q;
2505               *p=q->next;
2506               }
2507           else
2508               {
2509               while(j<i-1&&q->next!=null)
2510                   {
2511                   q=q->next;
2512                   j++;
2513                   }
2514               if(q->next!=null&&j==i-1)
2515                   {
2516                   t=q->next;
2517                   q->next=t->next;
2518                   }
2519               else 
2520                   printf("位置参数不正确!\n");
2521               }
2522           if(t=null) 
2523           free(t);
2524       }
2525       void display(struct LNode **p)
2526           { 
2527           struct LNode *q;
2528           q=*p;
2529           printf("单链表显示: ");
2530           if(q==null)
2531               printf("链表为空!");
2532           else if (q->next==null)
2533               printf("%c\n",q->data);
2534           else
2535               {
2536               while(q->next!=null)
2537                   {
2538                   printf("%c->",q->data);
2539                   q=q->next;
2540                   }
2541               printf("%c",q->data);
2542           }
2543           printf("\n");
2544       }
2545 
2546  
2547 4.链栈
2548       源程序: 
2549        # define null 0 
2550 
2551       typedef struct stacknode
2552       {
2553           int data;
2554           struct stacknode *next;
2555       } stacklink;
2556       typedef struct
2557       {
2558           stacklink *top;
2559           int stacksize;
2560           }stackk;
2561 
2562       initlink(stackk *s)
2563       {
2564          s->top=(stacklink *)malloc(sizeof(stacklink));
2565           s->top->data=0;
2566           s->top->next=null;
2567       } 
2568 
2569       int poplink(stackk *s)
2570       {
2571          stackk *p;int v;
2572           if(s->top->next==null) printf("the stackis empty\n");
2573           else
2574               {
2575               v=s->top->next->data;
2576                p=s->top->next;
2577                s->top=s->top->next;
2578               } 
2579           free(p);
2580           return v;
2581       }
2582       } 
2583       int pushlink(stackk *s,int x)
2584       {
2585          stackk *p;
2586           p=(stacklink *)malloc(sizeof(stacklink));
2587           p->data=x;
2588           p->next=s->top->next;
2589           s->top->next=p;
2590       }
2591       int gettop(stackk *s)
2592       {
2593          int e;
2594           if(s==null) printf("the stack is empty!\n");
2595           e=s->top->next->data;
2596           return e;
2597       }
2598 
2599       display(stackk *s)
2600       {
2601          stackk *p;
2602           p=s->top->next;
2603           printf("display the stacklink:\n");
2604           if (s->top=null) printf("the stacklink is empty!\n");
2605           else
2606              {
2607              while(p)
2608                   {
2609                  printf("->%d",p->data);
2610                   p=p->next;
2611                  }
2612               }
2613       }
2614 
2615       main(stacklink *p)
2616       {
2617          int n,k,i,select,h,x1,x2;
2618           printf("create a empty stacklink!\n");
2619           initlink(p);
2620           printf("input a stacklink length:\n");
2621           scanf("%d",&n);
2622           for (i=1;i<=n;i++)
2623               {printf("input a stacklink value:\n");
2624           scanf("%d",&k);
2625           pushlink(p,k);
2626               }
2627           printf("select 1:display()\n");
2628           printf("select 2:pushlink()\n");
2629           printf("select 3:poplink()\n");
2630           printf("select 4:gettop()\n");
2631           printf("input a your select(1-4):\n");
2632           scanf("%d",&select);
2633           switch(select)
2634               {case 1:
2635                    {display(p);break;}
2636               case 2:
2637                  {printf("input a push a value :\n");
2638                   scanf("%d",&h);
2639                   pushlink(p,h);
2640                   display(p);
2641                   break;}
2642               case 3:
2643                  {x1=poplink(p);printf("x1->%d\n",x1);
2644                   display(p);
2645                   break;}
2646               case 4:
2647                  {x2=gettop(p);printf("x2->%d",x2);
2648                   break;}
2649               }
2650       }
2651 
2652  
2653 5.二叉树
2654       源程序: 
2655        typedef struct bitnode
2656       {
2657           char data;
2658           struct bitnode *lchild, *rchild;
2659       }bitnode, *bitree; 
2660       void createbitree(t,n)
2661       bitnode ** t;
2662       int *n;
2663       {
2664           char x;
2665           bitnode *q;
2666           *n=*n+1;
2667           printf("\n Input %d DATA:",*n);
2668           x=getchar();
2669           if(x!='\n') getchar();
2670           if (x=='\n')
2671               return;
2672           q=(bitnode*)malloc(sizeof(bitnode));
2673           q->data=x;
2674           q->lchild=NULL;
2675           q->rchild=NULL;
2676           *t=q;
2677           printf(" This Address is: %o, Data is: %c,\n Left Pointer is: %o, 
2678       Right Pointer is: %o",q,q->data,q->lchild,q->rchild);
2679           createbitree(&q->lchild,n);
2680           createbitree(&q->rchild,n);
2681           return;
2682       }
2683 
2684       void visit(e)
2685       bitnode *e;
2686       {
2687           printf(" Address: %o, Data: %c, Left Pointer: %o, Right Pointer: 
2688       %o\n",e,e->data,e->lchild,e->rchild);
2689       }
2690 
2691       void preordertraverse(t)
2692       bitnode *t;
2693       {
2694           if(t)
2695               {
2696               visit(t);
2697               preordertraverse(t->lchild);
2698               preordertraverse(t->rchild);
2699               return ;
2700               }
2701          else
2702            return ;
2703       }
2704       void countleaf(t,c)
2705       bitnode *t;
2706       int *c;
2707       {
2708           if(t!=NULL)
2709               {
2710               if (t->lchild==NULL && t->rchild==NULL)
2711               {*c=*c+1;
2712               }
2713           countleaf(t->lchild,c);
2714           countleaf(t->rchild,c);
2715       }
2716       return;
2717       }
2718       int treehigh(t)
2719       bitnode *t;
2720       {
2721          int lh,rh,h;
2722           if(t==NULL)
2723               h=0;
2724           else
2725              {
2726               lh=treehigh(t->lchild);
2727               rh=treehigh(t->rchild);
2728               h=(lh>rh ? lh:rh)+1;
2729               }
2730           return h;
2731       }
2732 
2733       main()
2734       {
2735           bitnode *t; int count=0;
2736           int n=0;
2737          printf("\n Please input TREE Data:\n");
2738           createbitree(&t,&n);
2739          printf("\n This is TREE struct: \n");
2740           preordertraverse(t);
2741          countleaf(t,&count);
2742           printf("\n This TREE has %d leaves ",count);
2743          printf(" , High of The TREE is: %d\n",treehigh(t));
2744       }
2745 
2746  
2747 八、高精度运算专题
2748 1.专题函数说明
2749       说明: 
2750        本栏为本专题所有程序的公用部分,调用本专题任何一个程序必须加上本栏的代码
2751        input/print为高精度数输入输出,调用格式为input(hp HightPoint,"123456")/print(hp 
2752       HighPoint)
2753        本栏为纯C++代码
2754       源程序: 
2755        #include <iostream> 
2756       using namespace std;
2757       #define maxsize 100
2758       struct hp
2759       {
2760          int len;
2761          int s[maxsize+1];
2762       };
2763 
2764       void input(hp &a,string str)
2765       {
2766          int i;
2767          while(str[0]=='0' && str.size()!=1)
2768             str.erase(0,1);
2769          a.len=(int)str.size();
2770          for(i=1;i<=a.len;++i)
2771             a.s[i]=str[a.len-i]-48;
2772          for (i=a.len+1;i<=maxsize;++i)
2773             a.s[i]=0;
2774       }
2775       void print(const hp &y)
2776       {
2777       int i;
2778       for(i=y.len;i>=1;i--)
2779          cout<<y.s[i];
2780       cout<<endl;
2781       }
2782 
2783  
2784 2.高精度数比较
2785       语法:int result=compare(const hp &a,const hp &b);
2786       参数:
2787       a,b:进行比较的高精度数字
2788       返回值:比较结果,a>b返回正数,a=b返回0,a<b返回负数
2789       源程序: 
2790        int compare(const hp &a,const hp &b)
2791       {
2792       int len;
2793       if(a.len>b.len)
2794          len=a.len;
2795       else
2796          len=b.len;
2797       while(len>0 && a.s[len]==b.s[len]) len--;
2798       if(len==0)
2799          return 0;
2800       else
2801          return a.s[len]-b.s[len];
2802       } 
2803 
2804  
2805 3.高精度数加法
2806       语法:plus(const hp &a,const hp &b,hp &c);
2807       参数:
2808       a,b:进行加法的高精度数字
2809       返回值:返回相加结果到c中
2810       源程序: 
2811        void plus(const hp &a,const hp &b,hp &c)
2812       {
2813       int i,len;
2814       for(i=1;i<=maxsize;i++) c.s[i]=0;
2815       if(a.len>b.len) len=a.len;
2816       else len=b.len;
2817       for(i=1;i<=len;i++)
2818          {
2819          c.s[i]+=a.s[i]+b.s[i];
2820          if(c.s[i]>=10)
2821             {
2822             c.s[i]-=10;
2823             c.s[i+1]++;
2824             }
2825          }
2826       if(c.s[len+1]>0) len++;
2827          c.len=len;
2828       }
2829 
2830  
2831 4.高精度数减法
2832       语法:subtract(const hp &a,const hp &b,hp &c);
2833       参数:
2834       a,b:进行减法的高精度数字,a是被减数,b是减数,不支持负数
2835       返回值:返回结果到c中
2836       源程序: 
2837        void subtract(const hp &a,const hp &b,hp &c)
2838       {
2839       int i,len;
2840       for(i=1;i<=maxsize;i++) c.s[i]=0;
2841       if(a.len>b.len) len=a.len;
2842       else len=b.len;
2843       for(i=1;i<=len;i++)
2844          {
2845          c.s[i]+=a.s[i]-b.s[i];
2846          if(c.s[i]<0)
2847             {
2848             c.s[i]+=10;
2849             c.s[i+1]--;
2850             }
2851          }
2852       while(len>1&&c.s[len]==0) len--;
2853          c.len=len;
2854       }
2855 
2856  
2857 5.高精度乘10 
2858       语法:multiply10(hp &a);
2859       参数:
2860       a:进行乘法的高精度数字
2861       返回值:返回结果到 a 中
2862       源程序: 
2863        void multiply10(hp &a)
2864       {
2865       int i;
2866       for(i=a.len;i>=1;i--)
2867          a.s[i+1]=a.s[i];
2868       a.s[1]=0;
2869       a.len++;
2870       while(a.len>1&&a.s[a.len]==0) a.len--;
2871       }
2872 
2873  
2874 6.高精度乘单精度
2875       语法:multiply(const hp &a,int b,hp &c);
2876       参数:
2877       a:进行乘法的高精度数字
2878       b:进行乘法的单精度数字
2879       返回值:返回结果到 c 中
2880       源程序: 
2881        void multiply(const hp &a,int b,hp &c)
2882       {
2883       int i,len;
2884       for(i=1;i<=maxsize;i++) c.s[i]=0;
2885       len=a.len;
2886       for(i=1;i<=len;i++)
2887          {
2888          c.s[i]+=a.s[i]*b;
2889          c.s[i+1]+=c.s[i]/10;
2890          c.s[i]%=10;
2891          }
2892       len++;
2893       while(c.s[len]>=10)
2894          {
2895          c.s[len+1]+=c.s[len]/10;
2896          c.s[len]%=10;
2897          len++;
2898          }
2899       while(len>1&&c.s[len]==0) len--;
2900       c.len=len;
2901       }
2902 
2903  
2904 7.高精度乘高精度
2905       语法:multiplyh(const hp &a,const hp &b,hp &c);
2906       参数:
2907       a,b:进行乘法的高精度数字
2908       返回值:返回结果到 c 中
2909       源程序: 
2910        void multiplyh(const hp &a,const hp &b,hp &c)
2911       {
2912       int i,j,len;
2913       for(i=1;i<=maxsize;i++) c.s[i]=0;
2914       for(i=1;i<=a.len;i++)
2915       for(j=1;j<=b.len;j++)
2916          {
2917          c.s[i+j-1]+=a.s[i]*b.s[j];
2918          c.s[i+j]+=c.s[i+j-1]/10;
2919          c.s[i+j-1]%=10;
2920          }
2921       len=a.len+b.len+1;
2922       while(len>1&&c.s[len]==0) len--;
2923       c.len=len;
2924       }
2925 
2926  
2927 8.高精度除单精度
2928       语法:divide(const hp &a,int b,hp &c,int &d);
2929       参数:
2930       a:进行除法的高精度数字
2931       返回值:返回商到 c 中,余数到 d 中
2932       源程序: 
2933        void divide(const hp &a,int b,hp &c,int &d)
2934       {
2935       int i,len;
2936       for(i=1;i<=maxsize;i++) c.s[i]=0;
2937       len=a.len;
2938       d=0;
2939       for(i=len;i>=1;i--)
2940          {
2941          d=d*10+a.s[i];
2942          c.s[i]=d/b;
2943          d%=b;
2944          }
2945       while(len>1&&c.s[len]==0) len--;
2946       c.len=len;
2947       }
2948 
2949  
2950 9.高精度除高精度
2951       语法:divideh(const hp &a,const hp &b,hp &c,hp &d);
2952       参数:
2953       a,b:进行除法的高精度数字
2954       返回值:返回商到 c 中,余数到 d 中
2955       注意: 
2956        需要compare、multiply10、subtract
2957       源程序: 
2958        void divideh(const hp &a,const hp &b,hp &c,hp &d)
2959       {
2960       hp e;
2961       int i,len;
2962       for(i=1;i<=maxsize;i++)
2963          {
2964          c.s[i]=0;
2965          d.s[i]=0;
2966          }
2967       len=a.len;
2968       d.len=1;
2969       for(i=len;i>=1;i--)
2970          {
2971          multiply10(d);
2972          d.s[1]=a.s[i];
2973          while(compare(d,b)>=0)
2974             {
2975             subtract(d,b,e);
2976             d=e;
2977             c.s[i]++;
2978             }
2979          }
2980       while(len>1&&c.s[len]==0) len--;
2981       c.len=len;
2982       } 
2983 
2984  
2985  
2986 九、标准模板库的使用
2987 1.计算求和
2988 TYPE accumulate( iterator start, iterator end, TYPE val );
2989 
2990 The accummulate() function computes the sum of val and all of the elements in the range [start,end).
2991 #include <iostream>
2992 #include <vector>
2993 ////////////////////////////////////////////////////////////////用法1
2994 #include <numeric>
2995 using namespace std;
2996 int main () 
2997 {
2998      int arr[] = { 1,2,3,4,5 };
2999      vector<int> v(arr,arr+5);
3000      
3001      // 1+2+3+4+5 and + 0
3002 
3003      int sum = accumulate(v.begin(), v.end(), 0, );
3004 int sum
3005      cout << "sum = " << sum << endl;
3006      return 0;
3007 }
3008 //OUTPUT:
3009 // sum = 15
3010 
3011 /////////////////////////////////////////////////////////////////////用法2
3012 #include <iostream>
3013 #include <vector>
3014 #include <numeric>
3015 using namespace std;
3016 int mul(int x,int y)
3017 {
3018 return x*y;
3019 }
3020 int main () 
3021 {
3022      int arr[] = { 1,2,3,4,5 };
3023      vector<int> v(arr,arr+5);
3024      
3025      // 1+2+3+4+5 and + 0
3026      int sum = accumulate(v.begin(), v.end(), 1, mul);
3027 int sum
3028      cout << "sum = " << sum << endl;
3029      return 0;
3030 }
3031 //OUTPUT:
3032 // sum = 120
3033 
3034 /////////////////////////////////////////////////////////////////////////////////////////////////用法3
3035 #include <iostream>
3036 #include <algorithm>
3037 #include <numeric>
3038 using namespace std;
3039 
3040 int main () 
3041 {
3042     int x[] = {1,2,3,4,5};
3043 
3044     // 1 * 2 * 3 * 4 * 5 and * 1
3045     int sum = accumulate(x, x+5, 1, multiplies<int>());
3046     cout << "sum = " << sum << endl;
3047 
3048     // 1 * 2 * 3 * 4 * 5 and * 2
3049     sum = accumulate(x, x+5, 2, multiplies<int>());
3050     cout << "sum = " << sum << endl;
3051 
3052     // 2 * 3 * 4 and * 10
3053     sum = accumulate(x+2, x+4, 10, multiplies<int>());
3054     cout << "sum = " << sum << endl;
3055 
3056     return 0;
3057 }
3058 OUTPUT:
3059 // sum = 120
3060 // sum = 240
3061 // sum = 120
3062 
3063     2.求数组中的最大值
3064 
3065 max_element 
3066 Syntax: 
3067   #include <algorithm>
3068   iterator max_element( iterator start, iterator end );
3069   iterator max_element( iterator start, iterator end, BinPred p );
3070 The max_element() function returns an iterator to the largest element in the range [start,end).
3071 If the binary predicate p is given, then it will be used instead of the < operator to determine the largest element.
3072 Example code: 
3073 For example, the following code uses the max_element() function to determine the largest integer in an array and the largest character in a vector of characters:
3074  int array[] = { 3, 1, 4, 1, 5, 9 };
3075  unsigned int array_size = 6;
3076  cout << "Max element in array is " << *max_element( array, array+array_size) << endl;              
3077 Max element in array is 9
3078 3. sort和qsort
3079 1.sort
3080 用法:
3081 #include <algorithm>
3082   void sort( iterator start, iterator end );
3083   void sort( iterator start, iterator end, StrictWeakOrdering cmp );
3084 
3085 例子:
3086 
3087 #include<iostream>
3088 #include<algorithm>
3089 using namespace std;
3090 int cmp(int a,int b)
3091 {
3092     return a<b;
3093 }
3094 int main()
3095 {    
3096     int a[10]={1,5,68,32,15,48,78,45,35,45};
3097     for(int i=0;i<10;i++)
3098         cout<<a[i]<<"\t";
3099     sort(a,a+10,cmp);
3100     cout<<endl;
3101     for(int i=0;i<10;i++)
3102         cout<<a[i]<<"\t";
3103     return 0;
3104 }
3105 
3106 
3107 2.qsort
3108 #include<cstdlib>
3109 一:对整型数据进行排序
3110 int num[100];
3111 
3112 Sample:
3113 
3114 int cmp ( const void *a , const void *b )
3115 {
3116 return *(int *)a - *(int *)b;
3117 }
3118 
3119 qsort(num,100,sizeof(num[0]),cmp);
3120 二:对结构体进行排序
3121 struct In
3122 {
3123 double data;
3124 int other;
3125 }s[100];
3126 
3127 //按照data的值从小到大将结构体排序,关于结构体内的排序关键数据data的类型可以很多种
3128 
3129 int cmp( const void *a ,const void *b)
3130 {
3131 struct In *c=(In *)a;
3132 struct In *d=(In *)b;
3133 return c->data > d->data ? 1 : -1;
3134 }
3135 
3136 qsort(s,100,sizeof(s[0]),cmp);
3137 九、其他
3138 1.运行时间计算.
3139 #include<time.h>
3140 clock_t start,finish;
3141 start=clock();
3142 finish=clock();
3143 cout<< (double)(finish - start) / CLOCKS_PER_SEC;//运行时间:

 

posted @ 2014-08-11 16:20  MIND KING  阅读(180)  评论(0)    收藏  举报