[sort排序] 8. 成绩排序(自定义排序、宏定义、常规解法)

1. 题目来源

链接:成绩排序

2. 题目说明

在这里插入图片描述

3. 题目解析

方法一:sort()+自定义排序+常规解法

题意很明确,按照各科进行排序并输出对应的人名,最后按照总分排序输出人名即可。也是练习练习自定义排序和结构题吧。值得注意的是分数相同人名按照字典序进行输出。重复代码很多。

参见代码如下:

#include <iostream>
#include <algorithm>
#include <string>

using namespace std;

struct student {
    int a, b, c, d, sum;
    string name;
};

bool cmp1(student a, student b) {
    if (a.a == b.a) {
        return a.name < b.name;
    }
    return a.a > b.a;
}

bool cmp2(student a, student b) {
    if (a.b == b.b) {
        return a.name < b.name;
    }
    return a.b > b.b;
}

bool cmp3(student a, student b) {
    if (a.c == b.c) {
        return a.name < b.name;
    }
    return a.c > b.c;
}

bool cmp4(student a, student b) {
    if (a.d == b.d) {
        return a.name < b.name;
    }
    return a.d > b.d;
}

bool cmp5(student a, student b) {
    if (a.sum == b.sum) {
        return a.name < b.name;
    }
    return a.sum > b.sum;
}

int main() {
    int n;
    student s[105];
    cin >> n;
    for (int i = 0; i < n; i++) {
        cin >> s[i].name >> s[i].a >> s[i].b >> s[i].c >> s[i].d;
        s[i].sum = s[i].a + s[i].b + s[i].c + s[i].d;
    }
    sort(s, s + n, cmp1);
    for (int i = 0; i < 4; i++) {
        if (i) {
        	cout << " ";
        }
        cout << s[i].name;
    }
    cout << endl;
    sort(s, s + n, cmp2);
    for (int i = 0; i < 4; i++) {
        if (i) {
        	cout << " ";
        }
        cout << s[i].name;
    }
    cout << endl;
    sort(s, s + n, cmp3);
    for (int i = 0; i < 4; i++) {
        if (i) {
		   	  cout << " ";
        }
        cout << s[i].name;
    }
    cout << endl;
    sort(s, s + n, cmp4);
    for (int i = 0; i < 4; i++) {
        if (i) {
			   cout << " ";
        }
        cout << s[i].name;
    }
    cout << endl;
    sort(s, s + n, cmp5);
    for (int i = 0; i < 4; i++) {
        if (i) {
        	cout << " ";
        }
        cout << s[i].name;
    }
    cout << endl;
    return 0;
}

方法二:sort()+宏定义+自定义排序+巧妙解法

宏定义真的是千变万化,有点东西。看看就好吧~

参见代码如下:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <string>
using namespace std;

struct Student {
    string name;
    int score[4];
    int total_score;
    void read() {
        cin >> name;
        for (int i = 0; i < 4; i++) {
            cin >> score[i];
            total_score += score[i];
        }
        return ;
    }
};

#define MAX_N 100
#define cmp(x, y) bool cmp##x(Student &s1, Student &s2) { \
    if (s1.y > s2.y) return true; \
    if (s1.y == s2.y && s1.name < s2.name) return true; \
    return false; \
}

Student stu[MAX_N];

cmp(0, score[0]);
cmp(1, score[1]);
cmp(2, score[2]);
cmp(3, score[3]);
cmp(total, total_score);

