分治算法思想(4)未——两个大数相乘,欧冠冠军杯比赛日程安排

(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
编码如下:
#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;
}


猜你喜欢

转载自blog.csdn.net/liuzhioj/article/details/79840960