1. 程式人生 > >分治演算法思想(4)未——兩個大數相乘,歐冠冠軍盃比賽日程安排

分治演算法思想(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 42 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;
}