-
题目描述:
-
今天的上机考试虽然有实时的Ranklist,但上面的排名只是根据完成的题数排序,没有考虑每题的分值,所以并不是最后的排名。给定录取分数线,请你写程序找出最后通过分数线的考生,并将他们的成绩按降序打印。
-
输入:
-
测试输入包含若干场考试的信息。每场考试信息的第1行给出考生人数N ( 0 < N < 1000 )、考题数M ( 0 < M < = 10 )、分数线(正整数)G;第2行排序给出第1题至第M题的正整数分值;以下N行,每行给出一名考生的准考证号(长度不超过20的字符串)、该生解决的题目总数m、以及这m道题的题号(题目号由1到M)。
当读入的考生人数为0时,输入结束,该场考试不予处理。
-
输出:
-
对每场考试,首先在第1行输出不低于分数线的考生人数n,随后n行按分数从高到低输出上线考生的考号与分数,其间用1空格分隔。若有多名考生分数相同,则按他们考号的升序输出。
-
样例输入:
-
4 5 25 10 10 12 13 15 CS004 3 5 1 3 CS003 5 2 4 1 3 5 CS002 2 1 2 CS001 3 2 3 5 1 2 40 10 30 CS001 1 2 2 3 20 10 10 10 CS000000000000000001 0 CS000000000000000002 2 1 2 0
-
样例输出:
-
3 CS003 60 CS001 37 CS004 37 0 1 CS000000000000000002 20
AC代码:
#include <stdio.h>
#include<string.h>
#include<stdlib.h>
typedef struct info{
char num[21];
int mark[12];
int final;
}Info;
int cmp(const void *a,const void *b){
Info x=*(Info*)a;
Info y=*(Info*)b;
if(x.final !=y.final) return x.final<y.final;
else
return strcmp(x.num,y.num);
}
int main(){
int n,m,g;
int mpoint[11]={0};
Info *infos;
while(1){
scanf("%d",&n);
if(n==0) return 0;
scanf("%d %d",&m,&g);
int i;
for(i=1;i<m+1;i++) scanf("%d",&mpoint[i]);
infos=(Info*)calloc(n,sizeof(Info));
int j;
for(j=0;j<n;j++){
int l;
for(l=0;l<11;l++)infos[j].mark[l]=0;
infos[j].final=0;
scanf("%s %d",infos[j].num,&infos[j].mark[0]);
int temp,k;
for(k=0;k<infos[j].mark[0];k++){
scanf("%d",&temp);
infos[j].final +=mpoint[temp];
}
if(infos[j].final <g) infos[j].final=0;
}
int count=0;
for(i=0;i<n;i++){
if(infos[i].final !=0) count++;
}
qsort(infos,n,sizeof(Info),cmp);
printf("%d\n",count);
for(i=0;i<n;i++){
if(infos[i].final !=0)
printf("%s %d\n",infos[i].num,infos[i].final);
}
}
free(infos);
return 0;
}
最开始,我不知道还有qsort这种好东西,自己排的序,自己测试通过了题目给的测试用例,但是一直报runtime error。现在也没搞清楚是哪里的问题,应该还是排序那的问题。如下(恳请大佬们指点):
#include <stdio.h>
#include<string.h>
#include<stdlib.h>
typedef struct info{
char num[21];
int mark[12];
int final;
int flag;
}Info;
int main(){
int n,m,g;
int mpoint[11]={0};
Info *infos;
while(1){
scanf("%d",&n);
if(n==0) return 0;
scanf("%d %d",&m,&g);
int i;
for(i=1;i<m+1;i++) scanf("%d",&mpoint[i]);
//struct info *infos;
infos=(Info*)calloc(n,sizeof(Info));
int j;
for(j=0;j<n;j++){
int l;
for(l=0;l<11;l++)infos[j].mark[l]=0;
infos[j].final=0;
infos[j].flag=1;
scanf("%s %d",infos[j].num,&infos[j].mark[0]);
int temp,k;
for(k=0;k<infos[j].mark[0];k++){
scanf("%d",&temp);
infos[j].final +=mpoint[temp];
}
if(infos[j].final <g) infos[j].final=0;
}
int *accept;
int count=0;
accept=(int*)calloc(n,sizeof(int));
int temp=0;
char tempstr[20];
for(i=0;i<n;i++){
if(infos[i].final !=0) count++;
for(j=0;j<n;j++){
if(infos[j].flag && infos[j].final>temp){
accept[i]=j;
temp=infos[j].final;
strcpy(tempstr,infos[j].num);
}else if(infos[j].flag && infos[j].final==temp){
if(strcmp(tempstr,infos[j].num)){
accept[i]=j;
strcpy(tempstr,infos[j].num);
}
}
}
temp=0;
infos[accept[i]].flag=0;
}
printf("%d\n",count);
for(i=0;i<n;i++){
if(infos[accept[i]].final !=0)
printf("%s %d\n",infos[accept[i]].num,infos[accept[i]].final);
}
}
free(infos);
return 0;
}
/**************************************************************
Problem: 1014
User: 人气呆毛选手
Language: C
Result: Runtime Error
****************************************************************/
最最开始,自己在vc上通过了那几个测试用例,就提交上oj,一直提示compile error。后来苦苦查询,发现是结构体定义的问题
小小的总结
1.结构体
在C语言里定义一个结构体有如下方式:
//保险的用法
typedef struct info{
char num[21];
int mark[12];
int final;
int flag;
}Info;//Info是这个结构体的别名,还可以写多个别名
Info *infos;
infos=(Info*)calloc(n,sizeof(Info));
不负责任的写法如下(逃。。。。:
//but!!!!如果只写成这样
typedef struct info{
char num[21];
int mark[12];
int final;
int flag;
};
info a;
//vc6.0会警告一下,如下,但还是能用
//warning C4091: 'typedef ' : ignored on left of 'struct info' when no variable is declared
//但gcc似乎就不行了,因为我开始这样 ,就在九度oj上compile error了
如果不用typedef,写法如下:
//VC 下没有问题
struct info{
int final;
int flag;
}Info;//这个别名可以不写
struct info a={1,2};
struct info b={4,5};
info a={1,2};//VC下通过了
a=b//这都可以
//but!!!!
//Info a={1,2};//'a' : undeclared identifier,说明Info 不是别名
//struct Info a={1,2};//'a' uses undefined struct 'Info',也不是别名
//Info={6,7};//也报错,说明也不是一个定义好的结构体
//所以我真的不知道那个Info是用来干什么的
//但看其他的博客是可以 struct Info a={1,2};
//等会回去翻一翻书吧
2.动态内存分配
常常会遇到,先让用户输入一个数字,再根据这个数字创建一个数组什么的,这个时候就要用到malloc,calloc,realloc了。
int *p,*q;
p=(int*)malloc(10);//10byte,p指向这块地址的起始处,不会初始化,应该是开辟了一块大于10byte的空间的,和后面的q不一定是连续的
printf("0x%x\n",p);
q=(int*)calloc(1,sizeof(4));//会初始化为0,第一个参数是分配几个元素,第二个是每个元素的大小
p=(int*)realloc(p,14);//从p开始的位置开始往后分配14个
free(p);
free(q);
3.输入
针对九度oj上的题来说,常常会以输入数据0作为循环输入结束的标识,我常常看到大家用类似这样的写法
while(scanf("%d",&a)!=EOF){
if(a==0) return 0;
printf("print--%d\n",a);
}
就我做的的九度上的题而言,我个人感觉下面这样简单些:
while(scanf("%d",&a) && a){
printf("print--%d\n",a);
}
4.C语言自带的qsort函数
头文件是#include<stdlib.h>,原型是酱紫:
void qsort( void *base, size_t num, size_t width, int (__cdecl *compare )
//参数 base 是 需要排序的目标数组名(或者也可以理解成开始排序的地址,因为可以写&s[i]这样的表达式)
//参数 num 是 参与排序的目标数组元素个数
//参数 width 是单个元素的大小(或者目标数组中每一个元素长度),推荐使用sizeof(s[0])这样的表达式
//参数 compare 决定升序还是降序
int compare (const void *elem1, const void *elem2 ) );
对 int 排序:
int cmp(const void *a,const void *b);
int main(){
int s[10];
int len=10;
int i;
for(i=0;i<len;i++){
scanf("%d",&s[i]);
}
qsort(s,len,sizeof(s[0]),cmp);
for(i=0;i<len;i++)
{
printf("%d\n",s[i]);
}
system("pause");//头文件是#include<stdlib.h>
return 0;
}
int cmp(const void *a,const void *b){
return *(int*)a-*(int*)b;//这是升序,降序就b-a
}
对char排序:
int main(){
char s[20];
int len=10;
int i;
/*for(i=0;i<len;i++){
scanf("%c",&s[i]);//会把换行符也读进去
}*/
scanf("%s",s);
qsort(s,len,sizeof(s[0]),cmp);
for(i=0;i<len;i++)
{
printf("%c\n",s[i]);
}
system("pause");
return 0;
}
int cmp(const void *a,const void *b){
return *(char*)a-*(char*)b;
}
对结构体排序,就参照我的AC代码里。
-
好,暂时就酱紫啦。下一题,赶快下一题,最近进度太慢了!!!