#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");
}
}
穷举和分治算法
于 2023-05-22 12:36:41 首次发布