XTU-OJ 《C语言程序设计》 1297-Homework

题目描述

鉴于很多同学Ctrl+A,Ctrl+C,Ctrl+V的问题,Eric想重新计算一下作业成绩,成绩计算的规则如下:

  1. 每道题按正确提交的先后顺序给分,第1-12名32,13-24名16分,25-48名8分,49-96名4分,97-192名2分,其余1分。
  2. 学生所有题目的分数累加和为其积分。
  3. 作业成绩=round(100+log(1+本人积分−最高积分最高积分)×10),其中round为四舍五入取整,log以自然对数为底。

Eric已经通过查询数据库得到每个人每道题的排名情况,请写一个程序帮Eric算一下所有人的作业成绩。

输入

输入包含若干行,每行是三个部分,题目号,学号,排名。
学生人数不超过500,题目数量不超过200。

输出

输出学号和成绩,按成绩逆序,学号,并按作业成绩逆序,学号正序排列显示。

样例输入

1054 2015551111 1
1054 2015551101 2
1054 2015551119 3
1054 2015551115 4
1054 2015551110 5
1054 2015551114 6
1054 2015551128 7
1054 2015551118 8
1054 2015551102 9
1054 2015551130 10
1054 2015551139 11
1054 2015551135 12
1054 2015551120 13
1054 2015551129 14
1054 2015551104 15
1054 2015551112 16
1054 2015551116 17
1054 2015551138 18
1054 2015551103 19
1054 2015551131 20
1054 2015551132 21
1054 2015551106 22
1054 2015551136 23
1054 2015551124 24
1054 2015551126 25
1054 2015551113 26
1054 2015551109 27
1054 2015551117 28
1054 2015551125 29
1054 2015551127 30
1054 2015551123 31
1054 2015551133 32
1054 2015551134 33
1054 2015551121 34
1054 2015551122 35
1054 2015551137 36

样例输出

2015551101 100
2015551102 100
2015551110 100
2015551111 100
2015551114 100
2015551115 100
2015551118 100
2015551119 100
2015551128 100
2015551130 100
2015551135 100
2015551139 100
2015551103 93
2015551104 93
2015551106 93
2015551112 93
2015551116 93
2015551120 93
2015551124 93
2015551129 93
2015551131 93
2015551132 93
2015551136 93
2015551138 93
2015551109 86
2015551113 86
2015551117 86
2015551121 86
2015551122 86
2015551123 86
2015551125 86
2015551126 86
2015551127 86
2015551133 86
2015551134 86
2015551137 86

解题思路:大伙不要被题目看起来就很难给吓到,其实很简单,就是有一点点麻烦,但也不多。 

1:这种先一直输入,输入完了再处理的题,和多样例输入一样,稍微变换一下就好了。 (看代码),自己本地测试运行代码的时候,可以用  Ctrl + Z   手动终止输入。 

2: 题目中的数学公式,在头文件 <math.h> 里可以直接用。

3: 在进行公式计算的时候,记得用 浮点数进行运算。

AC代码:

结构体、字符比较、快排多级排序。

#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>

struct stu
{
   int grade;
   char Id[15];
}sData[520];


int cmp(const void* p1, const void* p2) {
   if (((stu*)p2)->grade != ((stu*)p1)->grade)
		return ((stu*)p2)->grade - ((stu*)p1)->grade; 
   return strcmp(((stu*)p1)->Id,((stu*)p2)->Id);
}

int Switch(int x)
{

    if ( x >= 1  && x <=12)         return 32;
    else if ( x >= 13 && x <=24)    return 16;
    else if ( x >= 25 && x <=48)    return 8;
    else if ( x >= 49 && x <=96)    return 4;
    else if ( x >= 97 && x <=192)   return 2;
    else                            return 1;
}

int main()
{
   int i,title,rank,num = 0;
   double maxscor = 0;
   while (scanf("%d %s %d",&title,sData[num].Id,&rank) != EOF)
   {
      for (i = 0; i <= num; i ++)                  
         if (!strcmp(sData[i].Id,sData[num].Id))      break;
      sData[i].grade += Switch(rank);

      if (sData[i].grade > maxscor)          maxscor = sData[i].grade;
      if (i == num)  num ++;
   }

   for (i = 0; i < num; i ++)                // 公式运算
   {
      double scor = log(1.0+(sData[i].grade - maxscor)/maxscor)*10.0;
      sData[i].grade = round(100.0 + scor);
   }

   qsort(sData,num,sizeof(stu),cmp);         // 排序(这里用的 快排)
   for (i = 0; i < num; i ++)
      printf("%s %d\n",sData[i].Id,sData[i].grade);
   return 0;
}

以前的代码


#include <stdio.h>
#include <math.h>

__int64     ID[520] = {0};
int  Grade[520] = {0};    

int total(int x)
{
    int g; 
    if ( x >= 1  && x <=12)            g=32;
    else if ( x >= 13 && x <=24)    g=16;
    else if ( x >= 25 && x <=48)    g=8;
    else if ( x >= 49 && x <=96)    g=4;
    else if ( x >= 97 && x <=192)   g=2;
    else if ( x >= 193)             g=1;
    return g;
}

void swap(int x,int y)
{
    int t = Grade[x];
    Grade[x] = Grade[y];
    Grade[y] = t;
    __int64 p = ID[x];
    ID[x] = ID[y];
    ID[y] = p;
}

int main()
{
    int bank,num=1,rank;
    while ( scanf("%d %I64d %d",&bank,&ID[num],&rank) != EOF)  //输入数据 
    {
        int i;
        for ( i = 1; i <= num; i ++)
            if (ID[i] == ID[num])   break;
        Grade[i] += total(rank);     //把排名转换成积分保存下来 
        if ( i == num ) num ++;
    }
    
    for (int i = 1; i < num; i ++)   //积分高低排序
        for (int j = i+1; j <= num; j ++)
             if (Grade[i] < Grade[j] )   swap(i,j);
     
    double max_fen = Grade[1];   // 积分转换为成绩
    for (int i = 1; i < num; i ++)
    {
        double xx = log(1.0+(Grade[i]-max_fen)/max_fen)*10.0;
        Grade[i] = round(100.0+xx);
    }

    for (int i = 1; i < num; i ++)  // 在相同积分下,对学号排序
    {
        int k = i;
        while (Grade[i] == Grade[i+1])  i++;
        for (int j = k; j < i; j ++)
            for (int l = j+1; l <= i; l ++) 
                if (ID[j] > ID[l])  swap(j,l);
    }
 
    for (int i = 1; i < num; i ++)
        printf("%I64d %d\n",ID[i],Grade[i]);
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值