您的位置:首页 > 其它

用程序解决一个实际问题---n支球队进行单循环比赛,每天一场,给出一个比赛日程,使每支球队在两场比赛之间至少间隔一天

2010-11-30 11:44 936 查看
  对于这个问题,首先将n具体化,比如我先把n定义为5,首先第一步要对队伍编号从0~4,那么这5支球队共要比赛多少天可以知道用组合C25 这个符号不会用,也就是n(n-1)/2,5支球队就要比赛10天,然后将所有可能的比赛先列出来

0

1

2

3

4

0-1,0-2,0-3,0-4,1-2,1-3,1-4,2-3,2-4,3-4 然后按条件进行排序,得出最后结果,如果按正常人为去排序则要花很长的时间,也许5支比较少,但如果是10支,20支呢,而事实却就是这样,NBA30支球队,足球更别说了,这里小程序如下:

代码

class Math
{
public Math() //无参数构造函数
{
//显示输入
ShowQuestion();
//计算比赛需要天数
CalCount();
//数组初始化
p=newint[days,2];
p1=newint[days,2];
//将球队编号后添加入球队集合
Add();
}
//队伍集合
private ArrayList Team =new ArrayList();
privateint t=0;
//共有多少支球队
privateint sum =20;
//比赛场次也就是比赛天数
privateint days =0;
//记录所有比赛,这里用了个二维数组p
privateint[,] p;
//记录下按要求的比赛日程,这里用了个新的二维数组p1
privateint[,] p1;
#region//展示问题 和提供输入
privatevoid ShowQuestion()
{
Console.Write("问题:{0}支球队进行单循环比赛,每天一场,给出一个比赛日程,使每支球队在两场比赛之间至少间隔一天 (要有安排比赛日程的可操作的方法)\n", sum);
Console.Write("请输入要比赛的球队数量:\n");
flag: try
{
sum = Convert.ToInt32(Console.ReadLine());
if (sum <5)
{
Console.Write("球队数目太少,不能少于5支球队!\n请输入要比赛的球队数量:\n");
goto flag;
}
}
catch (Exception e)
{
Console.Write("输入的数字不合规范!\n请输入要比赛的球队数量:\n");
goto flag;
}
}
#endregion
#region//计算将要打多少场比赛
privatevoid CalCount()
{
for (int i =0; i < sum; i++)
for (int j = i +1; j < sum; j++)
{
days++;
}
}
#endregion
#region//将所有可能的比赛列出来
publicvoid Add()
{
for (int i =0; i < sum; i++)
{
Team.Add(i.ToString());
}
for (int i =0; i < sum; i++)
for (int j = i +1; j < sum; j++)
{
p[t, 0] = Convert.ToInt32(Team[i]);
p[t, 1] = Convert.ToInt32(Team[j]);
t++;
}
}
#endregion
#region//判断当天比赛双方符不符合比赛要求:使每支球队在两场比赛之间至少间隔一天
privatebool check(int d)
{
if (d ==0)
returntrue;
else
{
//双方不能背靠背比赛,昨天刚打,则当天不能在比赛,这里条件是隔1天,如果隔2或3天,则要对p1[d, 0] 与 p1[d - 2, 0]进行比较
if (p1[d, 0] != p1[d -1, 0] && p1[d, 0] != p1[d -1, 1] && p1[d, 1] != p1[d -1, 0] && p1[d, 1] != p1[d -1, 1])
{
int i =0;
for (; i < d; i++)//这里通过查找已经比赛的记录看当天比赛双方有没有比赛过
{
//相同两队比赛过则不能再次比赛
if (p1[d, 0] == p1[i, 0] && p1[d, 1] == p1[i, 1])
{
break;
}
}
if (i == d)
returntrue;
else
returnfalse;
}
else
returnfalse;
}
}
#endregion
#region//按要求计算出比赛日程 d是从第几天开始比赛
publicvoid Start(int d)
{
if (d < days)
{
for (int i =0; i < days; i++)
{
p1[d, 0] = p[i, 0];
p1[d, 1] = p[i, 1];
if (check(d))
{
if (d <= days -1)
{
Start(d +1);
}
}
else
{
continue;
}
if (d == days-1)//如果找到了合适的日程则输出
{
if(p[0,1].ToString()!="")
Show();
// break;
}
}
}
}
#endregion
#region//显示相符的比赛日程
publicvoid Show()
{
Console.Write("-----------------------------------解决方案------------------------------------\n");
for (int i =0; i < days; i++)
{
Console.Write("第{0}天---------------------------{1}号对阵{2}号",(i+1).ToString(),p1[i,0].ToString(),p1[i,1].ToString());
Console.Write("\n");
if (i >=300)//这里防止球队数量过多时,只显示解决方案的一部分
Thread.Sleep(1000);
}
//这里表示找到一种解决方案就停止,因为多种解决方案,只是球队的序号不一样而已,只要最开始球队排序中改变就可以了
Console.ReadKey();
}
#endregion
}

在呈现输出端代码:

staticvoid Main(string[] args)
{
Math M =new Math();
M.Start(0); //从第一天开始找出合适的方案
Console.ReadKey();
}

输入5输出结果:



总结:这道题的思路就是先找出整个过程中的变量,条件已经很清楚,而这个变量就如同 高中数学中几何题中的辅助线一样重要,变量找的对与否或者好不好,直接关系这个问题解决的情况,而这个变量有时不是一眼就找到的,有时要换算下,正如上面的所有比赛列表,这个变量是通过二维数组事先存起来的方便后面条件的应用。

正如同上一篇说到的变量与条件在解决问题的关键性 对于一道经典程序算数题的启发

PS:如果有更好的解决方案可以提出啊,共同学习啊。。。

试试做个推广:手赚联盟http://shouzhuan.org
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