C语言期末大作业之榜单打印

点击查看题目描述详情

题目描述:
给定一场ACM比赛的题目数量和提交列表,请你打印输出最终榜单。榜单的格式见输出和样例。
根据比赛规则,榜单有以下要求:

每道题的通过罚时按照分钟计算。每次未通过提交增加20分钟罚时,输入数据保证每个队伍罚时均小于10000分钟。到比赛结束都没有通过的题目不计入该队伍的罚时。
每队通过后的题目在榜单的题目栏中用“+”号显示。如果仅提交一次就通过了,则显示“+”。否则显示“+k”,k 为这个队伍对于这道题通过之前的总提交次数。输入数据保证  k 不大于 9。
每队提交但是未通过的题目在榜单的题目栏中用“-”号显示。显示“-k”,k 为这个队伍对于这道题的总提交次数。输入数据保证 k 不大于9。
每队没有提交的题目需要在榜单的该队的题目栏留空。
题目提交状态为“Compile Error”的提交不计入榜单。
对于某个队伍,在通过某个题目后再次提交该题目,则通过后的提交不计入榜单。
如果某个队伍没有提交,或者所有的提交均不计入榜单。则榜单上不显示该队伍。
题目提交状态为“Accepted”的提交表示本题正确通过,其它状态均表示未通过。

输入描述:

第一行一个数字 n(n≤14),表示这场比赛有 n 道题目,题目的标号从 A开始。
接下来若干行,每行格式形如:时间 题号 结果 队名,表示一条提交记录,提交记录按提交时间顺序排列。
其中,时间形如HH:MM,输入数据保证时间一定小于05:00。
题号为单独的一个大写字母。
结果属于集合 { Accepted, Wrong Answer, Time Limit Exceeded, Compile Error, Memory Limit Exceeded, Output Limit Exceeded, Runtime Error, Presentation Error }。
队名为一个含有空格、大写和小写字母的字符串,队名长度不超过 43。
输入以一行 “GAME OVER!” 结尾,表示比赛结束。

输出描述:

输出的榜单有 n+4栏,每栏之间间隔 2个空格。
Rank一栏的宽度为 4个字符,表示该队伍的排名。
Who一栏的宽度43个字符,表示该队伍的名字。
Solved一栏宽度为 6个字符,显示每个队伍通过题目的数量。
Penalty一栏宽度为 7个字符,按要求显示每队总用时(每题通过时间+有效的总罚时)。
接下来是题目栏,每个题目栏的宽度均为 3个字符,按要求显示“+”或“-”,表示每个队伍通过题目的情况。
每一栏的第一行为这一栏的名称,其中,Who需左对齐,其他栏需右对齐。
题目栏的名称为题目的标号。
接下来若干行,按顺序输出每个队伍的信息,每栏的信息需右对齐。
队伍按照通过题目数量排名,如果两队通过题目数量相等,总用时少的队伍排名靠前。
如果出现题数和罚时均相等的队伍,则按照队名的字典序排序,同时Rank一栏的值需相等。第一个与他们排名不相等的队伍的排名选择绝对排名,例如前五个队伍的排名分别为1、2、3、3、3,则第六个队伍的绝对排名为6。

在这里插入图片描述

废话不多说,直接上代码:

代码一:
(自己所写代码)

