题目:
宋代史学家司马光在《资治通鉴》中有一段著名的“德才论”:“是故才德全尽谓之圣人,才德兼亡谓之愚人,德胜才谓之君子,才胜德谓之小人。凡取人之术,苟不得圣人,君子而与之,与其得小人,不若得愚人。”
现给出一批考生的德才分数,请根据司马光的理论给出录取排名。
输入格式:
输入第一行给出 3 个正整数,分别为:N(≤105),即考生总数;L(≥60),为录取最低分数线,即德分和才分均不低于 L 的考生才有资格被考虑录取;H(<100),为优先录取线——德分和才分均不低于此线的被定义为“才德全尽”,此类考生按德才总分从高到低排序;才分不到但德分到线的一类考生属于“德胜才”,也按总分排序,但排在第一类考生之后;德才分均低于 H,但是德分不低于才分的考生属于“才德兼亡”但尚有“德胜才”者,按总分排序,但排在第二类考生之后;其他达到最低线 L 的考生也按总分排序,但排在第三类考生之后。
随后 N 行,每行给出一位考生的信息,包括:准考证号 德分 才分
,其中准考证号
为 8 位整数,德才分为区间 [0, 100] 内的整数。数字间以空格分隔。
输出格式:
输出第一行首先给出达到最低分数线的考生人数 M,随后 M 行,每行按照输入格式输出一位考生的信息,考生按输入中说明的规则从高到低排序。当某类考生中有多人总分相同时,按其德分降序排列;若德分也并列,则按准考证号的升序输出。
我的答案(c语言):
#include <stdio.h>
#include <stdlib.h>
//学生链表
typedef struct xuesheng
{
long int zhunkaozheng;
int de,cai;
struct xuesheng* next;
}xuesheng,*xueshenglist;
//求合格人数,并把不合格的人删除
void fun1(xueshenglist s,int l)
{
int count=0;算出合格人数,并把不合格的人删除
xuesheng* t;
xuesheng* p;
t=s->next;
while(t)
{
if((t->de<l)||(t->cai<l))
{
p=t->next;
t->zhunkaozheng=t->next->zhunkaozheng;
t->de=t->next->de;
t->cai=t->next->cai;
t->next=t->next->next;
free(p);
}
else
{
count++;
t=t->next;
}
}
printf("%d\n",count);
}
//清空w
void vacue(xueshenglist w)
{
xuesheng* temp1;
xuesheng* temp2;
temp1=w->next;
while(temp1)
{
temp2=temp1;
temp1=temp1->next;
free(temp2);
}
w->next=NULL;
}
//排序,按照总分排序,若总分一样,就按照得分顺序
void sort(xueshenglist w)
{
int dde,dcai;
long int dzhunkaozheng;
xuesheng* d;
int max;
int now;
d=w->next;
xuesheng* f;
f=d;
while(d)
{
max=d->de+d->cai;
while(f)
{
now=f->de+f->cai;
if((now>max)||((now==max)&&(f->de>d->de))||((now==max)&&(f->de==d->de)&&(f->zhunkaozheng<d->zhunkaozheng)))
{
dde=d->de;
dcai=d->cai;
dzhunkaozheng=d->zhunkaozheng;
d->de=f->de;
d->cai=f->cai;
d->zhunkaozheng=f->zhunkaozheng;
f->de=dde;
f->cai=dcai;
f->zhunkaozheng=dzhunkaozheng;
}
f=f->next;
max=d->de+d->cai;
}
d=d->next;
f=d;
}
}
//输出
void out(xueshenglist w)
{
xuesheng* t1;
t1=w->next;
while(t1)
{
printf("%ld %d %d\n",t1->zhunkaozheng,t1->de,t1->cai);
t1=t1->next;
}
}
//将所有德才都好的人搬迁到新的链表w,并照总分排序,若总分一样,德分高的排前面
void fun2(xueshenglist w,xueshenglist s,int h)
{
xuesheng* d;
d=s->next;
xuesheng* t1;
while(d)
{
if((d->de>=h)&&(d->cai>=h))
{
t1=(xuesheng*)malloc(sizeof(xuesheng));
t1->zhunkaozheng=d->zhunkaozheng;
t1->de=d->de;
t1->cai=d->cai;
t1->next=w->next;
w->next=t1;
}
d=d->next;
}
d=s->next;
while(d)
{
if((d->de>=h)&&(d->cai>=h))
{
t1=d->next;
d->de=d->next->de;
d->cai=d->next->cai;
d->zhunkaozheng=d->next->zhunkaozheng;
d->next=d->next->next;
free(t1);
}
else
{
d=d->next;
}
}
sort(w);
out(w);
}
将s中的德好的人,但才不好且及格的人搬入w,并按照总分排序,若总分一样,那么按照德分排序
void fun3(xueshenglist s,xueshenglist w,int h)
{
xuesheng* temp1;
xuesheng* temp2;
temp1=s->next;
while(temp1)
{
if((temp1->de>=h)&&(temp1->cai<h))
{
temp2=(xuesheng*)malloc(sizeof(xuesheng));
temp2->de=temp1->de;
temp2->cai=temp1->cai;
temp2->zhunkaozheng=temp1->zhunkaozheng;
temp2->next=w->next;
w->next=temp2;
}
temp1=temp1->next;
}
temp1=s->next;
while(temp1)
{
if((temp1->de>=h)&&(temp1->cai<h))
{
temp2=temp1->next;
temp1->de=temp1->next->de;
temp1->cai=temp1->next->cai;
temp1->zhunkaozheng=temp1->next->zhunkaozheng;
temp1->next=temp1->next->next;
free(temp2);
}
else
{
temp1=temp1->next;
}
}
sort(w);
out(w);
}
将s中的德才都不好但都及格了、德分>=才分的人移动到w,按照总分排序,总分一样的德分高的排前面,并输出
void fun4(xueshenglist s,xueshenglist w,int h)
{
xuesheng* temp1;
temp1=s->next;
xuesheng* temp2;
while(temp1)
{
if((temp1->de<h)&&(temp1->cai<h)&&(temp1->de>=temp1->cai))
{
temp2=(xuesheng*)malloc(sizeof(xuesheng));
temp2->de=temp1->de;
temp2->cai=temp1->cai;
temp2->zhunkaozheng=temp1->zhunkaozheng;
temp2->next=w->next;
w->next=temp2;
}
temp1=temp1->next;
}
temp1=s->next;
while(temp1)
{
if((temp1->de<h)&&(temp1->cai<h)&&(temp1->de>=temp1->cai))
{
temp2=temp1->next;
temp1->de=temp1->next->de;
temp1->cai=temp1->next->cai;
temp1->zhunkaozheng=temp1->next->zhunkaozheng;
temp1->next=temp1->next->next;
free(temp2);
}
else
{
temp1=temp1->next;
}
}
sort(w);
out(w);
}
//将其他学生排序输出
void fun5(xueshenglist s)
{
sort(s);
out(s);
}
int main()
{
int n,l,h;
scanf("%d %d %d",&n,&l,&h);
xueshenglist s;//头指针
s=(xueshenglist)malloc(sizeof(xuesheng));//创建头节点
s->next=NULL;//初始为空链表
xuesheng* temp;
for(int i=0;i<n;i++)头插法输入数据
{
temp=(xuesheng*)malloc(sizeof(xuesheng));
scanf("%ld %d %d",&temp->zhunkaozheng,&temp->de,&temp->cai);
temp->next=s->next;
s->next=temp;
}
fun1(s,l);输出合格总人数,并把不合格的人删除
xueshenglist w;//头指针
w=(xuesheng*)malloc(sizeof(xuesheng));
w->next=NULL;
fun2(w,s,h);将s中的德才都好的人移动到w中,并排序输出
vacue(w);清空w下次使用
fun3(s,w,h);将s中的德好才不好但及格德人移动到w中,并排序输出
vacue(w);清空w
fun4(s,w,h);将s中的德才不好但及格、德胜才的人移动到w,并排序输出
fun5(s);将其他学生排序输出
return 0;
}
总结:这次我才用了单链表来做数据结构,练习了结构体节点的创建,单链表的基础操作(创建、删除、排序、输出,头插法输入),这道题虽然没有拿满分(段错误,现在还没改出来),但是夯实了我的链表操作技术,以后再写就不怕了。