【算法学习记录-排序题】【PAT A1062】Talent and Virtue

About 900 years ago, a Chinese philosopher Sima Guang wrote a history book in which he talked about people‘s talent and virtue. According to his theory, a man being outstanding in both talent and virtue must be a "sage(圣人)"; being less excellent but with one‘s virtue outweighs talent can be called a "nobleman(君子)"; being good in neither is a "fool man(愚人)"; yet a fool man is better than a "small man(小人)" who prefers talent than virtue.

Now given the grades of talent and virtue of a group of people, you are supposed to rank them according to Sima Guang‘s theory.

Input Specification:

Each input file contains one test case. Each case first gives 3 positive integers in a line: N (≤10?5??), the total number of people to be ranked; L (≥60), the lower bound of the qualified grades -- that is, only the ones whose grades of talent and virtue are both not below this line will be ranked; and H (<100), the higher line of qualification -- that is, those with both grades not below this line are considered as the "sages", and will be ranked in non-increasing order according to their total grades. Those with talent grades below H but virtue grades not are cosidered as the "noblemen", and are also ranked in non-increasing order according to their total grades, but they are listed after the "sages". Those with both grades below H, but with virtue not lower than talent are considered as the "fool men". They are ranked in the same way but after the "noblemen". The rest of people whose grades both pass the L line are ranked after the "fool men".

Then N lines follow, each gives the information of a person in the format:

ID_Number Virtue_Grade Talent_Grade

where ID_Number is an 8-digit number, and both grades are integers in [0, 100]. All the numbers are separated by a space.

Output Specification:

The first line of output must give M (≤N), the total number of people that are actually ranked. Then M lines follow, each gives the information of a person in the same format as the input, according to the ranking rules. If there is a tie of the total grade, they must be ranked with respect to their virtue grades in non-increasing order. If there is still a tie, then output in increasing order of their ID‘s.

Sample Input:

14 60 80
10000001 64 90
10000002 90 60
10000011 85 80
10000003 85 80
10000004 80 85
10000005 82 77
10000006 83 76
10000007 90 78
10000008 75 79
10000009 59 90
10000010 88 45
10000012 80 100
10000013 90 99
10000014 66 60

Sample Output:

12
10000013 90 99
10000012 80 100
10000003 85 80
10000011 85 80
10000004 80 85
10000007 90 78
10000006 83 76
10000005 82 77
10000002 90 60
10000014 66 60
10000008 75 79
10000001 64 90

题意:

第一行给出三个整数:考生人数N,最低录取线L,优先录取线H

德分和才分均不低于L的才有录取资格

德才分均不低于H的为I类,最优先录取

德分不低于H但才分低于H的为II类,次优先录取

德分和才分均低于H但德分不低于才分的为III类,更次录取

其余考生为IV类,最次优先录取

思路:

1、排序的逻辑

①按类别从低到高排序

②类别相同,按总分从高到低排序

③总分相同,按德分从高到低排序

④德分相同,按考号从低到高排序

2、所需要的信息及信息的存储

①对于单个学生student,需要对应的准考证号id,德分de,才分cai,总分sum,类别flag——结构体Student,并创建一个足够大的结构体数组

②此外还需要总考生数n,最低分数线l,优先录取分数线h,录取考生数num——int型变量

3、排序逻辑的实现

 1 bool cmp(Student a, Student b) {
 2     if (a.flag != b.flag) {
 3         return a.flag < b.flag;
 4     } else if (a.sum != b.sum) {
 5         return a.sum > b.sum;
 6     } else if (a.de != b.de) {
 7         return a.de > b.de;
 8     } else {
 9         return strcmp(a.id, b.id) < 0;
10     }
11 }

4、main()  雏形

int main() {
    int n, l, h, num = 0;
    scanf("%d%d%d", &n, &l, &h);
    for (int i = 0; i < n; i++) {
        scanf("%s%d%d", stu[i].id, &stu[i].de, &stu[i].cai);
        stu[i].sum = stu[i].de + stu[i].cai;
        if (stu[i].de < l || stu[i].cai < l) {
            stu[i].flag = 5;
        } else {
            num++;
            if (stu[i].de >= h && stu[i].cai >= h) {
                stu[i].flag = 1;
            } else if (stu[i].de >= h && stu[i].cai < h) {
                stu[i].flag = 2;
            } else if (stu[i] < h && stu[i].cai < h && stu[i].de >= stu[i].cai) {
                stu[i].flag = 3;
            } else {
                stu[i].flag = 4;
            }
        }
    }
    sort(stu, stu + n, cmp);
}

5、优化

①逻辑优化

  德分 < L L <= 德分 < H 德分 >= H
才分 < L 5 5 5
L <= 才分 < H 5 3 2
才分 >= H 5 4 1

所以,if-else逻辑应简化为

 1 if (stu[i].de < l || stu[i].cai < l) {
 2     stu[i].flag = 5;
 3 } else if (stu[i].de >= h && stu[i].cai >= h) {
 4     stu[i].flag = 1;
 5 } else if (stu[i].de >= h && stu[i].cai < h) {
 6     stu[i].flag = 2;
 7 } else if (stu[i].de >= stu[i].cai) {
 8     stu[i].flag = 3;
 9 } else {
10     stu[i].flag = 4;
11 }

②num的替换

若在①中后四个else if中,每个都写上num++,会显得过于繁杂

因此将num初值设为参与考试的人数n,每次出现不合格的人时num--

