算法笔记 上机训练实战指南 第4章 入门篇(2) --算法初步 4.1排序 学习笔记

PAT B1015 德才论 (25分)/A1062

宋代史学家司马光在《资治通鉴》中有一段著名的“德才论”:“是故才德全尽谓之圣人,才德兼亡谓之愚人,德胜才谓之君子,才胜德谓之小人。凡取人之术,苟不得圣人,君子而与之,与其得小人,不若得愚人。”

现给出一批考生的德才分数,请根据司马光的理论给出录取排名。

输入格式:

输入第一行给出 3 个正整数,分别为:N(≤),即考生总数;L(≥),为录取最低分数线,即德分和才分均不低于 L 的考生才有资格被考虑录取;H(<),为优先录取线——德分和才分均不低于此线的被定义为“才德全尽”,此类考生按德才总分从高到低排序;才分不到但德分到线的一类考生属于“德胜才”,也按总分排序,但排在第一类考生之后;德才分均低于 H,但是德分不低于才分的考生属于“才德兼亡”但尚有“德胜才”者,按总分排序,但排在第二类考生之后;其他达到最低线 L 的考生也按总分排序,但排在第三类考生之后。

随后 N 行,每行给出一位考生的信息,包括:准考证号 德分 才分,其中准考证号为 8 位整数,德才分为区间 [0, 100] 内的整数。数字间以空格分隔。

输出格式:

输出第一行首先给出达到最低分数线的考生人数 M,随后 M 行,每行按照输入格式输出一位考生的信息,考生按输入中说明的规则从高到低排序。当某类考生中有多人总分相同时,按其德分降序排列;若德分也并列,则按准考证号的升序输出。

输入样例:

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

输出样例:

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
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
struct student{
    char id[10];
    int de,cai,sum;
    int flag; //分类 
}stu[100010];
bool cmp(student a,student b){
    if(a.flag != b.flag ) 
        return a.flag < b.flag;
    else if(a.sum != b.sum) 
        return a.sum > b.sum;
    else if(a.de != b.de) 
        return a.de > b.de;
    else
        return strcmp(a.id,b.id) < 0;
}
int main(){
    int N,L,H;
    scanf("%d%d%d",&N,&L,&H);
    int m = N;
    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;
            m--;
        }else 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].de >= stu[i].cai){
            stu[i].flag = 3;
        }else{
            stu[i].flag = 4;
        }
    }
    sort(stu,stu+N,cmp);
    printf("%d\n",m);
    for(int i = 0;i<m;i++){
        printf("%s %d %d\n",stu[i].id,stu[i].de,stu[i].cai);
    }

    return 0;
}
PAT A1012 The Best Rank (25分)

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 emphasizing on their best ranks -- that is, among the four ranks with respect to the three courses and the average grade, we print the best rank for each student.

For example, The grades of CME and A - Average of 4 students are given as the following:

StudentID  C  M  E  A
310101     98 85 88 90
310102     70 95 88 84
310103     82 87 94 88
310104     91 91 91 91

Then the best ranks for all the students are No.1 since the 1st one has done the best in C Programming Language, while the 2nd one in Mathematics, the 3rd one in English, and the last one in average.

Input Specification:

Each input file contains one test case. Each case starts with a line containing 2 numbers N and M (≤), which are the total number of students, and the number of students who would check their ranks, respectively. Then N lines follow, each contains a student ID which is a string of 6 digits, followed by the three integer grades (in the range of [0, 100]) of that student in the order of CM and E. Then there are M lines, each containing a student ID.

Output Specification:

For each of the M students, print in one line the best rank for him/her, and the symbol of the corresponding rank, separated by a space.

The priorities of the ranking methods are ordered as A C M E. Hence if there are two or more ways for a student to obtain the same best rank, output the one with the highest priority.

If a student is not on the grading list, simply output N/A.

Sample Input:

5 6
310101 98 85 88
310102 70 95 88
310103 82 87 94
310104 91 91 91
310105 85 90 90
310101
310102
310103
310104
310105
999999

Sample Output:

