欧洲杯16强分组问题算法

hurricane511 2007-11-18 02:18:43
欧洲杯16强分组规则:
假设参加欧洲杯的球队来自4个国家A,B,C,D的16只球队,每个国家4只球队参赛,同一个国家的球队不能分在同一个小组
球队分别记为A1,A2,A3,A4,B1,B2,B3,B4,C1,C2,C3,C4,D1,D2,D3,D4
现在要求列出所有可能的分组(不能重复),并给出时间复杂度和空间复杂度.(根据排列组合知识,可以计算出一共有4^3*3^3*2^3 = 13824种组合)
...全文
930 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
HW121 2007-11-20
  • 打赏
  • 举报
回复
欧洲杯16强分组可以这样计算:
按国家顺序一个一个来:
1、先选国家A,只有一种组合C(4,4)=1
2、再选国家B,每个队分到A1、A2、A3、A4小组共有P(4,4 )=4!种情况;
3、上每情况,再选国家C又有P(4,4 )=4!种情况,同理D国家也一样;
所以共 C(4,4)*P(4,4)*(4,4)*P(4,4)=(4!)^3=13824种组合

按这个思路编程就好编:
#include  <stdio.h> 

void savePermutation(int *sa, int *a, int n, int k)
{
static int pos = 0;

if(n == k+1)
for(int i = 0; i < n; pos++)
sa[pos] = a[i];
else
for(int i = k; i < n; i++)
{
int t = a[k];
a[k] = a[i];
a[i] = t;
savePermutation(sa, a, n, k+1);
a[i] = a[k];
a[k] = t;
}
}


void main()
{
int perm[4*3*2*1][4];
int a[4] = { 1,2,3,4 };

savePermutation(perm[0], a, 4, 0);

int count =0;

for(int b = 0; b < 24; b++)
for(int c = 0; c < 24; c++)
for(int d = 0; d < 24; d++, count++)
{
printf("[ ");
for(int i = 0; i < 4; i++)
printf("(A%d,B%d,C%d,D%d) ", i+1, perm[b][i], perm[c][i],perm[d][i]);
printf("]\n");
}
printf("combination count=%d\n", count);
}
medie2005 2007-11-19
  • 打赏
  • 举报
回复
#include <iostream>

using namespace std;

int sl;
int L[4][4];
int H[][4]={
1,2,3,4,
1,2,4,3,
1,3,2,4,
1,3,4,2,
1,4,2,3,
1,4,3,2,
2,1,3,4,
2,1,4,3,
2,3,1,4,
2,3,4,1,
2,4,1,3,
2,4,3,1,
3,1,2,4,
3,1,4,2,
3,2,1,4,
3,2,4,1,
3,4,1,2,
3,4,2,1,
4,1,2,3,
4,1,3,2,
4,2,1,3,
4,2,3,1,
4,3,1,2,
4,3,2,1
};

void f( ){
int i, j, k, l;
for( l=0; l<4; ++l )
L[l][3]=l+1;
for( i=0; i<24; ++i ){
for( l=0; l<4; ++l )
L[l][0]=H[i][l];
for( j=0; j<24; ++j ){
for( l=0; l<4; ++l )
L[l][1]=H[j][l];
for( k=0; k<24; ++k ){
for( l=0; l<4; ++l )
L[l][2]=H[k][l];
cout<<++sl<<" :\n";
for( int h=0; h<4; ++h ){
for( int g=0; g<4; ++g )
cout<<char('A'+g)<<L[h][g]<<" ";
cout<<"\n";
}
}
}
}
}

int main( )
{
f();
cout<<sl<<endl;
return 0;
}
hurricane511 2007-11-18
  • 打赏
  • 举报
回复
下面是我写的算法,可以实现分组,但是MAX_GROUP_NUM大于1519的时候,VS 2005提示堆栈溢出,大家帮忙看看,谢谢!欢迎大家批评指正,如果能提供更好的算法就更好了!

#include "stdafx.h"
#include <math.h>
#include <string>
#include <iostream>
using namespace std ;

//欧洲杯16强分组规则:
//假设参加欧洲杯的球队来自4个国家A,B,C,D的16只球队,每个国家4只球队参赛,同一个国家的球队不能分在同一个小组
//球队分别记为A1,A2,A3,A4,B1,B2,B3,B4,C1,C2,C3,C4,D1,D2,D3,D4
//现在要求列出所有可能的分组(不能重复),并给出时间复杂度和空间复杂度.(根据排列组合知识,可以计算出一共有4^3*3^3*2^3 = 13824种组合)

const int MAX_GROUP_NUM = 24*24*24;
int _tmain(int argc, _TCHAR* argv[])
{
char *OriginalGroup[4][4] = {{"A1","A2","A3","A4"},{"B1","B2","B3","B4"},{"C1","C2","C3","C4"},{"D1","D2","D3","D4"}}; //初始分组
char *CurrentGroup[MAX_GROUP_NUM][4][4] = {""}; //存放所有分组结果
int i = 0;
int j = 0;
int iSeed;
int k = 0;
int iGroupcount =0;
while(iGroupcount < MAX_GROUP_NUM) //是否全部分好
{
for(i = 0;i<4;i++)
{
for(j= 0;j<4;j++)
{
iSeed = rand()%4; //获取随机种子
k = 0;
while(k < 4)
{
for(k = 0; k < 4; k++)
{
if(CurrentGroup[iGroupcount][k][j] == OriginalGroup[j][iSeed])
{
break;
}
}
if( k == 4) //不重复
{
CurrentGroup[iGroupcount][i][j] = OriginalGroup[j][iSeed];
}
else
{
iSeed = rand()%4; //重新获取随机种子
}
}

}

}
int p = 0;
int q = 0;
int r = 0;
int icount =0;

if(iGroupcount > 0)
{
for( r = 0;r < iGroupcount;r++)
{
icount = 0;
for(q = 0;q<4;q++)
{
for (p = 0; p < 4; p++)
{
if( CurrentGroup[r][p][0] == CurrentGroup[iGroupcount][q][0]
&¤tGroup[r][p][1] == CurrentGroup[iGroupcount][q][1]
&¤tGroup[r][p][2] == CurrentGroup[iGroupcount][q][2]
&¤tGroup[r][p][3] == CurrentGroup[iGroupcount][q][3]) //分组是否与以前分好的组完全相同
{
icount++;
}

}
}
}
if( 4 == icount) //相同则继续随机选取进行分组
{
continue;
}
}
iGroupcount++;

}
for( iGroupcount = 0;iGroupcount < MAX_GROUP_NUM;iGroupcount++) //输出全部分组结果
{
for( i =0;i< 4;i++ )
{
for( j =0;j< 4 ;j++ )
{
cout<<CurrentGroup[iGroupcount][i][j]<< " ";
}
cout<<endl;
}
cout<<endl;
cout<<endl;
}

return 0;
}

33,010

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