考试排名【结构体/多关键字排序】

题目描述

http://acm.hdu.edu.cn/showproblem.php?pid=2093
C++编程考试使用的实时提交系统,具有即时获得成绩排名的特点。它的功能是怎么实现的呢?
我们做好了题目的解答,提交之后,要么“AC”,要么错误,不管怎样错法,总是给你记上一笔,表明你曾经有过一次错误提交,因而当你一旦提交该题“AC”后,就要与你算一算帐了,总共该题错误提交了几回。虽然你在题数上,大步地跃上了一个台阶,但是在耗时上要摊上你共花去的时间。特别是,曾经有过的错误提交,每次都要摊上一定的单位时间分。这样一来,你在做出的题数上,可能领先别人很多,但是,在做出同样题数的人群中,你可能会在耗时上处于排名的劣势。
例如:某次考试一共8题(A,B,C,D,E,F,G,H),每个人做的题都在对应的题号下有个数量标记,负数表示该学生在该题上有过的错误提交次数,但到现在还没有AC,正数表示AC所耗的时间,如果正数a跟上一对括号,里面有个整数b,那就表示该学生提交该题AC了,耗去了时间a,同时,曾经错误提交了b次,因此对于下述输入数据:
在这里插入图片描述
在这里插入图片描述

实现

错误写法

#include<iostream>
#include <algorithm>
#include<vector>
#include<sstream>

using namespace std;

struct Person
{
	string name;    //名字
	int ac;          //ac题目的个数
	int time;       //罚时
};

bool cmp(Person& a, Person& b)
{
    if (a.ac != b.ac) {
        return a.ac > b.ac; // 第一关键字排序,降序
    }
    if (a.time != b.time) {
        return a.time < b.time; // 第二关键字排序,升序
    }
    return a.name < b.name; // 第三关键字排序,升序
}

