Description
比赛安排(NOI)
设有2^n(n<=6)个球队进行单循环比赛,计划在2^n-1天内完成,每个队每天进行一场比赛.设计一个比赛的安排,
使在2^n-1天内每个队都与不同的对手比赛.例如n=2时的比赛安排为:
队 1 2 3 4
比赛 1-2 3-4 第一天
1-3 2-4 第二天
1-4 2-3 第三天
Input
2
Output
1-2 3-4
1-3 2-4
1-4 2-3
#include<stdio.h> #include<math.h> int f[66][66]; //存放第i天j的对手 int d[66]; //比过的对手 void qsort(int num[],int shangbiao,int xiabiao) { int i=shangbiao,j=xiabiao; int key=i; int t; if(shangbiao<xiabiao) { while(i<j) { for(;j>key;j--) { if(num[j]<num[key]) { t=num[j]; num[j]=num[key]; num[key]=t; key=j; break; } } i++; for(;i<key;i++) { if(num[i]>num[key]) { t=num[i]; num[i]=num[key]; num[key]=t; key=i; break; } } j--; } qsort(num,shangbiao,key-1); qsort(num,key+1,xiabiao); } } int main() { int n; int i,j; int k; int q; int t; scanf("%d",&n); n=(int)pow(2,n); for(i=1;i<=n-1;i++) { for(j=1;j<=n;j++) { if(j==1) { f[i][j]=i+j; f[i][i+j]=j; } else if(f[i][j]==0) { q=0; d[q]=j; q++; for(k=1;k<j;k++) { if(f[i][k]!=0) d[q++]=f[i][k]; d[q++]=k; } for(k=1;k<i;k++) { if(f[k][j]!=0) d[q++]=f[k][j]; } qsort(d,0,q-1); for(t=1,k=1;k<q;k++,t++) { if(d[k]==d[k+1]) k++; if(d[k]!=t) { f[i][j]=t; f[i][t]=j; break; } } if(k==q) { f[i][j]=t; f[i][t]=j; } for(k=0;k<q;k++) d[k]=0; } } } for(i=1;i<=n-1;i++) { for(j=1;j<=n;j++) { if(f[i][j]!=0) { printf("%d-%d ",j,f[i][j]); f[i][j]=0; } for(k=1;k<=n;k++) { if(f[i][k]==j) { f[i][k]=0; break; } } } printf("\n"); } return 0; }
解题思想:这题我用的是直接模拟,因为数很小,方法虽然很笨,但是蛮实用的。
用一个二维数组存放第i天j的对手是谁,然后用另一个一维数组d[]存放当前j对手曾经打过的对手。然后对他们依次排序。从小到到大。如果遇到不连续的数,当前j的对手
就是他了。。。。
如有其他方法请指教。。。