分治法——循环赛日程表

总共2^k个选手,正好为2的整数幂,每位选手每天只能比一次,必须与其他选手各比赛一次,总共n-1天。如图所示以天数为横坐标,以运动员编号为纵坐标,我们得到了一个比赛日程表。

不难发现,图中左上角的红框部分和右下角红框部分相同,左下角蓝框和右上角蓝框部分相同,也就是说我们只需要从一半对称到另一半就可以完成这个矩阵

 这里最难理解的就是这个对称赋值,实质上这个赋值的顺序非常诡异,如下图所示

 

 而且我光自己跑还不够,输入代码发现这个代码完全是错误的!m*=2应该放在i的外层使得循环n次,否则用示例代码完全不需要t循环。假设k=2,n进入循环n/2=2,t循环两次,然后m*2=2,下次进来i循环2次,m*2*2=8,完全错了。而且这两条循环语句搞得又复杂有难懂。

右上方矩阵=左上方矩阵+规模m

左下方矩阵=右上方矩阵对称,右下方矩阵=左上方矩阵对称 

	int mid=1;
    while (i <= m)
	{    
        //将矩阵分成左上右上左下右下四块,每块规模都是mid*mid
        //每次进入下一次分治之前左上方的矩阵都已经求出来了
		for (int j = 0; j < mid; j++)//构造右上方方阵,右上方矩阵=左上方+mid
			for (int k = 0; k < mid; k++)
				a[j][k + mid] = a[j][k] + mid;
		for (int j = 0; j < mid; j++)//对称交换构造下半部分方阵
			for (int k = 0; k < mid; k++)
			{ 
				a[j + mid][k] = a[j][k + mid];/*左下方方阵等于右上方方阵*/
				a[j + mid][k + mid] = a[j][k];//右下方方阵等于左上方方阵
			}				
			mid *= 2, i++;
	}

这样求不是简单很多吗,求出左上右上,然后对称一下,非得搞得那么麻烦,浪费时间

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值