inti=1
i<=N
Y
N
m=1
i++s=1i++a[1][i]=i
s<=k?
Y
N
N=N/2
s++
intt=1
m=m*2
N
t<=N?
Y
inti=m+1
i<=2*m
Y
N
t++
j=m+1
i++
N
j<=m+1
Y
a[i][j+(t-1)*m*2]=a[i-m][j+(t-1)*m*2-m]a[i][j+(t-1)*m*2-m]=a[i-m][j+(t-1)*m*2]
j++
结束
2
(3)伪代码
publicstaticvoidTable(intn,int[][]a){intb=2;n=saicheng.x;//参赛人数intk=(int)(Math.log(n)/Math.log(b));//计算输入值是2的几次幂for(inti=1;i<=n;i++){a[1][i]=i;//打印出第一行即选手1的赛程表}intm=1;//控制每一次填充表格时i(i表示行)和j(j表示列)的起始填充位置for(ints=1;s<=k;s++){n/=2;//将问题分成k部分for(intt=1;t<=n;t++)//对每一部分进行划分{for(inti=m+1;i<=2*m;i++)//控制行{for(intj=m+1;j<=2*m;j++)//控制列{a[i][j+(t-1)*m*2]=a[i-m][j+(t-1)*m*2-m];//右下角等于左上角a[i][j+(t-1)*m*2-m]=a[i-m][j+(t-1)*m*2];//左下角等于右上角}}}m*=2;}}
四、详细设计及说明
1.输入一个数字n,根据(x&;(x-1))==0判断n是否等于2^k。不是则提示重新输入;是则利用换底公式k=(int)(Math.log(n)/Math.log(b))求出k.2.用一个for循环输出日程表的第一行for(inti=1;i<=N;i++)a[1][i]=i;12345678
3定义一个m值,m初始化为1,m用来控制每一次填充表格时i(i表示行)和j(j表示列)的起始填充位置。
3
4.用一个for循环将问题分成几部分,对于k=3,n=8,将问题分成3大部分,第一部分为,根据已经填充的第一行,填写第二行,第二部分为,根据已经填充好的第一部分,填写第三四行,第三部分为,根据已经填充好的前四行,填写最后四行。for(ints=1;s<=k;s++)N/=2;5.用一个for循环对4中提到的每一部分进行划分for(intt=1;t<=N;t++)对于第一部分,将其划分为四个小的单元,即对第二行进行如下划分
同理,对第二部分(即三四行),划分为两部分,第三部分同理6.最后,进行每一个单元格的填充。填充原则是:对角线填充for(inti=m+1;i<=2*m;i++)//i控制行for(intj=m+1;j<=2*m;j++)//j控制列{a[i][j+(t-1)*m*2]=a[i-m][j+(t-1)*m*2-m];/*右下角的值等于左上角的值*/a[i][j+(t-1)*m*2-m]=a[i-m][j+(t-1)*m*2];/*左下角的值等于右上角的值*/}例:由初始化的第一行填充第二行12287
进行第二部分的填充12342143341243268765
最后是第三部分的填充12345678214365873412785643234658721437856341287654321
4
五、调试与测试
测试一:输入一个不是2^k的数字结果如图2所示:
图2测试二:输入8结果如图3所示:
输入的数字不符题意
图3输入8所示赛程表
5