1 C
1 M
1 E
1 A
3 A
N/A
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
struct Student{
    int id;
    int score[4];
}stu[2010];
int now;
int Rank[1000000][4]={0};
char course[4]= {'A','C','M','E'};
bool cmp(Student a,Student b){
    return a.score[now] > b.score[now];
}
int main(){
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=0;i<n;i++){
        scanf("%d %d %d %d",&stu[i].id,&stu[i].score[1],&stu[i].score[2],&stu[i].score[3]);
        stu[i].score[0] = round((stu[i].score[1] + stu[i].score[2] + stu[i].score[3])/3.0);
    }
    for(now=0;now<4;now++){
        sort(stu,stu+n,cmp);
        Rank[stu[0].id][now] = 1;
        for(int i=1;i<n;i++){
            if(stu[i].score[now] == stu[i-1].score[now]){
                Rank[stu[i].id][now] = Rank[stu[i-1].id][now];
            }else{
                Rank[stu[i].id][now] = i + 1;
            }
        }
    }
    for(int i=0;i<m;i++){
        int query;
        scanf("%d",&query);
        if(Rank[query][0] == 0){
            printf("N/A\n");
        }else{
            int k=0;
            for(int j=0;j<4;j++){
                if(Rank[query][j] < Rank[query][k]){
                    k = j;
                }
            }
            printf("%d %c\n",Rank[query][k],course[k]);
        }
    }
    return 0;
}
PAT A1028 List Sorting (25分)

Excel can sort records according to any column. Now you are supposed to imitate this function.

Input Specification:

Each input file contains one test case. For each case, the first line contains two integers N (≤) and C, where N is the number of records and C is the column that you are supposed to sort the records with. Then N lines follow, each contains a record of a student. A student's record consists of his or her distinct ID (a 6-digit number), name (a string with no more than 8 characters without space), and grade (an integer between 0 and 100, inclusive).

Output Specification:

For each test case, output the sorting result in N lines. That is, if C = 1 then the records must be sorted in increasing order according to ID's; if C = 2 then the records must be sorted in non-decreasing order according to names; and if C = 3 then the records must be sorted in non-decreasing order according to grades. If there are several students who have the same name or grade, they must be sorted according to their ID's in increasing order.

Sample Input 1:

3 1
000007 James 85
000010 Amy 90
000001 Zoe 60

Sample Output 1:

000001 Zoe 60
000007 James 85
000010 Amy 90

Sample Input 2:

4 2
000007 James 85
000010 Amy 90
000001 Zoe 60
000002 James 98

Sample Output 2:

000010 Amy 90
000002 James 98
000007 James 85
000001 Zoe 60

Sample Input 3:

4 3
000007 James 85
000010 Amy 90
000001 Zoe 60
000002 James 90

Sample Output 3:

000001 Zoe 60
000007 James 85
000002 James 90
000010 Amy 90
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
struct Student{
    char id[10];
    char name[10];
    int grade;
}stu[100010];
bool cmp1(Student a,Student b){
    return strcmp(a.id,b.id)<0;
}
bool cmp2(Student a,Student b){
    int s = strcmp(a.name,b.name);
    if(s!= 0) return s < 0;
    else
        return strcmp(a.id,b.id) < 0;
}
bool cmp3(Student a,Student b){
    if(a.grade != b.grade){
        return a.grade < b.grade;
    }else{
        return strcmp(a.id,b.id) < 0;
    }
}
int main(){
    int n,c;
    scanf("%d%d",&n,&c);
    for(int i=0;i<n;i++){
        scanf("%s %s %d",stu[i].id,stu[i].name,&stu[i].grade);
    }
    if(c == 1){
        sort(stu,stu+n,cmp1);
    }else if(c == 2){
        sort(stu,stu+n,cmp2);
    }else if(c == 3){
        sort(stu,stu+n,cmp3);
    }
    for(int i=0;i<n;i++){
        printf("%s %s %d\n",stu[i].id,stu[i].name,stu[i].grade);
    }
    return 0;
}

PAT A1055 The World's Richest (25分)

Forbes magazine publishes every year its list of billionaires based on the annual ranking of the world's wealthiest people. Now you are supposed to simulate this job, but concentrate only on the people in a certain range of ages. That is, given the net worths of N people, you must find the M richest people in a given range of their ages.

Input Specification:

Each input file contains one test case. For each case, the first line contains 2 positive integers: N (≤) - the total number of people, and K (≤) - the number of queries. Then N lines follow, each contains the name (string of no more than 8 characters without space), age (integer in (0, 200]), and the net worth (integer in [−]) of a person. Finally there are K lines of queries, each contains three positive integers: M (≤) - the maximum number of outputs, and [AminAmax] which are the range of ages. All the numbers in a line are separated by a space.

Output Specification:

For each query, first print in a line Case #X: where X is the query number starting from 1. Then output the M richest people with their ages in the range [AminAmax]. Each person's information occupies a line, in the format

Name Age Net_Worth

The outputs must be in non-increasing order of the net worths. In case there are equal worths, it must be in non-decreasing order of the ages. If both worths and ages are the same, then the output must be in non-decreasing alphabetical order of the names. It is guaranteed that there is no two persons share all the same of the three pieces of information. In case no one is found, output None.

