[ Source : Seaeagle ]
1437: 校长杯

Time Limit: 1500 ms    Memory Limit: 32000 kB  
Judge type: Multi-cases Special Judge
Total Submit : 113 (54 users)   Accepted Submit : 70 (48 users)   Page View : 3989 
Font Style: Aa Aa Aa

        在南开大学,一年一度的“校长杯”三大球比赛是广大师生必不可少的一次运动大餐。随着南开大学学校规模的扩大和体育事业的发展,参与校长杯赛事的师生越来越多。竞赛采用的是传统的“循环赛”制,即每队的选手都必须和其他各队选手较量一次。为了竞赛日程安排方便,报名的队伍数n都将是2的k次幂,(0<k<9,且k为自然数)。为了避免参赛师生过于疲劳,竞赛安排每支队伍每天只比赛一次。同时,竞赛一共进行(n-1)天。
      现在,竞赛组委会想请你帮忙设计一个循环赛的日程表,使得竞赛的日程安排满足上述要求。

Input

输入只有一个数k。

Output

请输出一个n行,每行有n个正整数的循环赛日程表。相邻的两个正整数用一个空格隔开。
其中,第i行(0<i<n+1)表示第i队的参赛日程,第1个正整数为i,表示参赛队的队号,后面的(n-1)个正整数表示该队在参赛日程中,依次较量的队号。

Sample Input

1

Sample Output

1 2
2 1
 1 /*
 2    功能Function Description:     NKOJ-1437
 3    开发环境Environment:          DEV C++ 4.9.9.1
 4    技术特点Technique:
 5    版本Version:
 6    作者Author:                   可笑痴狂
 7    日期Date:                      20120821
 8    备注Notes:
 9         就是打印一个循环赛编制安排
10         每次从小到大找当前点在同行和同列都没有出现过的编号填充数组
11    题目来源: http://acm.nankai.edu.cn/p1437.html
12 */
13 //真邪恶----竟然没超时
14 #include<stdio.h>
15 int a[550][550];
16 int main()
17 {
18     int k,n,flag,i,j,t,x,y;
19     while(scanf("%d",&k)!=EOF)
20     {
21         n=1<<k;
22         for(i=1;i<=n;++i)
23             a[1][i]=a[i][1]=i;
24         for(i=2;i<=n;++i)
25         {
26             for(j=2;j<=n;++j)
27             {
28                 for(t=1;t<=n;++t)
29                 {
30                     flag=1;
31                     for(x=1;x<j;++x)
32                     {
33                         if(a[i][x]==t)
34                         {
35                             flag=0;
36                             break;
37                         }
38                     }
39                     if(flag)
40                     {
41                         for(y=1;y<i;++y)
42                         {
43                             if(a[y][j]==t)
44                             {
45                                 flag=0;
46                                 break;
47                             }
48                         }
49                     }
50                     if(flag)
51                     {
52                         a[i][j]=t;
53                         break;
54                     }
55                 }
56             }
57         }
58         for(i=1;i<=n;++i)
59         {
60             for(j=1;j<n;++j)
61                 printf("%d ",a[i][j]);
62             printf("%d\n",a[i][j]);
63         }
64     }
65     return 0;
66 }
 1 //代码二:---递归(转)
 2 /*
 3 由人数为k推得人数为2*k时,方阵变为原来的四倍,不仅对角相互对称,而且对角完全相同
 4 左上角和右下角对称,左下角和右上角对称,左上角加上表大小的一半可得右上角的元素,
 5 而根据对称,可求出整个表.
 6 */
 7 #include<stdio.h> 
 8 int n,m[1<<8][1<<8]; 
 9 
10 //由左上角得到其他  
11 void fun(int size) 
12 { 
13     int i,j; 
14     if(size==n) 
15         return; 
16     for(i=0;i<size;++i) 
17         for(j=0;j<size;++j) 
18             m[i+size][j+size]=m[i][j];  //由左上角与右下角相同,推出右下角元素
19     for(i=0;i<size;++i) 
20         for(j=size;j<2*size;++j) 
21         { 
22             m[i][j]=m[i][j-size]+size; 
23             m[j][i]=m[i][j-size]+size; 
24         } 
25     fun(size*2); 
26 } 
27 int main() 
28 { 
29     int i,j,k; 
30     while(~scanf("%d",&k)) 
31     { 
32         n=1<<k; 
33         m[0][0]=1; 
34         fun(1); 
35         for(i=0;i<n;++i) 
36         { 
37             for(j=0;j<n-1;++j) 
38                 printf("%d ",m[i][j]); 
39             printf("%d\n",m[i][j]); 
40         } 
41     } 
42     return 0;
43 } 

 

 

posted on 2012-08-21 09:58  可笑痴狂  阅读(682)  评论(0)    收藏  举报