//任务10(大作业)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct team
{
    int rank;//该队伍的排名
    char Who[43];//队伍名
    int solved;//解题数
    int Penalty;//队伍所用总时间
    int time[14];//每道题解出的时间(分钟数)
    int trys[14];//每道题解出之前尝试的次数
}Team;
Team teamArr[100];
int teamCount;//队伍的个数
int n;//题目的个数
//根据队伍名在teamArr中查找有没有出现过
//出现过返回对应下标
//没有出现返回-1
//循环查找上限由teamCount决定
int findTeam(char * teamStr)
{
    int i;
    for(i=0;i<teamCount;++i)
    {
        if(strstr(teamArr[i].Who,teamStr)!=NULL)
            return i;
    }
    return -1;
}
int main(void)
{
    int t,tim;
    int i,j,a,b;
    int in;
    Team temp;
    char str[100],team[100];
    char * arr[8]={"Accepted"," Wrong Answer","Time Limit Exceeded",
                           "Compile Error","Memory Limit Exceeded",
                           "Output Limit Exceeded","Runtime Error",
                           "Presentation Error"};
    scanf("%d",&n);
    getchar();
    for(gets(str);strstr(str,"GAME OVER!")==NULL;gets(str))
    {
        //int in;
        if(str[1]-'5'==0) break;
        tim=((str[0]-'0')*10+str[1]-'0')*60+(str[3]-'0')*10+(str[4]-'0');
        t=str[6]-'A';
        for(i=0;i<8;++i){
            char *str1=str+8;
            char *rtn=strstr(str,arr[i]);
            if(rtn!=NULL) break;
        }
        if(str[8]-'W'==0)
            strcpy(team,str+8+strlen(arr[i]));
        else
            strcpy(team,str+9+strlen(arr[i]));
        if(i==3) continue;
        //判断当前记录的队伍有没有在前面出现过
        //若没有出现过则记录该队伍的名字
        in=findTeam(team);
        if(in ==-1){
            in=teamCount++;
            strcpy(teamArr[in].Who,team);
        }
        //teamArr[index];
        if(str[8]-'A'==0) {
            if(teamArr[in].time[t]!=0)
                continue;
            teamArr[in].solved ++;
            teamArr[in].time[t]=tim;
        }
        else{
            teamArr[in].trys[t]++;
        } 
    }
   //计算每支参赛队伍所用时间
    for(i=0;i<teamCount;++i)
    {
        for(j=0;j<n;++j)
        {
            if(teamArr[i].time[j]!=0){
                teamArr[i].Penalty+=teamArr[i].time[j];
                teamArr[i].Penalty+=teamArr[i].trys[j]*20;
            }
        }
    }
    //针对解题数、时间、队伍名称对参赛队伍进行冒泡排序
    for(i=0;i<teamCount-1;++i)
    {
        for(j=0;j<teamCount-1-i;++j)
        {
            if(teamArr[j].solved<teamArr[j+1].solved)
            {
                temp=teamArr[j];
                teamArr[j]=teamArr[j+1];
                teamArr[j+1]=temp;
            }
            else if(teamArr[j].solved==teamArr[j+1].solved)
            {
                if(teamArr[j+1].Penalty<teamArr[j].Penalty)
                {
                    temp=teamArr[j];
                    teamArr[j]=teamArr[j+1];
                    teamArr[j+1]=temp;
                }
                else if(teamArr[j].Penalty==teamArr[j+1].Penalty)
                {
                    if(strcmp(teamArr[j+1].Who,teamArr[j].Who)<0)
                    {
                        temp=teamArr[j];
                        teamArr[j]=teamArr[j+1];
                        teamArr[j+1]=temp;
                    }
                }
            }
        }
    }
    //计算队伍排名
    //解题数及时间都相同时排名相同
    teamArr[0].rank=1;
    for(a=1;a<teamCount;++a)
    {
        if(teamArr[a].solved==teamArr[a-1].solved && teamArr[a].Penalty==teamArr[a-1].Penalty)
            teamArr[a].rank=teamArr[a-1].rank;
        else
                teamArr[a].rank=a+1;
    }
    //打印结果:
    printf("Rank  Who                                          Solved  Penalty     ");
    for(b=0;b<n;++b)
    {
        printf("%c     ",b+'A');
    }
    printf("\n");
    for(i=0;i<teamCount;++i)
    {
        printf("%4d",teamArr[i].rank);//结果正确
        printf("  ");
        printf("%43s",teamArr[i].Who);//结果正确
        printf("  ");
        printf("%6d",teamArr[i].solved);//结果正确
        printf("  ");
        printf("%7d",teamArr[i].Penalty);//结果正确
        for(j=0;j<n;++j)
        {
            if(teamArr[i].trys[j]==0 && teamArr[i].time[j]!=0)
            {
                printf("     ");
                printf("+");
            }
            else if(teamArr[i].trys[j]!=0 && teamArr[i].time[j]!=0)
            { 
                printf("    ");
                printf("+%d",teamArr[i].trys[j]);
            }
            else if(teamArr[i].trys[j]!=0 && teamArr[i].time[j]==0)
            {  
                printf("    ");
                printf("-%d",teamArr[i].trys[j]);
            }
            else
                printf("      ");
        }
        printf("\n");
    }
    return 0;
}