int main() {
    int n;
    cin >> n;
    for (int i = 0; i < n; i++) {
        stu[i].read();
    }
    sort(stu, stu + n, cmp0);
    for (int i = 0; i < 4; i++) {
        if (i) cout << " ";
        cout << stu[i].name;
    }
    cout << endl;
    sort(stu, stu + n, cmp1);
    for (int i = 0; i < 4; i++) {
        if (i) cout << " ";
        cout << stu[i].name;
    }
    cout << endl;
    sort(stu, stu + n, cmp2);
    for (int i = 0; i < 4; i++) {
        if (i) cout << " ";
        cout << stu[i].name;
    }
    cout << endl;
    sort(stu, stu + n, cmp3);
    for (int i = 0; i < 4; i++) {
        if (i) cout << " ";
        cout << stu[i].name;
    }
    cout << endl;
    sort(stu, stu + n, cmptotal);
    for (int i = 0; i < 4; i++) {
        if (i) cout << " ";
        cout << stu[i].name;
    }
    cout << endl;
    return 0;
}
//-------- LineSimplify.mac -----------------------------------------// // 重複行を削除する簡易マクロ Ver.2.09 // 山紫水明 2006年11月1日 $inifile = currentmacrodirectory + "\\MyMacro.ini"; #sort = getininum($inifile, "LineSimplify", "sort"); #delete = getininum($inifile, "LineSimplify", "delete"); #delspc = getininum($inifile, "LineSimplify", "delspc"); $sort[1] = "する"; $sort[0] = "しない"; $delete[1] = "する"; $delete[0] = "しない"; $delspc[1] = "する"; $delspc[0] = "しない"; while( 1 ) { menu "&E 実 行", "&S ソート:" + $sort[#sort], "&D 重複行の削除:" + $delete[#delete], "&N 空白行の削除:" + $delspc[#delspc]; #r = result; if( #r == 0 ) endmacro; else if( #r == 1 ) break; else if( #r == 2 ) #sort = !#sort; else if( #r == 3 ) #delete = !#delete; else if( #r == 4 ) #delspc = !#delspc; } disabledraw; #starttime = tickcount; if( selecting ) { #handle1 = hidemaruhandle(0); cut; openfile "/h"; paste; #handle2 = hidemaruhandle(0); #select = 1; } if( #delspc ) { replaceallfast "^[ \t ]*\\n", "", regular; #delspcnum = result; if( #delspcnum ) $delspcnum = "空白行削除:" + str( #delspcnum ) + "\n"; #ex = #ex + #delspcnum; } if( #sort == 0 && #delete == 0 ) goto End; if( #sort ) call Sort; else call NoSort; if( #select ) { selectall; copy; setactivehidemaru #handle1; paste; closehidemaruforced #handle2; #ex = #ex + 2; } gofiletop; End: title 0; enabledraw; if( #sort && #delete == 0 && #delspc == 0 ) $sorted = "ソートしました。\n"; if( #count ) $dellinenum = "重複行削除:" + str( #count ) + "\n"; #time = tickcount - #starttime; #minute = #time / 60000; #second = #time / 1000 - #minute * 60; if( #minute > 0 ) $minute = str( #minute ) + "分"; question $dellinenum + $delspcnum + $sorted + "所 要 時 間:" + $minute + str(#second) + "秒" + str( #time % 1000 ) + "\n\n確定しますか?"; if( result == no ) call Cancel; writeininum $inifile, "LineSimplify", "sort", #sort; writeininum $inifile, "LineSimplify", "delete", #delete; writeininum $inifile, "LineSimplify", "delspc", #delspc; endmacro; Sort: title "ソート中"; selectall; if( existfile( hidemarudir + "\\Sort.hmf " ) ) filter "Sort.hmf", "sort", "0000"; else run "sort /rec 8200 < con > con"; #ex = #ex + 2; escape; if( !#delete ) return; SortDelete: gofiletop; while ( code == 0x0d ) down; while( code != eof ) { $s1 = gettext2( 0, lineno, linelen2, lineno ); movetolineno 1, lineno + 1; while( 1 ) { $s2 = gettext2( 0, lineno, linelen2, lineno ); if( $s1 == $s2 ) { selectline; delete; #count = #count + 1; } else break; } #i = #i + 1; if( #i % 20 == 0 ) title "削除中 " + str( #i ); } #ex = #ex + #count; return; NoSort: gofiletop; title "削除中"; disabledraw; $sb = searchbuffer; #so = searchoption; while( code != eof ) { $s1 = gettext2( 0, lineno, linelen2, lineno ); if( $s1 == "" ) { //空行の場合 movetolineno 1, lineno + 1; continue; } movetolineno 1, lineno + 1; #line = lineno; while( 1 ) { searchdown2 $s1; if( !result ) break; if( return ) {//折り返している場合 //長い場合,検索バッファに入りきれないので,文字列を直接比較 $s2 = gettext2( 0, lineno, linelen2, lineno ); if( $s1 != $s2 ) break; } selectline; delete; #count = #count + 1; } movetolineno 1, #line; if( lineno == linecount2 ) break; #i = #i + 1; if( #i % 20 == 0 ) title "削除中 " + str( #i ); } #ex = #ex + #count; setsearch $sb, #so; return; Cancel: disabledraw; ##u = 0; while( 1 ) { undo; ##u = ##u + 1; if( ##u >= #ex ) break; if( !updated ) break; } return; //------------------------------------------------------//
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Ypuyu

如果帮助到你,可以请作者喝水~

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

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

打赏作者

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

抵扣说明:

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

余额充值