Sample Input:

12 4
Zoe_Bill 35 2333
Bob_Volk 24 5888
Anny_Cin 95 999999
Williams 30 -22
Cindy 76 76000
Alice 18 88888
Joe_Mike 32 3222
Michael 5 300000
Rosemary 40 5888
Dobby 24 5888
Billy 24 5888
Nobody 5 0
4 15 45
4 30 35
4 5 95
1 45 50

Sample Output:

Case #1:
Alice 18 88888
Billy 24 5888
Bob_Volk 24 5888
Dobby 24 5888
Case #2:
Joe_Mike 32 3222
Zoe_Bill 35 2333
Williams 30 -22
Case #3:
Anny_Cin 95 999999
Michael 5 300000
Alice 18 88888
Cindy 76 76000
Case #4:
None

 

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
struct Student{
    char name[10];
    int age;
    int worth;
}stu[100010];

bool cmp(Student a,Student b){
    if(a.worth != b.worth) 
        return a.worth > b.worth;
    else if(a.age != b.age)
        return a.age < b.age; 
    else if(strcmp(a.name,b.name)!=0)
        return strcmp(a.name,b.name) < 0;
}
int main(){
    int n,k;
    scanf("%d%d",&n,&k);
    for(int i=0;i<n;i++){
        scanf("%s %d %d",stu[i].name,&stu[i].age,&stu[i].worth);
    }
    sort(stu,stu+n,cmp);
    for(int i=1;i<=k;i++){
        int m,age1,age2;
        scanf("%d %d %d",&m,&age1,&age2);
        printf("Case #%d:\n",i);
        int count = 0;
        int valid[100010]={-1};
        for(int j=0;j<n;j++){
            if(stu[j].age >=age1 && stu[j].age <= age2){
                valid[count] = j;
                count++;
            }
        }
        if(count==0){
            printf("None\n");
        }else{
            int printnum = 0;
            for(int j=0;j<count && printnum < m;j++){
                    printf("%s %d %d\n",stu[valid[j]].name,stu[valid[j]].age,stu[valid[j]].worth);
                    printnum++;
            }
        }
        
    }
    return 0;
}
PAT A1075 PAT Judge (25分)

The ranklist of PAT is generated from the status list, which shows the scores of the submissions. This time you are supposed to generate the ranklist for PAT.

Input Specification:

Each input file contains one test case. For each case, the first line contains 3 positive integers, N (≤), the total number of users, K (≤), the total number of problems, and M (≤), the total number of submissions. It is then assumed that the user id's are 5-digit numbers from 00001 to N, and the problem id's are from 1 to K. The next line contains K positive integers p[i] (i=1, ..., K), where p[i] corresponds to the full mark of the i-th problem. Then M lines follow, each gives the information of a submission in the following format:

user_id problem_id partial_score_obtained

where partial_score_obtained is either − if the submission cannot even pass the compiler, or is an integer in the range [0, p[problem_id]]. All the numbers in a line are separated by a space.

Output Specification:

For each test case, you are supposed to output the ranklist in the following format:

rank user_id total_score s[1] ... s[K]

where rank is calculated according to the total_score, and all the users with the same total_score obtain the same rank; and s[i] is the partial score obtained for the i-th problem. If a user has never submitted a solution for a problem, then "-" must be printed at the corresponding position. If a user has submitted several solutions to solve one problem, then the highest score will be counted.

The ranklist must be printed in non-decreasing order of the ranks. For those who have the same rank, users must be sorted in nonincreasing order according to the number of perfectly solved problems. And if there is still a tie, then they must be printed in increasing order of their id's. For those who has never submitted any solution that can pass the compiler, or has never submitted any solution, they must NOT be shown on the ranklist. It is guaranteed that at least one user can be shown on the ranklist.

Sample Input:

7 4 20
20 25 25 30
00002 2 12
00007 4 17
00005 1 19
00007 2 25
00005 1 20
00002 2 2
00005 1 15
00001 1 18
00004 3 25
00002 2 25
00005 3 22
00006 4 -1
00001 2 18
00002 1 20
00004 1 15
00002 4 18
00001 3 4
00001 4 2
00005 2 -1
00004 2 0

Sample Output:

