用程序解决一个实际问题---n支球队进行单循环比赛,每天一场,给出一个比赛日程,使每支球队在两场比赛之间至少间隔一天
2010-11-30 11:44
936 查看
对于这个问题,首先将n具体化,比如我先把n定义为5,首先第一步要对队伍编号从0~4,那么这5支球队共要比赛多少天可以知道用组合C25 这个符号不会用,也就是n(n-1)/2,5支球队就要比赛10天,然后将所有可能的比赛先列出来
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
0 | 1 | 2 | 3 | 4 |
代码
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
相关文章推荐
- 使用VS进行打包程序解决生成两个文件的问题(压缩后只有一个exe)
- 在股市的交易日中,假设最多可进行两次买卖(即买和卖的次数均小于等于2),规则是必须一笔成交后进行另一笔(即买-卖-买-卖的顺序进行)。给出一天中的股票变化序列,请写一个程序计算一天可以获得的最大收益。
- Unity之一天一个技术点(五)---解决U3D程序“按下休眠键时退出程序”的问题
- 初学ASP编程易犯的一个致命程序问题及解决办
- 一个用程序解决数学问题的网站
- 今天一天解决了一个 ph56w-opcache问题 (yum 命令方式)
- 针对linux课本的一个程序,反映出来的问题(留有问题没解决)
- 一个实际问题分析及解决之三:websphere中SSL配置及使用
- 迷宫问题--第一次写的一个算是大点的程序吧……用了接近一天……
- 一个tomcat下执行java程序报错问题的解决
- 两个乒乓球队进行比赛,各出三人。甲队为A、B、C 3人,乙队为X、Y、Z 3人。已抽签决定比赛名单。有人向队员打听比赛的名单,A说他不和X比,C说他不和X、Y比,请编程序找出3三队选手的对阵名单。
- 逻辑题:题目:两个乒乓球队进行比赛,各出三人。甲队为a,b,c三人,乙队为x,y,z三人。已抽签决定比赛名单。有人向队员打听比赛的名单。a说他不和x比,c说他不和x,z比,请编程序找出三队赛手的名单
- 使用eclipse进行Android编程发生崩溃的一个问题及解决办法
- Java 用Jackson进行json和object之间的转换(并解决json中存在新增多余字段的问题)
- 完成一个GUI应用程序,一个窗口中含有4个按钮,两个label,按照流式布局器进行布局,每个组件之间间隔20px,居右对齐。
- perl 问题解决:一个有多个perl安装程序的机器环境上运行程序的问题
- 【程序17】 题目:猴子吃桃问题:猴子第一天摘下若干个桃子,当即吃了一半, 还不瘾,又多吃了一个 第二天早上又将剩下的桃子吃掉一半, 又多吃了一个。以后每天早上都吃了前一天剩下的一半零一个。
- 练习1-21 编写程序entab,将空格串替换成最少数量的制表符和空格,但要保持单词之间的间隔不变。假设制表符终止位的位置与练习1-20的detab程序的情况相同。当使用一个制表符或者一个空格都可以到达下一个制表符终止位时,选用哪种替换字符比较好。
- 一个实际问题分析及解决之四:通过IBM的JDK建立SSL连接
- 一个关于时间的故事(通过历史分析解决程序问题)