Java_swt实现_分治法循环赛日程表_论文
- 格式:doc
- 大小:192.00 KB
- 文档页数:16
Java 循环比赛日程表附有结果//输出表格a[i][j](i =1,2,…,n;j=2,3,…,n)表示第i号选手在第j-1天的对手public class CirCompete {public void Table(int k,int[][]a){int n=1;for(int i=1;i<=k;i++){//假设k=个运动员要进行循环比赛n2n *=2; //通过k计算n值,实际是通过参赛人数计算出k值的}for(int i=1;i<=n;i++){a[1][i]=i; //打印出第一行即选手1的赛程表}int m=1;//控制每次填充表格i(i表示行)和j(j表示列)的起始填充位置for(int s=1;s<=k;s++){n/=2;//将问题分成k部分for(int t=1;t<=n;t++) {//对每一部分进行划分for(int i=m+1;i<=2*m;i++){ //控制行for(int j=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;} }public static void main(String[] args) {CirCompete circompete = new CirCompete();int[][] a=new int[9][9];circompete.Table(3,a);//求8n个选手时候的比赛日程表23==for(int i=1;i<9;i++) {for(int j=1;j<9;j++) {System.out.print(a[i][j]+" ");}System.out.println();}}}运行结果:1 2 3 4 5 6 7 82 1 43 6 5 8 73 4 1 2 7 8 5 64 3 2 1 8 7 6 55 6 7 8 1 2 3 46 5 87 2 1 4 37 8 5 6 3 4 1 28 7 6 5 4 3 2 1。
循环赛日程表问题研究题目循环赛日程表问题研究学生指导教师年级 2009级专业软件工程系别软件工程学院计算机科学与信息工程学院哈尔滨师范大学2012年6月论文提要本文采用分治算法来解决循环赛日程表的安排问题。
通过对问题的详细分析,列出1到10个选手的比赛日程表,找出两条规则,作为算法实现的依据,而后采用c语言实现算法,通过测试分析,程序运行结果正确,运行效率较高。
同时也介绍了循环赛日程表问题的另一种解法多边形解法,这种方法另辟蹊径,巧妙地解决了循环赛日程表问题,运行效率较高。
循环赛日程表问题研究摘要:本文采用分治算法来解决循环赛日程表的安排问题。
根据算法的设计结果,采2用c语言实现算法,通过测试分析,程序运行结果正确,运行效率较高。
同时也介绍了循环赛日程表问题的另一种解法,这种方法另辟蹊径,想法独特,运行效率较高。
关键词:循环赛日程表问题,分治法一、题目描述设有n个运动员要进行网球循环赛。
设计一个满足以下要求的比赛日程表:(1)每个选手必须与其他n-1个选手各赛一次;(2)每个选手一天只能赛一次;(3)当n是偶数时,循环赛进行n-1天。
当n是奇数时,循环赛进行n天。
二、问题分析循环赛日程表可以采用分治法实现,把一个表格分成4个小表格来处理,每个小表格都是一样的处理方法,只是参数不同。
分析过程具体如下:1、n=1(表2-1)12.、n=2-2) (表21 22 13、n=3(1) 添加一个虚拟选手4#,构成n+1,4(2) 4/2,2,分两组,每组各自安排(1 2),(3 4)(3) 每组跟另一组分别比赛(拷贝)这是四个人比赛的(表2-3) 4人赛程1 2 3 42 1 4 33 4 1 24 3 2 1 (4) 把虚选手置为0(表2-4)3人赛程31 2 3 02 1 0 33 0 1 20 3 2 1这是三个人比赛的安排4、n=4,见表2-35、n=5(1) 加一个虚选手,n+1=6。
安排好6个人的比赛后,把第6个人用0表示即得5人的。
循环赛日程表的递归和非递解作者:吴秀梅蒋婧王少华温敬和来源:《电脑知识与技术·学术交流》2008年第25期摘要:介绍了算法设计技术分治法的应用。
使用分治法实现了循环赛日程表的递归和非递归解,并作了较为详细的说明,供《算法设计与分析》课程教学参考。
关键词:算法;数据结构;分治法;递归中图分类号:TP301文献标识码:A文章编号:1009-3044(2008)25-1445-04The Recursive and Non-recursive Solution for Calendar of Round RobinWU Xiu-mei, JIANG Jing, WANG Shao-hua, WEN Jing-he(School of Computer and Information, Shanghai Second Polytechnic University, Shanghai 201209, China)Abstract: The application of a powerful algorithm design technique is introduced. The name oftechnique is "divide and conquer". The recursive and non-recursive solution for calendar of round robin is given by divide and conquer. The algorithm of solution is more detailed explanation. It can be used for teaching reference.Key words: algorithm; data structure; divide and conquer; recursive1 引言分治法是一种重要的算法设计技术,它可以用来解决各类问题。
分治算法在循环赛赛程分配中的应用循环赛赛程分配是指在一个参赛队伍数量为2的幂次方的情况下,如何设计赛程,使得每个队伍都能与其他队伍进行一次比赛。
分治算法是一种将问题划分为更小的子问题,然后递归地解决这些子问题,并将子问题的解合并为原始问题的解的方法。
在循环赛赛程分配中,我们可以使用分治算法来实现一个高效的赛程分配算法。
首先,考虑到参赛队伍数量是2的幂次方,我们可以将所有队伍分为两个组,并将每个组分别再次分成两个更小的子组。
这个过程可以持续进行直到每个组只有两个队伍。
然后,将每个组内的两个队伍进行比赛,得到胜者和败者。
胜者将进入下一轮的比赛,而败者则被淘汰。
这个过程可以一直进行,直到最后只剩下一个胜者。
为了更好地理解分治算法在循环赛赛程分配中的应用,下面我们可以考虑一个具体的例子。
假设有8个队伍,编号分别为A、B、C、D、E、F、G、H。
首先,我们先将它们分成两组,每组4个队伍。
第一轮比赛:组1:A、B、C、D组2:E、F、G、H然后,在每个组内进行比赛,得到胜者和败者。
第二轮比赛:组1:胜者A、胜者B、胜者C、胜者D组2:胜者E、胜者F、胜者G、胜者H同样地,在每个组内进行比赛。
第三轮比赛:组1:胜者A、胜者B组2:胜者C、胜者D组3:胜者E、胜者F组4:胜者G、胜者H再次进行比赛。
第四轮比赛:组1:胜者A组2:胜者B组3:胜者C组4:胜者D组5:胜者E组6:胜者F组7:胜者G组8:胜者H最后,胜者A将被认定为整个比赛的冠军。
通过上述例子,我们可以看到分治算法在循环赛赛程分配中的应用。
通过将问题不断地划分为更小的子问题,并通过递归地解决这些子问题,最后合并子问题的解,我们可以有效地设计出循环赛的赛程,使得每个队伍都能与其他队伍进行一次比赛。
总结来说,分治算法在循环赛赛程分配中的应用是通过将问题划分为更小的子问题,并通过递归地解决这些子问题,最终得到一个完整的赛程安排。
这种方法可以保证每个队伍都能与其他队伍进行一次比赛,并且通过使用递归和分治的思想,我们能够高效地解决问题。
循环赛程表#define MAXN 64#define MAX 32int a[MAX][MAX];void Copy(int tox, int toy, int fromx, int fromy, int n) { for (int i=0; i<n; i++)for (int j=0; j<n; j++)a[tox + i][toy + j] = a[fromx + i][fromy + j];}void Table(int k, int a[][MAX]){ int i, n = 1 << k;int r;for (i=0; i<n; i++)a[0][i] = i + 1;for (r=1; r<n; r<<=1){ for (i=0; i<n; i+=2*r){ Copy(r, i + r, 0, i, r);Copy(r, i, 0, i + r, r);}}//ENDFOR}void Out(int a[][MAX], int n){ for (int i=0; i<n; i++){ for (int j=0; j<n; j++) printf("%3d", a[i][j]);printf("\n");}printf("\n");getch();}void main(){ int i;for (i=0; i<5; i++){ int len = 1 << i;Table(i, a);Out(a, len);}}归并排序void merge(int data[], int p, int q, int r){ int n1 = q - p + 1;int n2 = r - q;int L[n1],R[n2];for(int i = 0, k = p; i < n1; i++, k++) L[i] = data[k];for(int i = 0, k = q + 1; i < n2; i++, k++) R[i] = data[k];for(int k = p, i = 0, j = 0; i < n1 && j < n2; k++){ if(L[i] > R[j]) { data[k] = L[i]; i++; }else { data[k] = R[j]; j++; }}if(i < n1) { for(j = i; j < n1; j++, k++) data[k] = L[j]; }if(j < n2) { for(i = j; i < n2; i++, k++) data[k] = R[i]; }}void merge_sort(int data[], int p, int r){ if(p < r){ int q = (p + r) / 2;merge_sort(data, p, q);merge_sort(data, q + 1, r);merge(data, p, q, r);}}快速排序int partition(int number[], int left, int right){ int s = number[right];int i = left - 1;for(int j = left; j < right; j++)if(number[j] <= s) { i++; SW AP(number[i], number[j]); } SW AP( number[i+1], number[right] );return i+1;}void quicksort(int number[], int left, int right){ int q;if(left < right){ q = partition(number, left, right);quicksort(number, left, q-1);quicksort(number, q+1, right);}}二分搜索(非递归)public static int binarySearch(int [] a, int x, int n){ // 在a[0] <= a[1] <= ... <= a[n-1] 中搜索x// 找到x时返回其在数组中的位置,否则返回-1int left = 0; int right = n - 1;while (left <= right){ int mid = (left + right)/2; // mid = low + ((high - low) / 2);if (x == a[mid]) return mid;if (x > a[mid]) left = mid + 1;else right = mid - 1;}return -1; // 未找到x}二分递归public static int binarySearch(int a[], int x, int left ,int right){ // 找到x时返回其在数组中的位置,否则返回-1if (left>right) return -1; // 未找到xelse{ int mid = (left + right)/2;if (x == a[mid]) return mid;if (x > a[mid]) return binarySearch(a, x, mid+1,right);else return binarySearch( a,x,left,mid);}}大数乘法int qiuweishu(long z){ int t=0;while(z>0){ z=z/10; t++; }return t;}main(){ long x,y,a,b,c,d;double z;printf("Please input the two number x and y:\n");scanf("%,%l",&x,&y);a=x/(long)pow10(qiuweishu(x)/2);b=x%(long)pow10(qiuweishu(x)/2);c=y/(long)pow10(qiuweishu(y)/2);d=y%(long)pow10(qiuweishu(y)/2);z=(double)(a*c*pow10(qiuweishu(x))+(a*d+b*c)*pow10(qiuweishu(x)/2)+b*d); /*z=(a*c*(long)pow10(qiuweishu(x))+((a-b)*(d-c)+a*c+b*d)*(long)pow10(qiuw eishu(x)/2)+b*d);*/printf("the result is %ld:",z);}棋盘覆盖#define BOARD_SIZE 4int board[BOARD_SIZE][BOARD_SIZE];// c1, r1: 棋盘左上角的行号和列号c2, r2: 特殊方格的行号和列号void chessboard(int r1, int c1, int r2, int c2, int size) // size = 2 ^ k{ if(1 == size) return;int half_size;static int domino_num = 1;int d = domino_num++;half_size = size / 2;if(r2 < r1 + half_size && c2 < c1 + half_size) //特殊方格在左上角子棋盘{ chessboard(r1, c1, r2, c2, half_size); }else // 不在此棋盘,将此棋盘右下角设为相应的骨牌号{ board[r1 + half_size - 1][c1 + half_size - 1] = d;chessboard(r1, c1, r1 + half_size - 1, c1 + half_size - 1, half_size);}if(r2 < r1 + half_size && c2 >= c1 + half_size) //特殊方格在右上角子棋盘{chessboard(r1, c1 + half_size, r2, c2, half_size); }else // 不在此棋盘,将此棋盘左下角设为相应的骨牌号{ board[r1 + half_size - 1][c1 + half_size] = d;chessboard(r1, c1 + half_size, r1 + half_size - 1, c1 + half_size, half_size);}if(r2 >= r1 + half_size && c2 < c1 + half_size) //特殊方格在左下角子棋盘{ chessboard(r1 + half_size, c1, r2, c2, half_size);}else // 不在此棋盘,将此棋盘右上角设为相应的骨牌号{ board[r1 + half_size][c1 + half_size - 1] = d;chessboard(r1 + half_size, c1, r1 + half_size, c1 + half_size - 1, half_size);}if(r2 >= r1 + half_size && c2 >= c1 + half_size) //特殊方格在左上角子棋盘{chessboard(r1 + half_size, c1 + half_size, r2, c2, half_size); }else // 不在此棋盘,将此棋盘左上角设为相应的骨牌号{ board[r1 + half_size][c1 + half_size] = d;chessboard(r1 + half_size, c1 + half_size, r1 + half_size, c1 + half_size, half_size);}}//ENDint main(){ board[2][2] = 0;chessboard(0, 0, 2, 2, BOARD_SIZE);for(i = 0; i < BOARD_SIZE; i++){for(j = 0; j < BOARD_SIZE; j++){printf("%-4d", board[i][j]);}printf("\n");}}。
算法之循环赛⽇程表循环赛⽇程表⼀.问题描叙设有n=2^k个运动员,要进⾏⽹球循环赛。
现在要设计⼀个满⾜以下要求的⽐赛⽇程表(1).每个选⼿必须与其他n-1个选⼿各赛⼀场(2).每个选⼿⼀天只能赛⼀次(3).循环赛⼀共进⾏n-1天⼆.问题分析按此要求可将⽐赛⽇程表设计成n⾏n-1列的表,在表中第 i ⾏和第j 列处填⼊第 i 个选⼿在第 j 天所遇到的对⼿。
例如,当选⼿的⼈数为8⼈时,其⽐赛⽇程表如下图算法分析:按分治策略,我们可以将所有的选⼿分为两半,则n个选⼿的⽐赛⽇程表可以通过n/2个选⼿的⽐赛⽇程表来决定。
递归地⽤这种⼀分为⼆的策略对选⼿进⾏划分,直到只剩下两个选⼿时,⽐赛⽇程表的制定就变得很简单。
这时只要让这两个选⼿进⾏⽐赛就可以了。
如上图,所列出的正⽅形表是8个选⼿的⽐赛⽇程表。
其中左上⾓与左下⾓的两⼩块分别为选⼿1⾄选⼿4和选⼿5⾄选⼿8前3天的⽐赛⽇程。
据此,将左上⾓⼩块中的所有数字按其相对位置抄到右下⾓,⼜将左下⾓⼩块中的所有数字按其相对位置抄到右上⾓,这样我们就分别安排好了选⼿1⾄选⼿4和选⼿5⾄选⼿8在后4天的⽐赛⽇程。
依此思想容易将这个⽐赛⽇程表推⼴到具有任意多个选⼿的情形。
算法实现步骤:(1)当k=1时,即⼈数为2⼈,此情况为最简单的情况此时表为1 22 1(2)当k=2时,⼈数为4⼈,循环表为1 2 3 42 1 4 33 4 1 2 4 3 2 1(3)当k=3时,⼈数为8⼈,此时循环表为1 2 3 4 5 6 7 82 1 4 3 6 5 8 73 4 1 2 7 8 5 64 3 2 1 8 7 6 55 6 7 8 1 2 3 46 5 8 7 2 1 4 37 8 5 6 3 4 1 28 7 6 5 4 3 2 1以此类推,我们不难发现,我们可以⽤分治的⽅法实现,现⾃顶向下分解,直到分解到最简单的情况,即⼈数为2⼈,这时就可以两两⽐赛,表的填充为对⾓填充的⽅式,然后再⾃底向上填充表格,具体的看上⾯的k=1,k=2,k=3时形成的循环表就很好理解了。
利用分治法设计循环赛日程表摘要:对于单循环赛的比赛日程安排问题,利用分治算法给出了可读性较好的设计,并分析了各种假设下的时间复杂度。
关键词:分治算法;复杂度;递归;循环赛引言任何一个可以用计算机求解的问题所需的计算时间都与其规模有关。
问题的规模越小,越容易求解,所需的计算时间也越少。
分治法是计算机科学中经常使用的一种算法。
设计思想是,将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之。
1分治法应用条件及一般步骤1.1 分治法的应用条件1.1.1能将n个数据分解成k个不同子集合,且得到的k个子集合是可以独立求解的子问题,其中11&&odd(n/2)) copyodd(n);else copy(n);}void copyodd(int n){int m=n/2;for(int i=0;i=m){a[i][j]=b[i];a[m+i][j]=(b[i]+m)%n;}else a[m+i][j]=a[i][j]+m;}for(j=1;j<m;j++){a[i][m+j]=b[i+j];a[b[i+j]][m+j]=i;}}}分析算法的时间性能:当n/2为奇数时,基本语句的执行次数是:当n/2为偶数时,基本语句的执行次数是:综上,时间复杂度为O(4k )。
2.3 运行结果及分析当输入n为2时,输出:0 11 0在上面n=2时的日程表(二维表)中,左边第一列表示球队编号,第二列表示在某天碰到的对手球队的编号。
推广之,对于n行n列的二维日程表,那么,a[0][0],a[1][0],……,a[n-1][0]表示参加循环赛的n支球队的编号;a[0][1],a[0][2],……,a[0][n-1]表示球队a[0][0]在第1,2,……,n-1天碰到的对手球队编号。
a[i][j](i,j<n)表示编号为a[i][0]的球队在第j日遇到的对手球队的编号。
以下同。
问题描述:设有n个运动员要进行网球循环赛。
设计一个满足以下要求的比赛日程表:(1)每个选手必须与其他n-1个选手各赛一次;(2)每个选手一天只能赛一次;(3)当n是偶数时,循环赛进行n-1天。
当n是奇数时,循环赛进行n天。
分析过程:这个问题的解搜索空间是一个n的全排列。
要求的解是其中的n个排列,满足条件:第1列n个元素值按增序排列;每行每列没有相同的数。
也是一个幻方(除对角线的和不作要求)的问题。
1.n=11)2. n=2(表2)3.n=3,(1) 添加一个虚拟选手4#,构成n+1=4(2) 4/2=2,分两组,每组各自安排(1 2),(3 4)(3)每组跟另一组分别比赛(拷贝)这是四个人比赛的安排(4)把虚选手置为0(表4)3人赛程这是三个人比赛的安排4. n=4, 见表35. n=5, (1)加一个虚选手,n+1=6。
安排好6个人的比赛后,把第6个人用0表示即得5人的。
(2) 分成两组(1 2 3) (4 5 6),各3名选手(3) 依照表4,安排第1组;按表5安排第2组(除0元素外,都加3)(表5)(4) 把表5排于表4下方(5) 把同一天都有空的两组安排在一起比赛(按这种安排,肯定每天只有一对空组,?)。
(6) 第一组的(1 2 3)和第2组的(4 5 6)分别比赛。
但是由于(1,4), (2, 5), (3 6)已经比赛过了,所以在后面的安排中不能再安排他们比赛。
1 2 34 5 6首先,1#只能和5#或6#比赛。
(a)若1#-5#,由于3#和6#已经比赛过,所以只能安排: 2#-6#,3#-4#(b)若1#-6#,由于2#和5#已经比赛过,只能安排:2#-4#,3#-5#这样安排后前三行的后两列,后三行的后两列由上面的三行来定:表8就是6名选手的比赛日程安排。
将其中的6号作为虚拟选手,把6换成0,即得5名选手的赛程安排表:(表9)5人赛程6 n=6,见表8。
7 n=7, 添加1,n+1=8。
利用分治法设计循环赛日程表作者:王猛来源:《科技经济市场》2008年第07期摘要:对于单循环赛的比赛日程安排问题,利用分治算法给出了可读性较好的设计,并分析了各种假设下的时间复杂度。
关键词:分治算法;复杂度;递归;循环赛引言任何一个可以用计算机求解的问题所需的计算时间都与其规模有关。
问题的规模越小,越容易求解,所需的计算时间也越少。
分治法是计算机科学中经常使用的一种算法。
设计思想是,将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之。
1分治法应用条件及一般步骤1.1 分治法的应用条件1.1.1能将n个数据分解成k个不同子集合,且得到的k个子集合是可以独立求解的子问题,其中11.1.2分解所得到的子问题与原问题具有相似的结构,便于利用递归或循环机制;1.1.3合并各个子问题的解,就是原问题的解。
1.2 分治法的一般步骤1.2.1分解:将原问题分解为若干个规模较小,相互独立,与原问题形式相同的子问题;1.2.2求解子问题:若子问题规模较小而容易解决则直接解,否则再继续分解为更小的子问题,直到容易解决;1.2.3合并:将已求解的各个子问题的解,合并为原问题的解。
2 循环赛分治算法2.1 问题描述有n支球队参加循环赛,设计一个满足下面要求的比赛日程表:2.1.1每支球队必须与其他n-1支球队各赛一次;2.1.2每支球队一天只能比赛一次;2.1.3当n为偶数时,比赛进行n-1天;当n为奇数时,比赛进行n天。
2.2 算法分析当n=2k (k=1、2、3、4……)时,比较简单。
按照分治的策略,可将所有参赛的选手分为两部分,n=2k 个选手的比赛日程表就可以通过为n/2=2k-1 个选手设计的比赛日程表来决定。
递归地执行这种分割,直到只剩下2个选手时,比赛日程表的制定就变得很简单,只要让这2个选手进行比赛就可以了。
再逐步合并子问题的解即可得到原问题的解。
算法如下:void tourna(int n){if(n==1){a[0][0]=1;return;}tourna(n/2);copy(n);}void copy(int n){int m=n/2;for(int i=0;ifor(int j=0;j{a[i][j+m]=a[i][j]+m;a[i+m][j]=a[i][j+m];a[i+m][j+m]=a[i][j];}基本语句的执行次数是:T(n)=3=O(4k ),所以算法的时间复杂度为O( 4k)。
附件二【学生用】《算法分析与设计》综合训练实习报告题目:利用分治思想设计循环赛日程表学号姓名专业班级指导教师实践日期目录一、综合训练目的与要求 (1)二、综合训练任务描述 (1)三、算法设计 (1)四、详细设计及说明 (3)五、调试与测试 (5)六、实习日志 (6)七、实习总结 (6)八、附录:核心代码清单 (6)一、综合训练目的与要求本综合训练是软件工程专业重要的实践性环节之一,是在学生学习完《算法分析》课程后进行的综合练习。
本课综合训练的目的和任务:1. 巩固和加深学生对算法分析课程基本知识的理解和掌握;2. 培养利用算法知识解决实际问题的能力;3. 掌握利用程序设计语言进行算法程序的开发、调试、测试的能力;4. 掌握书写算法设计说明文档的能力;5. 提高综合运用算法、程序设计语言、数据结构知识的能力。
二、综合训练任务描述假设有n=2k 个运动员要进行网球循环赛。
设计一个满足一下要求的比赛日程表:1. 每个选手必须与其他n-1个选手各赛一次2. 每个选手一天只能赛一次3. 循环赛一共进行n-1天利用Java语言开发一个界面,输入运动员的个数,输出比赛日程表。
对于输入运动员数目不满足n=2k时,弹出信息提示用户。
三、算法设计(1) 文字描述假设n位选手顺序编号为1,2,3……n,比赛的日程表是一个n行n-1列的表格。
i行j列的表格内容是第i号选手在第j天的比赛对手。
根据分而治之的原则,可从其中一半选手的比赛日程,导出全体n位选手的的日程,最终细分到只有两位选手的比赛日程出发(2)框图比赛人数n=2^k ,求出kNNYNYNYYNYint i=1i<=Ni++a[1][i]=ii++m=1s=1s<=k?N=N/2int t=1t<=N?int i=m+1i<=2*mj=m+1j<=m+1a[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++i++t++s++ m=m*2结束(3)伪代码public static void Table(int n,int[][]a) {int b = 2;n = saicheng.x;//参赛人数int k=(int) (Math.log(n)/Math.log(b)); //计算输入值是2的几次幂for(int i=1;i<=n;i++){a[1][i]=i;//打印出第一行即选手1的赛程表}int m=1;//控制每一次填充表格时i(i表示行)和j(j表示列)的起始填充位置for(int s=1;s<=k;s++){n/=2;//将问题分成k部分for(int t=1;t<=n;t++)//对每一部分进行划分{for(int i=m+1;i<=2*m;i++)//控制行{for(int j=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(int i=1;i<=N;i++)a[1][i] = i;1 2 3 4 5 6 7 83定义一个m值,m初始化为1,m用来控制每一次填充表格时i(i表示行)和j(j表示列)的起始填充位置。
4.用一个for 循环将问题分成几部分,对于k=3,n=8,将问题分成3大部分,第一部分为,根据已经填充的第一行,填写第二行,第二部分为,根据已经填充好的第一部分,填写第三四行,第三部分为,根据已经填充好的前四行,填写最后四行。
for (int s=1;s<=k;s++)N/=2;5.用一个for 循环对4中提到的每一部分进行划分for(int t=1;t<=N;t++)对于第一部分,将其划分为四个小的单元,即对第二行进行如下划分同理,对第二部分(即三四行),划分为两部分,第三部分同理6.最后,进行每一个单元格的填充。
填充原则是:对角线填充 for(int i=m+1;i<=2*m;i++) //i 控制行 for(int j=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];/*左下角的值等于右上角的值 */ }例:由初始化的第一行填充第二行1 2 3 4 5 6 7 8 21436587进行第二部分的填充1 2 3 4 5 6 7 8 2 1 4 3 6 5 8 7 3 4 1 2 7 8 5 6 43218765最后是第三部分的填充1 2 3 4 5 6 7 8 2 1 4 3 6 5 8 7 3 4 1 2 7 8 5 6 4 3 2 1 8 7 6 5 5 6 7 8 1 2 3 4 6 5 8 7 2 1 4 3 7 8 5 6 3 4 1 2 8 7654321五、调试与测试测试一:输入一个不是2^k 的数字结果如图2所示:测试二:输入8结果如图3所示:图2输入的数字不符题意图3 输入8所示赛程表六、实习日志9月13日理解题意,题目要求,确定使用分治法解决。
9月14日根据书上分治法的设计思路以及所提供的代码按题目要求设计算法。
9月15日根据算法写出代码。
9月16日根据代码设计SWT界面。
9月17日总结,写论文。
七、实习总结根据分治算法,将本问题进行了由小规模到大规模的求解设计,程序设计的关键点在于如何对问题进行划分和填充公式的归纳。
在划分时,主要运用了两个for循环;在填充时,运用了两个for 循环。
通过这次程序设计,加深了对分治算法的认识。
解决具体问题时,程序故重要,但一个好的算法更加重要。
不足之处即花费了很长时间来推导这个算法,对算法掌握还不够熟练。
八、附录:核心代码清单输入界面代码:import org.eclipse.swt.widgets.Display;import org.eclipse.swt.widgets.Shell;import org.eclipse.swt.widgets.Button;import org.eclipse.swt.SWT;import bel;import org.eclipse.swt.widgets.Text;import org.eclipse.swt.events.SelectionAdapter;import org.eclipse.swt.events.SelectionEvent;import com.swtdesigner.SWTResourceManager;public class saicheng {protected Shell competetion;private Text text;public static int x;/***Launch the application.*@param args*/public static void main(String[] args) {try {saicheng window = new saicheng();window.open();} catch (Exception e) {e.printStackTrace();}}/***Open the window.*/public void open() {Display display = Display.getDefault();createContents();competetion.open();yout();while (!competetion.isDisposed()) {if (!display.readAndDispatch()) {display.sleep();}}}/***Create contents of the window.*/protected void createContents() {competetion = new Shell();competetion.setSize(450, 300);competetion.setText("\u6BD4\u8D5B\u65E5\u7A0B\u8868\u8BA1\u7B97");{Button button = new Button(competetion, SWT.NONE);button.addSelectionListener(new SelectionAdapter() {public void widgetSelected(SelectionEvent e) {x=Integer.valueOf(text.getText());if((x&(x-1))==0){//判断是否为2的整次幂competetion.close();eeee eeee=new eeee();eeee.open();}else{competetion.close();ssss ssss=new ssss();ssss.open();}}});button.setBounds(125, 158, 72, 22);button.setText("\u786E\u8BA4");}{final Button button = new Button(competetion, SWT.NONE);button.addSelectionListener(new SelectionAdapter() {public void widgetSelected(SelectionEvent e) {System.exit(0); //退出系统}});button.setBounds(226, 158, 72, 22);button.setText("\u9000\u51FA");}{Label label = new Label(competetion, SWT.NONE);label.setFont(SWTResourceManager.getFont("黑体", 12, SWT.NORMAL));label.setAlignment(SWT.CENTER);label.setBounds(107, 84, 128, 19);label.setText("\u8BF7\u8F93\u5165\u6BD4\u8D5B\u4EBA\u6570\uFF1A");}{text = new Text(competetion, SWT.BORDER);text.setBounds(241, 81, 84, 22);}}}提示错误界面import org.eclipse.swt.widgets.Display;import org.eclipse.swt.widgets.Shell;import bel;import org.eclipse.swt.SWT;import org.eclipse.swt.widgets.Button;import org.eclipse.swt.events.SelectionAdapter;import org.eclipse.swt.events.SelectionEvent;import com.swtdesigner.SWTResourceManager;public class ssss {protected Shell warnings;/***Launch the application.*@param args*/public static void main(String[] args) {try {ssss window = new ssss();window.open();} catch (Exception e) {e.printStackTrace();}}/***Open the window.*/public void open() {Display display = Display.getDefault();createContents();warnings.open();yout();while (!warnings.isDisposed()) {if (!display.readAndDispatch()) {display.sleep();}}}/***Create contents of the window.*/protected void createContents() {warnings = new Shell();warnings.setSize(450, 300);warnings.setText("\u8B66\u544A");{Label label = new Label(warnings, SWT.NONE);label.setFont(SWTResourceManager.getFont("黑体", 12, SWT.NORMAL));label.setBounds(47, 109, 371, 17);label.setText("\u8F93\u5165\u9519\u8BEF\uFF01\uFF01\uFF01\u8BF7\u91CD\u65B0\u 8F93\u5165\u4E00\u4E2A\u662F2\u7684\u6574\u6B21\u5E42\u7684\u6570\uFF01\uFF01 \uFF01");}{Button rebutton = new Button(warnings, SWT.NONE);rebutton.addSelectionListener(new SelectionAdapter() {public void widgetSelected(SelectionEvent e) {warnings.close();saicheng saicheng=new saicheng();saicheng.open();}});rebutton.setBounds(183, 179, 72, 22);rebutton.setText("\u91CD\u7F6E");}}}赛程表输出代码:import org.eclipse.swt.widgets.Display;import org.eclipse.swt.widgets.Shell;import bel;import org.eclipse.swt.SWT;import com.swtdesigner.SWTResourceManager;import org.eclipse.swt.widgets.Button;import org.eclipse.swt.events.SelectionAdapter;import org.eclipse.swt.events.SelectionEvent;public class eeee {protected Shell shell;int[][] a=new int[saicheng.x+1][saicheng.x+1];/***Launch the application.*@param args*/public static void main(String[] args) {try {eeee window = new eeee();window.open();} catch (Exception e) {e.printStackTrace();}}/***Open the window.*/public void open() {Display display = Display.getDefault();createContents();shell.open();yout();while (!shell.isDisposed()) {if (!display.readAndDispatch()) {display.sleep();}}}public static void Table(int n,int[][]a){int b = 2;n = saicheng.x;//参赛人数int k=(int) (Math.log(n)/Math.log(b)); //计算输入值是2的几次幂for(int i=1;i<=n;i++){a[1][i]=i;//打印出第一行即选手1的赛程表}int m=1;//控制每一次填充表格时i(i表示行)和j(j表示列)的起始填充位置for(int s=1;s<=k;s++){n/=2;//将问题分成k部分for(int t=1;t<=n;t++)//对每一部分进行划分{for(int i=m+1;i<=2*m;i++)//控制行{for(int j=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;}}/***Create contents of the window.*/protected void createContents() {shell = new Shell();shell.setSize(663, 473);shell.setText("\u8D5B\u7A0B\u8868");{Label label1 = new Label(shell, SWT.NONE);label1.setAlignment(SWT.CENTER);label1.setFont(SWTResourceManager.getFont("黑体", 16, SWT.NORMAL));label1.setBounds(10, 10, 191, 22);label1.setText("参赛人数有"+saicheng.x+"人");}{Label label = new Label(shell, SWT.NONE);label.setBounds(10, 38, 79, 12);label.setText("\u8D5B\u7A0B\u5B89\u6392\u5982\u4E0B"); }{Label label = new Label(shell, SWT.NONE);label.setBounds(10, 76, 54, 12);label.setText("\u9009\u624B/\u8F6E\u6570");}{Button button1 = new Button(shell, SWT.NONE);button1.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) {shell.close();saicheng saicheng=new saicheng();saicheng.open();}});button1.setBounds(274, 10, 42, 22);button1.setText("\u8FD4\u56DE");}{Button button2 = new Button(shell, SWT.NONE);button2.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) {shell.close();System.exit(0);}});button2.setBounds(332, 10, 42, 22);button2.setText("\u9000\u51FA");}for(int i=1;i<saicheng.x;i++){{Label label = new Label(shell, SWT.NONE);label.setBounds(70+35*(i-1), 76, 35, 12);label.setText("第"+i+"天");}}for(int i=1;i<saicheng.x+1;i++){for(int j1=1;j1<saicheng.x+1;j1++){{Table(saicheng.x,a);//调用table函数Label label = new Label(shell, SWT.NONE);label.setBounds(35*j1, 100+21*(i-1), 35, 12);label.setText("选手"+a[i][j1]);}}}}}。