1 int num = n;
2
3 if (stu[i].de < l || stu[i].cai < l) {
4     stu[i].flag = 5;
5         num--;
6 }

6、题解

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 struct Student {
 6     char id[10];
 7     int de;
 8     int cai;
 9     int sum;
10     int flag;
11 }stu[100010];
12 bool cmp(Student a, Student b) {
13     if (a.flag != b.flag) {
14         return a.flag < b.flag;
15     } else if (a.sum != b.sum) {
16         return a.sum > b.sum;
17     } else if (a.de != b.de) {
18         return a.de > b.de;
19     } else {
20         return strcmp(a.id, b.id) < 0;
21     }
22 }
23 int main() {
24     int n, l, h;
25     scanf("%d%d%d", &n, &l, &h);
26     int num = n;
27     for (int i = 0; i < n; i++) {
28         scanf("%s%d%d", stu[i].id, &stu[i].de, &stu[i].cai);
29         stu[i].sum = stu[i].de + stu[i].cai;
30         if (stu[i].de < l || stu[i].cai < l) {
31             stu[i].flag = 5;
32             num--;
33         } else if (stu[i].de >= h && stu[i].cai >= h) {
34             stu[i].flag = 1;
35         } else if (stu[i].de >= h && stu[i].cai < h) {
36             stu[i].flag = 2;
37         } else if (stu[i].de >= stu[i].cai) {
38             stu[i].flag = 3;
39         } else {
40             stu[i].flag = 4;
41         }
42     }
43     sort(stu, stu + n, cmp);
44     printf("%d\n", num);
45     for (int i = 0; i < num; i++) {
46         printf("%s %d %d\n", stu[i].id, stu[i].de, stu[i].cai);
47     }
48 }

*7、未解决的问题

题目中准考证号给出8位

但实际使用char[8]存储再输出时会出错???



原文地址:https://www.cnblogs.com/Bananice/p/12234582.html

时间: 2024-08-28 11:30:43

【算法学习记录-排序题】【PAT A1062】Talent and Virtue的相关文章

【算法学习记录-排序题】【PAT A1012】The Best Rank

To evaluate the performance of our first year CS majored students, we consider their grades of three courses only: C - C Programming Language, M - Mathematics (Calculus or Linear Algrbra), and E - English. At the mean time, we encourage students by e

【算法学习记录-排序题】【PAT A1025】PAT Ranking

Programming Ability Test (PAT) is organized by the College of Computer Science and Technology of Zhejiang University. Each test is supposed to run simultaneously in several places, and the ranklists will be merged immediately after the test. Now it i

算法学习记录-查找——平衡二叉树(AVL)

排序二叉树对于我们寻找无序序列中的元素的效率有了大大的提高.查找的最差情况是树的高度.这里就有问题了,将无序数列转化为 二叉排序树的时候,树的结构是非常依赖无序序列的顺序,这样会出现极端的情况. [如图1]: 这样的一颗二叉排序树就是一颗比较极端的情况.我们在查找时候,效率依赖树的高度,所以不希望这样极端情况出现,而是希望元素比较均匀 的分布在根节点两端. 技术参考:fun4257.com/ 问题提出: 能不能有一种方法,使得我们的二叉排序树不依赖无序序列的顺序,也能使得我们得到的二叉排序树是比

算法学习记录-栈的应用--表达式运算

前面做了栈的基本操作 总感觉需要做一个实际的例子来检验一下. 这里我将用栈来做一个简单的四则运算. 目标比较简单: 做一个带小括号(“()”)的四则运算,如果要加入到中括号(“[]”)或者大括号(“{}”),依次类推. 求一个表达式: 用下面这个算是做例子,程序最后应该可以算出任何带小括号的运算. 3+(32-6)*9+5*3-(3*(65-15)/5)+12; 方法一:后缀法. 1.了解中缀和后缀表示法 中缀表示法:刚才的那个算是就是中缀表示法,我们通常看到的数学符号就是中缀表示法,即数字在计

PAT B1015/A1062 Talent and Virtue

PAT B1015/A1062 Talent and Virtue 题目描述: About 900 years ago, a Chinese philosopher Sima Guang wrote a history book in which he talked about people's talent and virtue. According to his theory, a man being outstanding in both talent and virtue must be

PAT-B 1015. 德才论(同PAT 1062. Talent and Virtue)

1. 在排序的过程中,注意边界的处理(小于.小于等于) 2. 对于B-level,这题是比較麻烦一些了. 源代码: #include <cstdio> #include <vector> #include <algorithm> using namespace std; struct People { int m_id; int m_virtue; int m_talent; People(int id, int virtue, int talent): m_id(id

PAT 1062 Talent and Virtue[难]

1062 Talent and Virtue (25 分) About 900 years ago, a Chinese philosopher Sima Guang wrote a history book in which he talked about people's talent and virtue. According to his theory, a man being outstanding in both talent and virtue must be a "sage(圣

PAT 1062 Talent and Virtue

#include <cstdio> #include <cstdlib> #include <cstring> #include <vector> #include <algorithm> using namespace std; class Man { public: char id[10]; int talent; int virtue; }; bool mycmp(const Man& a, const Man& b) {

PAT 1062. Talent and Virtue (25)

1062. Talent and Virtue (25) About 900 years ago, a Chinese philosopher Sima Guang wrote a history book in which he talked about people's talent and virtue. According to his theory, a man being outstanding in both talent and virtue must be a "sage(圣人