代码二:
(参考答案代码)

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

typedef struct team {
    char who[44];   // 队伍名称
    int solved;     // 解题数
    int penalty;    // 总用时
    int title[14];  // 题目尝试次数
    int titleState[14];// 题目状态 0未通过 1通过
} Team;

typedef struct node {
    Team data;
    struct node * next;
} Node;

// 题目数量
int n = 0;
// 提交记录状态数组
char * states[8] = {
    "Accepted", 
    "Wrong Answer", 
    "Time Limit Exceeded", 
    "Compile Error", 
    "Memory Limit Exceeded",
    "Output Limit Exceeded",
    "Runtime Error",
    "Presentation Error"
};

/**
 *  链表中增加节点
 *  who : 队伍名
 *  return : 插入节点的地址
 */
Node * pushFrontList(Node ** pList, char * who) {
    int i;
    Node * newNode = (Node *)malloc(sizeof(Node));
    strcpy(newNode->data.who, who);
    newNode->data.solved = 0;
    newNode->data.penalty = 0;
    for(i=0; i<14; ++i) {
        newNode->data.title[i] = 0;
        newNode->data.titleState[i] = 0;
    }
    newNode->next = *pList;
    *pList = newNode;
    return newNode;
}

/**
 *  链表中查找节点
 *  who : 队伍名
 *  return : 匹配节点的地址,没有找到返回NULL
 */
Node * findList(Node * list, char * who) {
    for(; list!=NULL; list=list->next) {
        if(strcmp(list->data.who, who)==0)
            break;
    }
    return list;
}

/**
 * 求链表节点个数
 */
int sizeList(Node * list) {
    int n;
    for(n=0; list!=NULL; ++n)
        list = list->next;
    return n;
}

/**
 * 队伍比较,不存在
 * return:  1 : t1>t2
 *          0 : t1==t2
 *         -1 : t1<t2
 */
int cmpTeam(Team t1, Team t2) {
    // 比较解题数
    if(t1.solved > t2.solved)
        return 1;
    else if (t1.solved < t2.solved)
        return -1;
    // 解题数相等时,比较总用时
    if(t1.penalty < t2.penalty)
        return 1;
    else if (t1.penalty > t2.penalty)
        return -1;
    // 解题数、总用时都相等
    return 0;
}

/**
 *  链表排序
 */
void sortList(Node * head) {
    Team temp;
    Node * p;
    int cmprst;
    int i, j;
    int len = sizeList(head);
    for(i=0; i<len-1; ++i) {
        p = head;
        for(j=0; j<len-i-1; ++j, p=p->next) {
            // 比较解题数和总用时
            cmprst = cmpTeam(p->data, p->next->data);
            if(cmprst == 1)
                continue;
            // 比较队伍名称
            if(cmprst==0 && strcmp(p->data.who, p->next->data.who) < 0)
                continue;
            // 交换
            temp = p->data;
            p->data = p->next->data;
            p->next->data = temp;
        }
    }
}

/**
 *  打印榜单
 */
void printBoard(Node * list) {
    int i, j;
    Node * head = list;
    int len = sizeList(list);
    int equFlag = 0;
    
    // 打印榜单头
    printf("%4s  %-43s  %6s  %7s", "Rank", "Who", "Solved", "Penalty");
    for(i=0; i<n; ++i)
        printf("  %3c", 'A'+i);
    printf("\n");
    // 打印榜单内容
    for(i=1; i<=len; ++i) {
        int index = i;
        if(equFlag != 0)
            index = equFlag;

        if(head->next!=NULL && cmpTeam(head->data, head->next->data) == 0)
            equFlag = index;
        else 
            equFlag = 0;
        printf("%4d  %-43s  %6d  %7d", index, head->data.who, 
            head->data.solved, head->data.penalty);
        for(j=0; j<n; ++j) {
            char str[4] = "   ";
            if(head->data.titleState[j]==1 && head->data.title[j]==0) {
                str[2] = '+';
            } else {
                if(head->data.titleState[j]==1) {
                    str[1] = '+';
                    str[2] = head->data.title[j]+'0';
                } else if(head->data.title[j] != 0) {
                    str[1] = '-';
                    str[2] = head->data.title[j]+'0';
                }
            }
            printf("  %s", str);
        }
        printf("\n");
        head = head->next;
    }
}




