2000.9请你编程

Author: Date: 2000年 第35期

  大家好!《请你编程》又与你们见面了。《请你编程》得到了广大朋友的关心和支持,我在这里表示衷心的感谢。《请你编程》是一个读者朋友直接参与的栏目,是一个体现自我的园地,希望有编程愿望的朋友,无论是编程高手,还是初学者都能参与进来,我们将会认真对待每一份作品。下面请看2000.5期湖南读者肖雁鹏的程序。
  本人用Turbo C2.0实现了题目的要求,解题思路如下:
  1.先读入全部数据,找到单项分数最高的人和位置,让该队员打对应位置。然后设法让该队员不再可选,(这里将他的单项分数全赋为-1)。
  2.如果防守、组织和进攻中某位置人员已经选齐,则将该位置的分数全部赋为-1,(保证该位置的分数不再参与选择)。如果选择没有完成则转向第1步。这样就能利用每个队员的最强项,符合题目要求。
#1    源程序
  #include ″stdio.h″
  #define NMAX 200 /*设最多有200个队员参选*/
  main()
  {FILE *fp;
  int member[NMAX][4],total,n,max,currow,curcol,i,j;/*队员分数用member二维数组描述*/
  static char *string[4]={″″,″防守″,″组织″,″进攻″};
  static char name[NMAX][20]; /*设名字最长20个字符*/
  if((fp=fopen(″football.txt″,″r″))==NULL)
  {printf(″\ncan not open the football.txt″);
  exit(0);}
  fscanf(fp,″%d %d %d %d″,&n,&member[0][1],&member[0][2],&member[0][3]);/*第零行存放A,B,C*/
  for(i=1;i<=n;i++)
  fscanf(fp,″%s %d %d %d″,name[i],&member[i][1],&member[i][2],&member[i][3]);
  /*打开文件,读出全部数据。为清晰起见,第零列没有使用*/
  total=0;
  while(member[0][1]>0||member[0][2]>0||member[0][3]>0)/*如果未选完则循环继续*/
  {max=member[1][1];
  for(i=1;i<=n;i++)
  for(j=1;j<=3;j++)
  {if( max<member[i][j])
  {max=member[i][j];
  currow=i;
  curcol=j;}}/*选出最有利的分数*/
   printf(″\n%s:%s:%d″,name[currow],string[curcol],member[currow][curcol]);
  /*打印被选出的队员的信息*/
  total=total+member[currow][curcol]; /*累加总分*/
  for(i=1;i<=3;i++)
  member[currow][i]=-1;
  member[0][curcol]--; /*删除被选出的队员*/
  for(i=1;i<=3;i++)
  {if (member[0][curcol]==0)
  {for(j=1;j<=n;j++)
  member[j][curcol]=-1;}} /*如果该位置已满则删除该位置(即该列)全部信息*/}
  printf(″\n阵法总分=%d″,total);}
    本期请你编程题目
  愚人国议会
  这个月愚人国召开议会。议会由N人组成,分为K个组,每个组的人数都不相同。每天,他们从每个组中选举出一人,组成愚人国议会的“调和委员会”。愚人议员们要求每天的调和委员会的组成都不同,否则议会将解散。
  现在的问题是,如何对议会进行分组,使得议会能持续最长的时间而不被解散。
  输入:N
  输出:各组中的人数。要按升序排列。