int main()
{
    vector<Person> persons; // 结构体数组
    string line;
    int n;
    int cost;
    cin >> n >> cost;
    int personIndex = 0;
    while (getline(cin, line)) {
        int acCnt = 0;
        int timeTotal = 0;
        stringstream ss;
        ss << line;
        string temp = 0;
        for (int i = 0; i < n; i++) {
            stringstream s; // sting to int
            int k1,k2; // 当前行后面的数字
            ss >> persons[personIndex].name;
            ss >> temp;
            int pos1 = temp.find('(');
            int pos2 = temp.find(')');
            if ( pos1 == string::npos) { // 没有括号
                s << temp;
                s >> k1;
                if (k1 > 0) { // 为正数需要计数,为负数时不处理
                    acCnt++;
                    timeTotal += k1;
                }
            } else {
                string s1 = temp.substr(0,pos1);
                string s2 = temp.substr(pos1+1, pos2);
                s << s1;
                s >> k1;
                s << s2;
                s >> k2;
                acCnt++;
                timeTotal = k1 + k2*cost;
            }
        }
        persons[personIndex].ac = acCnt;
        persons[personIndex].time = timeTotal;
        personIndex++;
    }
    sort(persons.begin(), persons.end(), cmp);
    for (int i = 0; i < persons.size(); i++) {
        cout << persons[i].name << " " <<persons[i].ac << " " << persons[i].time << endl;![在这里插入图片描述](https://img-blog.csdnimg.cn/4ba7790ede2c4b7a9ea7b7938745859d.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAR2F2eW5sZWU=,size_20,color_FFFFFF,t_70,g_se,x_16)

    }
}

接近AC

#include<iostream>
#include <algorithm>
#include<vector>
#include<sstream>

using namespace std;

struct Person{
    string name;    //名字
    int ac;          //ac题目的个数
    int time;       //罚时
};

bool cmp(Person& a, Person& b)
{
    if (a.ac != b.ac) {
        return a.ac > b.ac; // 第一关键字排序,降序
    }
    if (a.time != b.time) {
        return a.time < b.time; // 第二关键字排序,升序
    }
    return a.name < b.name; // 第三关键字排序,升序
}

int main()
{
    vector<Person> persons; // 结构体数组
    int n;
    int cost;
    cin >> n >> cost;
    
    string line;
    while (getline(cin, line) && line != "x") {
        int acCnt = 0;
        int timeTotal = 0;
        stringstream ss;
        ss << line;

        string strName;
        ss >> strName;
        string temp;
        for (int i = 0; i < n; i++) {
            stringstream s; // sting to int
            int k1,k2; // 当前行后面的数字
            ss >> temp;
            int pos1 = temp.find('(');
            int pos2 = temp.find(')');
            if ( pos1 == string::npos) { // 没有括号
                s << temp;
                s >> k1;
                //cout << k1 << " ";
                if (k1 > 0) { // 为正数需要计数,为负数时不处理
                    acCnt++;
                    timeTotal += k1;
                }
            } else {
                string s1 = temp.substr(0,pos1);
                string s2 = temp.substr(pos1+1, pos2);
                s << s1;
                s >> k1;
                s.clear();
                s << s2;
                s >> k2;
                s.clear();
                acCnt++;
                timeTotal = k1 + k2 * cost;
            }
        }
        ss.clear(); // 多次转换之间必须使用clear()方法进行清空
        Person addVal = {strName, acCnt, timeTotal};
        persons.push_back(addVal);
//        persons[personIndex].name = strName; 错误操作,vector还没有分配空间
//        persons[personIndex].ac = acCnt;
//        persons[personIndex].time = timeTotal;
//        personIndex++;
    }
    sort(persons.begin(), persons.end(), cmp);
    for (int i = 0; i < persons.size(); i++) {
        cout << persons[i].name << " " <<persons[i].ac << " " << persons[i].time << endl;
    }
}

在这里插入图片描述

AC

#include<iostream>
#include <algorithm>
#include<vector>
#include<sstream>

using namespace std;

struct Person{
    string name;    //名字
    int ac;          //ac题目的个数
    int time;       //罚时
};

bool cmp(Person& a, Person& b)
{
    if (a.ac != b.ac) {
        return a.ac > b.ac; // 第一关键字排序,降序
    }
    if (a.time != b.time) {
        return a.time < b.time; // 第二关键字排序,升序
    }
    return a.name < b.name; // 第三关键字排序,升序
}

int main()
{
    vector<Person> persons; // 结构体数组
    int n;
    int cost;
    cin >> n >> cost;

    string enter;
    getline(cin, enter); // 换行,输入换行符,enter为空
    string line;
    while (getline(cin, line) && line != "x") {
        int acCnt = 0;
        int timeTotal = 0;
        stringstream ss;
        ss << line;

        string strName;
        ss >> strName;
        string temp;
        for (int i = 0; i < n; i++) {
            stringstream s; // sting to int
            int k1,k2; // 当前行后面的数字
            ss >> temp;
            int pos1 = temp.find('(');
            int pos2 = temp.find(')');
            if ( pos1 == string::npos) { // 没有括号
                s << temp;
                s >> k1;
                //cout << k1 << " ";
                if (k1 > 0) { // 为正数需要计数,为负数时不处理
                    acCnt++;
                    timeTotal += k1;
                }
            } else {
                string s1 = temp.substr(0,pos1);
                string s2 = temp.substr(pos1+1, pos2);
                s << s1;
                s >> k1;
                s.clear();
                s << s2;
                s >> k2;
                s.clear();
                acCnt++;
                timeTotal += k1 + k2 * cost;
            }
        }
        ss.clear(); // 多次转换之间必须使用clear()方法进行清空
        Person addVal = {strName, acCnt, timeTotal};
        persons.push_back(addVal);
//        persons[personIndex].name = strName; 错误操作,vector还没有分配空间
//        persons[personIndex].ac = acCnt;
//        persons[personIndex].time = timeTotal;
//        personIndex++;
    }
    sort(persons.begin(), persons.end(), cmp);
    for (int i = 0; i < persons.size(); i++) {
        cout << persons[i].name << " " <<persons[i].ac << " " << persons[i].time << endl;
    }
}

在这里插入图片描述

参考

输入输出处理

(1)使用getline

#include <iostream>
#include <vector>
#include <string>
#include <sstream>
using namespace std;

int main()
{
    int mask1 = 0, mask2 = 0, mask3 = 0, mask4 = 0;
    char ch;
    string inputstr;
    stringstream ss;
    string line;
    while (getline(cin, inputstr)) {
        int ip1a = 0, ip1b = 0, ip1c = 0, ip1d = 0;
        int ip2a = 0, ip2b = 0, ip2c = 0, ip2d = 0;
        ss << inputstr;
        ss >> mask1 >> mask2  >> mask3  >> mask4;
        ss.clear();
        cout << mask1 << " " << mask2 << " " << mask3 << " " << mask4 <<endl;
    }
    return 0;
}

在这里插入图片描述

#include <iostream>
#include <vector>
#include <string>
#include <sstream>
using namespace std;

int main()
{
    string mask1, mask2, mask3, mask4;
    char ch;
    string inputstr;
    stringstream ss;
    string line;
    while (getline(cin, inputstr)) {
        string ip1a, ip1b, ip1c, ip1d;
        string ip2a, ip2b, ip2c, ip2d;
        ss << inputstr;
        ss >> mask1 >> mask2  >> mask3  >> mask4;
        ss.clear();
        cout << mask1 << " " << mask2 << " " << mask3 << " " << mask4 <<endl;
    }
    return 0;
}

在这里插入图片描述

#include <iostream>
#include <vector>
#include <string>
#include <sstream>
using namespace std;

int main()
{
    string mask1, mask2, mask3, mask4;
    char ch;
    string inputstr;
    stringstream ss;
    string line;
    while (getline(cin, inputstr)) {
        string ip1a, ip1b, ip1c, ip1d;
        string ip2a, ip2b, ip2c, ip2d;
        ss << inputstr;
        ss >> mask1;
        ss >> mask2;
        ss >> mask3;
        ss >> mask4;
        ss.clear(); // 必须要
        cout << mask1 << " " << mask2 << " " << mask3 << " " << mask4 <<endl;
    }
    return 0;
}

在这里插入图片描述
如果没有ss.clear(),则输出为以下情况:
在这里插入图片描述

#include <iostream>
#include <vector>
#include <string>
#include <sstream>
using namespace std;

int main()
{
    string mask1, mask2, mask3, mask4;
    char ch;
    string inputstr;
    stringstream ss;
    string line;
    while (getline(cin, inputstr)) {
        string ip1a, ip1b, ip1c, ip1d;
        string ip2a, ip2b, ip2c, ip2d;
        ss << inputstr;
        for (int i = 0; i < 4; i++) {
            ss >> mask1;
            cout << mask1 << " ";
        }
        ss.clear();
        cout << endl;
    }
    return 0;
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值