穷举和分治算法

#include<stdio.h>
#define MAXSIZE 64  //允许的最多的参赛队伍数量 
int a[MAXSIZE][MAXSIZE]; //将比赛情况放在这个二维表中 --穷举法 
int b[MAXSIZE][MAXSIZE]; //将比赛情况放在这个二维表中 --分治法 
//----------穷举法实现(基于2进制位移计算)--------------
 void GameTable_1(int n){
    size_t s = n;//s是n的二进制表达
    int k = 0;
    while(s = s >> 1){k++;    }//右移三次结束,k=3
        //初始化
    a[0][0] = 1;
    a[0][1] = 2;
    a[1][0] = 2;
    a[1][1] = 1;
 
    for(int i = 2; i <= k; i++){
//0x1H=0001B,i=2,左移两位得到0100,等于length*2的i次方,得到length=4
        int length = 0x1 << i;
//右移1位,等于length除以2的1次方,得到half=2,即0010
        int half = length >> 1;

//左下角的子表中项为左上角子表对应项加half=2^(i-1)
        for(int row = 0; row < half; row++){
            for(int col = 0; col < half; col++){
                a[row + half][col] = a[row][col] + half;
            }
        }

        //通过左下角求解右上角的值
        for(int row = 0; row < half; row++){
            for(int col = 0; col < half; col++){
                a[row][col + half] = a[row + half][col];//列数+half得到右上角子表 
            }
        }

        //通过左上角求解右下角的值
        for(int row = 0; row < half; row++){
            for(int col = 0; col < half; col++){
                a[row + half][col + half] = a[row][col];//行数,列数同时+half得到右上角子表 
            }
        }


    }
    
    //输出 
    for(int i = 0; i <n; i++){
        for(int j = 0; j < n; j++){
            printf("%d  ",a[i][j]);
        }
        printf("\n");
    }
}

//----------分治法实现-------------- 
int GameTable_2(int n,int k){
    if(n == 2){                     //子问题为2位参赛队伍 
        b[k][0] = k+1;
        b[k][1] = k+2;
        b[k+1][0] = k+2;
        b[k+1][1] = k+1;
    } 
    else{
        
        GameTable_2(n/2,k);
        GameTable_2(n/2,k+n/2);
        
        //填充右上角 
        for (int i=k;i<k+n/2;i++)
        {
            for(int j=n/2;j<n;j++)
            {
                b[i][j]=b[i+n/2][j-n/2];
            }
        }
        
        //填充右下角 
        for (int i=k+n/2;i<k+n;i++)
        {
            for(int j=n/2;j<n;j++)
            {
                b[i][j]=b[i-n/2][j-n/2];
            }
        }
    }
    
} 

int main(){
    int n; //队伍数 
//    cout<<"输入参与队伍数(2的幂次方,2到64):";
    printf("输入参与队伍数(2的幂次方,2到64):"); 
    scanf("%d",&n); 
    printf("-----------穷举法结果------\n"); 
    GameTable_1(n);    
    printf("-----------分治法结果------\n");     
    GameTable_2(n,0);    
    for(int i = 0; i < n; i++){
        for(int j = 0; j < n; j++){
            printf("%d  ",b[i][j]);
        }
        printf("\n");
    } 


} 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值