(1)分治算法基础解题一般步骤:
1.分解,将要解决的问题划分成若干规模较小的同类问题
2.求解,当子问题划分的足够小时,用较简单的方法解决
3.合并,按原问题的要求,将子问题的解逐层合并构成原问题的解此方法主要是对分治的理解,以及结果的调整和对结果的合并。较难理解~需仔细思考
(2)实践1.解决”大数相乘“问题即计算两个大数的积;
例如123*456
分析:sorry?
编程代码如下:
#include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <string.h> char *result='\0'; int pr=1; void getFill(char *a,char *b,int ia,int ja,int ib,int jb,int tbool,int move) { int r,m,n,s,j,t; char *stack; m=a[ia]-48; if(tbool) { //直接将结果数组的标志位填入,栈对思想 r=(jb-ib>ja-ia)?(jb-ib):(ja-ia); stack=(char *)malloc(r+4); for(r=j=0, s=jb; s>=ib; r++,s--) { n=b[s]-48; stack[r]=(m*n+j)%10; j=(m*n+j)/10; } if(j) { stack[r]=j; r++; } for(r--; r>=0; r--,pr++) result[pr]=stack[r]; free(stack); for(move=move+pr; pr<move; pr++) result[pr]='\0'; } else { r=pr-move-1; for(s=jb,j=0; s>=ib; r--,s--) { n=b[s]-48; t=m*n+j+result[r]; result[r]=t%10; j=t/10; } for(;j;r--) { t=j+result[r]; result[r]=t%10; j=t/10; } } } int get(char *a,char *b,int ia,int ja,int ib,int jb,int t,int move) { int m,n,s,j; if(ia==ja) { getFill(a,b,ia,ja,ib,jb,t,move); return 1; } else if (ib==jb) { getFill(b,a,ib,jb,ia,ja,t,move); return 1; } else { m=(ja+ia)/2; n=(jb+ib)/2; s=ja-m; j=jb-n; get(a,b,ia,m,ib,n,t,s+j+move); get(a,b,ia,m,n+1,jb,0,s+move); get(a,b,m+1,ja,ib,n,0,j+move); get(a,b,m+1,ja,n+1,jb,0,0+move); } return 0; } int main() { char *a,*b; int n,flag; a=(char *)malloc(1000); b=(char *)malloc(1000); printf("The program will computer a*b\n "); printf("Enter a,b:"); scanf("%s %s",a,b); result=(char *)malloc(strlen(a)+strlen(b)+2); flag=pr=1; result[0]='\0'; if(a[0]=='-'&&b[0]=='-') { get(a,b,1,strlen(a)-1,1,strlen(b)-1,1,0); } if(a[0]=='-'&&b[0]!='-') { flag=0; get(a,b,1,strlen(a)-1,0,strlen(b)-1,1,0); } if(a[0]!='-'&&b[0]=='-') { flag=0; get(a,b,0,strlen(a)-1,1,strlen(b)-1,1,0); } if(a[0]!='-'&&b[0]!='-') { get(a,b,0,strlen(a)-1,0,strlen(b)-1,1,0); } if(!flag) printf("-"); if(result[0]) printf("%d",result[0]); for(n=1; n<pr; n++) { printf("%d",result[n]); } printf("\n"); free(a); free(b); free(result); system("pause"); return 0; }
(2)欧冠冠军杯比赛日程安排设共有n队参加,初赛进行n-1天,每队要和其他各队进行一场比赛,然后按照最后积分选拔进入决赛的球队,要求没队每天进行一场比赛,并且不能轮空,按上述要求安排比赛日程决定每队每天的对手。
分析:分治算法得——先将所有队伍分成两半,则n队的比赛日程表可以通过n/2个队的比赛日程决定。然后继续按上述方法将一半再分成一半只到只剩余最后两队结束/例如四队:
编号 第一天
1 2 3 4
2 1 4 3
3 4 1 2
4 3 2 1
4 3 2 1
编码如下:
#include <stdio.h> #include <stdlib.h> #define MAXN 64 int a[MAXN+1][MAXN+1]={0}; void gamecal(int k,int n)//处理编号k开始的n个球队的过程 { int i,j; if(n==2) { a[k][1]=k;//参赛球队编号 a[k][2]=k+1;//对阵球队编号 a[k+1][1]=k+1;//参赛球队编号 a[k+1][2]=k;//对阵球队编号 } else { gamecal(k,n/2); gamecal(k+n/2,n/2); for(i=k;i<k+n/2;i++) { for(j=n/2+1;j<=n;j++) { a[i][j]=a[i+n/2][j-n/2]; } } for(i=k+n/2;i<k;i++) { for(j=n/2;j<=n;j++) { a[i][j]=a[i-n/2][j-n/2]; } } } } int main() { int m,i,j; printf("参赛球队数:"); scanf("%d",&m); j=2; for(i=2;i<8;i++) { j=j*2; if(j==m) break; } if(i>=8) { printf("参赛球队书必须为2的整数次幂,并且不超过64!\n"); getch(); return 0; } gamecal(1,m); printf("\n编号"); for(i=2;i<=m;i++) { printf("%2d天",i-1); printf("\n"); for(i=1;i<m;i++) { for(j=1;j<=m;j++) printf("%4d",a[i][j]); printf("\n"); } } getch(); return 0; }