问题 问答题

【说明】 某超市集团为发展业务向社会公开招聘N个工种的工作人员,每个工种各有不同的编号(1至M)和计划招聘人数。每位应聘者需申报两个工种,并参加集团组织的考试。该集团公司将按应聘者的成绩从高分至低分的顺序进行排队录取。具体录取原则是:从高分到低分依次对每位应聘者先按其第一志愿录取;当不能按其第一志愿录取时,便将他的成绩扣去5分后,重新排队,并按其第二志愿录取。 以下C程序为输出各工种实际招聘的应聘人员,每个工种都保留一个录取者的有序队列。录取处理循环直至招聘额满或已对全部应聘者都作了录取处理后跳出。 C程序中,类型STU包含有应聘者的基本信息:编号、成绩、志愿、排队成绩和录取志愿号。数组 rzl)的每个元素对应一个工种,包含有计划招聘人数和已录取的人数。【C程序】#include#define N 36#define EDMARK 5typedef struct stu { int no, total, z[2], sortm, zi; struct stu *next;} STU;struct rznode { int lmt, count; STU *next;} rz [N];STU *head = NULL, *over = NULL;int allFILE *fp;char dataf [ ] = "zp2008.dat" ;print(STU *p){ for (;p!=NULL; p = p->next) printf( "%d(%d) \t" , p->no, p->total}insert(STU **p, STU *u){ STU *v, *q; for (q = *p;q != NULL; v = q , (1) ) if (q-> sortm < u->sortm) break; if ( q == *p) (2) ; else (3) ; u->next = q ;}main ( ){ int zn, i, no, total, zl, z2 ; STU *p, *v, *q; fp = fopen(dataf, "r" ); if (fp == NULL) { printf ("Can’t open file %s.kn" ,dataf); exit (0); } fscanf (fp, "%d" ,&zn); for (all = 0, i = 1; i <= zn; i++) { fscanf (fp, "%d", &rz [ i ].lmt ; rz[i].count = 0; rz[i].next = NULL; all += (4) ; } for (;;) { if (( fscanf(fp, "%d%d%d%d" ,&no,&total,&zl,&z2)) != 4 ) break; p = ( STU *) malloc (sizeof (STU)); p->no = no; p->total = p->sortm = total; p->zi = 0; p->z[0] = z1; p->z[1] = z2; (5) ; } fclose (fp); for (;all && head != NULL;) { p = head; head = head->next; if (rz[p->z[p->zi]].count < (6) ) { rz[p->z[p->zi]].count ++; insert(&rz[p->z[p->zi]].next,p); all--; continue; } if (p->zi >= 1 ) { p->next = over; over = p; continue; } p->sortm -= DEMARK; (7) ; insert(&head,p); } for (i = 1; i <= zn; i++ ) { printf("%d:\n" ,i); print( rz[i ].next); printf(" \n"); } printf( "over:\n" ); print(head); print(over); printf(" \n");}

答案

参考答案:

解析:(1)q=q->next或q=v->next或其等价的代码形式 (2)*p=u或其等价的代码形式 (3)v->next=u或其等价的代码形式 (4)rz[i].1mt (5)insert(&head,p) (6)rz[p-,[p->zi)].1mt或其等价的代码形式 (7)p->zi++或p->zi=1,或其等价的代码形式[要点解析] 这是一道要求读者掌握队列应用的程序设计题。本题的解答思路如下。 该C程序由主函数main、打印函数print及表元插入函数insert组成。主函数main首先打开数据文件,读入各工种需招聘的人数并统计总招聘人数。再读入应聘者信息,并调用函数insert按成绩排队,应聘者信息全部读入后,按照第一志愿录取。如果不能按照第一志愿录取招聘者,则将其成绩扣去5分,按照第二志愿录取。最后输出各工种招聘结果。 函数insert的功能是根据指针u所指单元的排队成绩,将此表元插入队列。p为指向队列首的指针。 (1)空缺处在此函数的for循环中,由队首开始查找,每次需要保存指向当前表元的指针,并更改指向当前表元的指针,(1)空缺处之前的语句“v=q”是保存指向当前表元的指针,因此该空缺处所填入的更改指向当前表元指针的语句是“q=q->next(或q=v->next)”或其等价的代码形式。 当找到排队成绩小于u所指表元或已查找至队尾时,就要将u所指表元插入队列。如果此表元需插在队首,则需更改队首的指针,即(2)空缺处所填写的内容是“*p=u”或其等价代码形式:否则,需要根拥保存的前驱表元指针来进行插入操作,即(3)空缺处所填写的内容是“v->next=u”或其等价的代码形式。 主函数main首先将各丁种录取队列设为空队列,并统计总招聘人数。(4)空缺处所在的语句是统计总招聘人数,方法为招聘各工种人数进行累加,因此(4)空缺处所填写的内容是“rz[i].1mt”。 (5)空缺处所在的for循环功能是:读入应聘者信息,形成表元,并按成绩插入队列。其中,插入是通过调用函数insert实现的,因此(5)空缺处所填入的内容是“insert(&head,p)”。 形成队列成绩后,开始按成绩和志愿决定聘用者。如果当前应聘者的志愿工种未招满,则聘用此应聘者,并将此工种已聘用人数加1,且将此聘用者信息加入工种录取队列。(6)空缺处所在判断条件的功能是:判断志愿工种是否己招满。如果志愿工种己招满,则根据此志愿是否是第一志愿来进一步划分。如果是第一志愿,则将成绩扣5分,再插入应聘者队列,考虑第二志愿;否则将此应聘者移入不录取队列。因此(6)空缺处所填写的内容是“rz[p->[p->zi]].1mt”。 (7)空缺处所填入语句的功能是,将志愿工种置为第二工种,应填入“p->zi++”或“p->zi=1”或其他等价的代码形式。

解答题
填空题