1 00002 63 20 25 - 18
2 00005 42 20 0 22 -
2 00007 42 - 25 - 17
2 00001 42 18 18 4 2
5 00004 40 15 0 25 -
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct Student{
    int id;
    int score[6];
    bool flag;
    int allscore;
    int solve; 
}stu[10010];
int n,k,m;
void init(){
    for(int i=1;i<=n;i++){
        stu[i].id=i;
        stu[i].flag=false;
        stu[i].allscore=0;
        stu[i].solve = 0;
        memset(stu[i].score,-1,sizeof(stu[i].score));
    }
}
bool cmp(Student a,Student b){
    if(a.flag != b.flag){
        return a.flag > b.flag;
    }else if(a.allscore != b.allscore){
        return a.allscore > b.allscore;
    }else if(a.solve != b.solve){
        return a.solve > b.solve;
    }else{
        return a.id < b.id;
    }
}
int main(){
    scanf("%d %d %d",&n,&k,&m);
    init();
    int *full = new int[k];
    for(int i=1;i<=k;i++){
        scanf("%d",&full[i]);
    }
    for(int i=0;i<m;i++){
        int tempid,tempnum,tempscore;
        scanf("%d %d %d",&tempid,&tempnum,&tempscore);
        if(tempscore != -1){
            stu[tempid].flag = true;
        }
        if(tempscore == -1 && stu[tempid].score[tempnum] == -1){
            stu[tempid].score[tempnum] = 0;
        }
        if(tempscore == full[tempnum] && stu[tempid].score[tempnum] < full[tempnum]){
            stu[tempid].solve++;
        }
        if(tempscore > stu[tempid].score[tempnum]){
            stu[tempid].score[tempnum] = tempscore;
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=k;j++){
            if(stu[i].score[j] != -1){
                stu[i].allscore = stu[i].allscore + stu[i].score[j]; 
            }
        }
    }
    sort(stu+1,stu+1+n,cmp);
    int r = 1;
    for(int i=1;i<=n && stu[i].flag==true;i++){
        if(i>1 && stu[i].allscore != stu[i-1].allscore){
            r = i;
        }
        printf("%d %05d %d ",r,stu[i].id,stu[i].allscore);
        for(int j=1;j<=k;j++){
            if(j != k){
                if(stu[i].score[j] != -1)
                    printf("%d ",stu[i].score[j]);
                else
                    printf("- ");
            }else{
                if(stu[i].score[j] != -1)
                    printf("%d",stu[i].score[j]);
                else
                    printf("-");
            }
        }
        printf("\n");
    }
    return 0;
}

 

PAT A1083 List Grades (25分)

Given a list of N student records with name, ID and grade. You are supposed to sort the records with respect to the grade in non-increasing order, and output those student records of which the grades are in a given interval.

Input Specification:

Each input file contains one test case. Each case is given in the following format:

N
name[1] ID[1] grade[1]
name[2] ID[2] grade[2]
... ...
name[N] ID[N] grade[N]
grade1 grade2

where name[i] and ID[i] are strings of no more than 10 characters with no space, grade[i] is an integer in [0, 100], grade1 and grade2 are the boundaries of the grade's interval. It is guaranteed that all the grades are distinct.

Output Specification:

For each test case you should output the student records of which the grades are in the given interval [grade1grade2] and are in non-increasing order. Each student record occupies a line with the student's name and ID, separated by one space. If there is no student's grade in that interval, output NONE instead.

Sample Input 1:

4
Tom CS000001 59
Joe Math990112 89
Mike CS991301 100
Mary EE990830 95
60 100

Sample Output 1:

Mike CS991301
Mary EE990830
Joe Math990112

Sample Input 2:

2
Jean AA980920 60
Ann CS01 80
90 95

Sample Output 2:

NONE
#include<cstdio>
#include<algorithm>
using namespace std;
struct Student{
    char name[15];
    char id[15];
    int grade;
}stu[100];
bool cmp(Student a,Student b){
    return a.grade > b.grade;
}
int main(){
    int n;
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        scanf("%s %s %d",stu[i].name,stu[i].id,&stu[i].grade);
    }
    int grade1,grade2;
    scanf("%d %d",&grade1,&grade2);
    Student *newstu = new Student[n];
    int num = 0;
    for(int i=0;i<n;i++){
        if(stu[i].grade >= grade1 && stu[i].grade <= grade2){
            newstu[num] = stu[i];
            num++;
        }
    }
    sort(newstu,newstu+num,cmp);
    if(num ==0){
        printf("NONE\n");
    }else{
        for(int i=0;i<num;i++){
            printf("%s %s\n",newstu[i].name,newstu[i].id);
        }
    }
    return 0;
}
PAT A1080 Graduate Admission (30分)

It is said that in 2011, there are about 100 graduate schools ready to proceed over 40,000 applications in Zhejiang Province. It would help a lot if you could write a program to automate the admission procedure.