int main(void) {
    char str[100];
    Node * list = NULL;

    // 读取题目数量
    scanf("%d", &n);
    getchar();
    // 循环读取提交记录
    do {
        int i, time, title, state;
        char who[44];
        Node * node;
        gets(str);
        if(strcmp(str, "GAME OVER!")==0)
            break;
        // 解析提交记录[时间]
        time = (str[1]-'0')*60 + (str[3]-'0')*10 + (str[4]-'0');
        // 解析提交记录[题目编号]
        title = str[6]-'A';
        // 解析提交记录[状态]
        for(i=0; i<8; ++i) {
            if(strstr(str+8, states[i])==(str+8)) {
                state = i;
                break;
            }
        }
        // 状态为 "Compile Error" 不做任何处理
        if(state == 3) {  
            continue;        
        }
        // 获取提交记录[队伍名称]
        strcpy(who, str+8+strlen(states[state])+1);
        // 找到链表中队伍名称所对应节点
        node = findList(list, who);
        // 如果节点不存在,在链表中新增节点
        if(node == NULL)
            node = pushFrontList(&list, who);
        if(state == 0) { 
            // 状态为 "Accepted"
            if(node->data.titleState[title] == 1) {
                // 当前提交记录对应题目已经解出,不做任何处理
                continue;
            }
            // 题目状态改为已解出
            node->data.titleState[title] = 1;
            // 累加总用时
            node->data.penalty += node->data.title[title] * 20 + time;
            // 解题数+1
            node->data.solved += 1;
        } else  { 
            // 其它状态,题目尝试次数+1
            node->data.title[title] += 1;
        }
    } while(1);

    // 链表排序
    sortList(list);
    // 打印榜单
    printBoard(list);

    return 0;
}
  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
以下是几个C语言期末大作业项目的介绍: 1. C语言点餐系统 这个项目是一个简单的点餐系统,用户可以通过控制台界面选择菜品并下单。该系统可以实现菜单的展示、菜品的选择、订单的生成等功能。 2. C语言货物管理系统 这个项目是一个简单的货物管理系统,用于管理货物的入库、出库和库存等信息。该系统可以实现货物信息的录入、查询、修改和删除等功能。 3. C语言歌曲信息管理系统 这个项目是一个简单的歌曲信息管理系统,用于管理歌曲的基本信息,如歌曲名称、歌手、专辑等。该系统可以实现歌曲信息的录入、查询、修改和删除等功能。 4. C语言职工信息管理系统 这个项目是一个简单的职工信息管理系统,用于管理公司职工的基本信息,如姓名、年龄、性别等。该系统可以实现职工信息的录入、查询、修改和删除等功能。 5. C语言学生打卡系统 这个项目是一个简单的学生打卡系统,用于记录学生的考勤情况。该系统可以实现学生的签到、签退、请假等功能,并可以生成考勤报表。 6. C语言小学生计算机辅助教学系统 这个项目是一个简单的小学生计算机辅助教学系统,用于帮助小学生学习基础的计算题。该系统可以生成随机的计算题目,并根据学生的答案给出评分和反馈。 7. C语言门禁系统 这个项目是一个简单的门禁系统,用于控制进出门禁区域的人员。该系统可以实现人员的注册、刷卡进出、权限管理等功能。 8. C语言银行管理系统(文件操作) 这个项目是一个简单的银行管理系统,用于管理银行的客户信息和账户信息。该系统可以实现客户信息和账户信息的录入、查询、修改和删除等功能,并可以进行基本的存取款操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FF小迷糊吖~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值