Each applicant will have to provide two grades: the national entrance exam grade GE​​, and the interview grade GI​​. The final grade of an applicant is (. The admission rules are:

  • The applicants are ranked according to their final grades, and will be admitted one by one from the top of the rank list.

  • If there is a tied final grade, the applicants will be ranked according to their national entrance exam grade GE​​. If still tied, their ranks must be the same.

  • Each applicant may have K choices and the admission will be done according to his/her choices: if according to the rank list, it is one's turn to be admitted; and if the quota of one's most preferred shcool is not exceeded, then one will be admitted to this school, or one's other choices will be considered one by one in order. If one gets rejected by all of preferred schools, then this unfortunate applicant will be rejected.

  • If there is a tied rank, and if the corresponding applicants are applying to the same school, then that school must admit all the applicants with the same rank, even if its quota will be exceeded.

Input Specification:

Each input file contains one test case.

Each case starts with a line containing three positive integers: N (≤), the total number of applicants; M (≤), the total number of graduate schools; and K (≤), the number of choices an applicant may have.

In the next line, separated by a space, there are M positive integers. The i-th integer is the quota of the i-th graduate school respectively.

Then N lines follow, each contains 2 integers separated by a space. The first 2 integers are the applicant's GE​​ and GI​​, respectively. The next K integers represent the preferred schools. For the sake of simplicity, we assume that the schools are numbered from 0 to M1, and the applicants are numbered from 0 to N1.

Output Specification:

For each test case you should output the admission results for all the graduate schools. The results of each school must occupy a line, which contains the applicants' numbers that school admits. The numbers must be in increasing order and be separated by a space. There must be no extra space at the end of each line. If no applicant is admitted by a school, you must output an empty line correspondingly.

Sample Input:

11 6 3
2 1 2 2 2 3
100 100 0 1 2
60 60 2 3 5
100 90 0 3 4
90 100 1 2 0
90 90 5 1 3
80 90 1 0 2
80 80 0 1 2
80 80 0 1 2
80 70 1 3 2
70 80 1 2 3
100 100 0 2 4

Sample Output:

0 10
3
5 6 7
2 8

1 4
#include<cstdio>
#include<algorithm>
using namespace std;
struct Student{
    int GE,GI,sum;
    int r,stuid;
    int choice[6];
}stu[40010];
struct School{
    int id[40010]; //录取的学生编号 
    int quota;
    int admitnum;
    int lastadmit;
}sch[120];
bool cmpStu(Student a,Student b){
    if(a.sum != b.sum){
        return a.sum > b.sum;
    }else{
        return a.GE > b.GE;
    }
}
bool cmpID(int a,int b){
    return stu[a].stuid < stu[b].stuid;
}
int main(){
    int n,m,k;
    scanf("%d %d %d",&n,&m,&k);
    for(int i=0;i<m;i++){
        scanf("%d",&sch[i].quota);
        sch[i].admitnum = 0;
        sch[i].lastadmit = -1;
    }
    for(int i=0;i<n;i++){
        scanf("%d %d",&stu[i].GE,&stu[i].GI);
        for(int j=0;j<k;j++){
            scanf("%d",&stu[i].choice[j]);
        }
        stu[i].sum = (stu[i].GE + stu[i].GI) / 2.0;
        stu[i].stuid = i;
    }
    sort(stu,stu+n,cmpStu);
    for(int i=0;i<n;i++){
        if(i>0 && stu[i].sum==stu[i-1].sum && stu[i].GE == stu[i-1].GE){
            stu[i].r = stu[i-1].r;
        }else{
            stu[i].r = i;
        }
    }
    for(int i=0;i<n;i++){
        for(int j=0;j<k;j++){
            int cho = stu[i].choice[j];
            int num = sch[cho].admitnum;
            int last = sch[cho].lastadmit;
            if(num < sch[cho].quota || (last != -1 && stu[i].r == stu[last].r)){
                sch[cho].id[num] = i;
                sch[cho].admitnum ++;
                sch[cho].lastadmit = i;
                break;
            }
        }
    }
    for(int i=0;i<m;i++){
        if(sch[i].admitnum > 0){
            sort(sch[i].id,sch[i].id+sch[i].admitnum,cmpID);
            for(int j=0;j<sch[i].admitnum;j++){
                printf("%d",stu[sch[i].id[j]].stuid);
                if(j<sch[i].admitnum - 1)
                    printf(" ");
            }
        }
        printf("\n");
    }
    return 0;
}

 

 

 

 
posted @ 2020-01-25 23:50  程序员小应  阅读(196)  评论(0编辑  收藏  举报