PAT排序题总结

来源:互联网 发布:地图数据可视化 编辑:程序博客网 时间:2024/05/29 02:39

PAT排序题总结

1.概述

这两天专门抽时间把PAT甲级的排序题给都做了,没那么简单,不可能只让你排序,一般还需要再加点别的东西,比如说,

1.排序+贪心算法

1125. Chain the Ropes,

2.排序+整数集划分

1113. Integer Set Partition ,
这是最简单的,只是当时做的中文版的题目,他写的是|n1-n2|尽量小,|S1-S2|尽量大,整的我当时一脸蒙圈,不过在这道题中说的非常清楚、|n1 - n2| is minimized first, and then |S1 - S2| is maximized.,首先满足|n1 - n2|最小,其次|S1-S2|最大,早这么说不就好了吗?

3.条件排序

1028. List Sorting (25)
也是最简单的

4.多维排序

1016. Phone Bills (25)这种多维排序我原来很是烦恼,就比如说这个,计算电话费,天数,小时,分钟还得转化,想想就麻烦,看柳婼学姐博客得到了一个思路,那就是把这些时间都转化成最小的单位,比如说这个题,都转化成分钟,以0点为起点,转化成分钟,这就简单多了,当然这道题还有个需要注意的就是,如果有人从一天打到另一天了呢,所以针对这个题,我们从前一天的0点开始计时。
总之,这种多维题的思路就是把多维转化成一维的,类似的还有一个开门签到的题目,到时候找到了再补上来。

5.多种排序

1012. The Best Rank (25)这种排序呢不是由单一的因素决定排序的,几乎里面的每种元素都排列一遍。

2.实际例题分析

1125. Chain the Ropes (25)

Given some segments of rope, you are supposed to chain them into one rope. Each time you may only fold two segments into loops and chain them into one piece, as shown by the figure. The resulting chain will be treated as another segment of rope and can be folded again. After each chaining, the lengths of the original two segments will be halved.

Your job is to make the longest possible rope out of N given segments.

Input Specification:

Each input file contains one test case. For each case, the first line gives a positive integer N (2 <= N <= 104). Then N positive integer lengths of the segments are given in the next line, separated by spaces. All the integers are no more than 104.

Output Specification:

For each case, print in a line the length of the longest possible rope that can be made by the given segments. The result must be rounded to the nearest integer that is no greater than the maximum length.

Sample Input:

810 15 12 3 4 13 1 15

Sample Output:

14

分析:

这套题意思是这样的,两个绳子绑在一起,两个绳子长度会减半,那现在给你N段绳子,按照上面的规则求出最大的长度。那我们尽量让长的少损失,所以从小到大排序,先把短的绳子捆在一起,以此增大绳子的长度,这样长的绳子不会损失太多,这就是传说中的贪心算法。

代码:

#include<cstdio>#include<vector>#include<algorithm>using namespace std;int main(){    int N;    scanf("%d", &N);    vector<int> v(N);    for (int i = 0; i < N; i++) {        scanf("%d", &v[i]);    }    sort(v.begin(), v.end());    double sum = v[0];    for (int i = 1; i < N; i++) {        sum = (sum + v[i])*1.0 / 2;    }    printf("%d", int(sum));    return 0;}

1113. Integer Set Partition (25)

Given a set of N (> 1) positive integers, you are supposed to partition them into two disjoint sets A1 and A2 of n1 and n2 numbers, respectively. Let S1 and S2 denote the sums of all the numbers in A1 and A2, respectively. You are supposed to make the partition so that |n1 - n2| is minimized first, and then |S1 - S2| is maximized.

Input Specification:

Each input file contains one test case. For each case, the first line gives an integer N (2 <= N <= 105), and then N positive integers follow in the next line, separated by spaces. It is guaranteed that all the integers and their sum are less than 231.

Output Specification:

For each case, print in a line two numbers: |n1 - n2| and |S1 - S2|, separated by exactly one space.

Sample Input 1:

1023 8 10 99 46 2333 46 1 666 555

Sample Output 1:

0 3611

Sample Input 2:

13110 79 218 69 3721 100 29 135 2 6 13 5188 85

Sample Output 2:

1 9359

解析:

题目大意是给定一组数,让你分成两个不相交的集合,使得这两个集合的元素个数相差最小的前提下,两个集合的总和之差最大首先对N个元素排序,计算前N/2个元素的总和S1,即n1=N/2,n2=N-N/2,然后用N个元素的总和sum-S1得剩余的元素的总和S2,  对于,当N位偶数时|n1-n2|=0,对于,当N位奇数时|n1-n2|=1。

代码

#include<iostream>#include<vector>#include<math.h>#include<algorithm>using namespace std;int main(){    int N;    cin >> N;    vector<int> v(N + 1);    for (int i = 1; i <= N; i++)        cin >> v[i];    sort(v.begin()+1, v.end());    int n1, n2, S1=0, S2=0;    n1 = N /2;    n2 = N- n1;    cout << abs(n1 - n2);    cout << " ";    for (int i = 1; i <= n1; i++)        S1 += v[i];    for (int i = n1 + 1; i <= N; i++)        S2 += v[i];    cout << abs(S1 - S2);    return 0;}

1098. Insertion or Heap Sort (25)

According to Wikipedia:

Insertion sort iterates, consuming one input element each repetition, and growing a sorted output list. At each iteration, insertion sort removes one element from the input data, finds the location it belongs within the sorted list, and inserts it there. It repeats until no input elements remain.

Heap sort divides its input into a sorted and an unsorted region, and it iteratively shrinks the unsorted region by extracting the largest element and moving that to the sorted region. it involves the use of a heap data structure rather than a linear-time search to find the maximum.

Now given the initial sequence of integers, together with a sequence which is a result of several iterations of some sorting method, can you tell which sorting method we are using?

Input Specification:

Each input file contains one test case. For each case, the first line gives a positive integer N (<=100). Then in the next line, N integers are given as the initial sequence. The last line contains the partially sorted sequence of the N numbers. It is assumed that the target sequence is always ascending. All the numbers in a line are separated by a space.

Output Specification:

For each test case, print in the first line either “Insertion Sort” or “Heap Sort” to indicate the method used to obtain the partial result. Then run this method for one more iteration and output in the second line the resuling sequence. It is guaranteed that the answer is unique for each test case. All the numbers in a line must be separated by a space, and there must be no extra space at the end of the line.

Sample Input 1:

103 1 2 8 7 5 9 4 6 01 2 3 7 8 5 9 4 6 0

Sample Output 1:

Insertion Sort1 2 3 5 7 8 9 4 6 0

Sample Input 2:

103 1 2 8 7 5 9 4 6 06 4 5 1 0 3 2 7 8 9

Sample Output 2:

Heap Sort5 4 3 1 0 2 6 7 8 9

解析:题目大意是给定一个数组的初始序列v1和v1排序步骤中某一序列v2,问是插入排序,还是堆排序,并且输出v2的下一排序序列
如果是插入排序,那么v2序列的前几个数是有序的,剩余的数和v1相同位置的数相同,如果不是插入排序,那就直接判断为堆排序。
如果是插入排序再排下一个序列时就简单了,如果前k个数是有序的,那么我们只要再把前k+1的数用sort函数排成有序的就行了。
堆排序的特点是后面的数是有序的,但前面的顺序就不一定了,找到第一个不是前面所有序列的最大值的那一个数字i,把它和第一个数字交换,然后对1~i-1的数组进行一次向下调整。

向下调整,low和high是需要调整的区间,因为是大顶堆,就是不断比较当前结点和自己的孩子结点哪个大,如果孩子大就把孩子结点和自己交换,然后再不断调整直到到达区间的最大值不能再继续了为止
代码

#include<cstdio>#include<vector>#include<algorithm>using namespace std;vector<int> v1, v2;void print(vector<int> v) {    for (int j = 1; j < v.size(); j++) {        if (j == 1)            printf("%d", v[j]);        else            printf(" %d", v[j]);    }}void adjust(int low, int high) {    int i = 1, j = i * 2;    while (j <= high) {        if (j + 1 <= high&&v2[j] < v2[j + 1])            j = j + 1;        if (v2[i] < v2[j]) {            swap(v2[i], v2[j]);            i = j;            j = i * 2;        }        else {            break;        }    }}int main(){    int N,i;    scanf("%d", &N);    v1.resize(N + 1), v2.resize(N + 1);    for (int i = 1; i <= N; i++)        scanf("%d", &v1[i]);    for (int i = 1; i <= N; i++)        scanf("%d", &v2[i]);    i = 2;    while (i <=N  && v2[i-1] <= v2[i])i++;//注意边界问题,要小于等于才可以    int j = i ;    while (i<=N && v2[i] == v1[i])i++;    if (i == N+1) {        printf("Insertion Sort\n");        sort(v2.begin()+1, v2.begin()+ j+1 );        print(v2);    }    else {        printf("Heap Sort\n");        i = N ;        while (i >= 2 && v2[i] >= v2[i - 1])//这里也要注意边界问题,记得加上等号            i--;        swap(v2[1],v2[i]);        adjust(1, i-1);        print(v2);    }    return 0;}

1083. 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 [grade1, grade2] 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:

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

Sample Output 1:

Mike CS991301Mary EE990830Joe Math990112

Sample Input 2:

2Jean AA980920 60Ann CS01 8090 95

Sample Output 2:

NONE

分析
给定学生的成绩,在给定一个分数段,输出这个分数段的人的姓名和学号。
定义一个结构体,sort排序一下,再定义一个flag,1表示没有没有满足要求的,1表示有满足要求的,然后从头到尾循环,只要是成绩满足要求输出即可,更新flag=1,结束后没有满足的,,即flag输出NONE

代码

#include<cstdio>#include<string.h>#include<vector>#include<algorithm>using namespace std;struct node {    char name[11], ID[11];    int grade;};bool cmp(node a, node b) {    return a.grade > b.grade;}int main(){    int N,Low,High;    scanf("%d", &N);    vector<node> v(N);    for (int i = 0; i < N; i++) {        scanf("%s %s %d", v[i].name,v[i].ID,&v[i].grade);    }    scanf("%d %d", &Low, &High);    sort(v.begin(), v.end(), cmp);    int flag = 0;    for (int i = 0; i < N; i++) {        if (v[i].grade >= Low&&v[i].grade <= High) {            printf("%s %s\n", v[i].name, v[i].ID);            flag = 1;        }    }    if (flag == 0) {        printf("NONE");    }    return 0;}

1075. PAT Judge (25)

The ranklist of PAT is generated from the status list, which shows the scores of the submittions. 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 (<=104), the total number of users, K (<=5), the total number of problems, and M (<=105), the total number of submittions. 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 submittion in the following format:

user_id problem_id partial_score_obtained

where partial_score_obtained is either -1 if the submittion 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 2020 25 25 3000002 2 1200007 4 1700005 1 1900007 2 2500005 1 2000002 2 200005 1 1500001 1 1800004 3 2500002 2 2500005 3 2200006 4 -100001 2 1800002 1 2000004 1 1500002 4 1800001 3 400001 4 200005 2 -100004 2 0

Sample Output:

1 00002 63 20 25 - 182 00005 42 20 0 22 -2 00007 42 - 25 - 172 00001 42 18 18 4 25 00004 40 15 0 25 -

分析
这道题是这样的,N个用户,K个问题,给定M个提交,K个问题的满分用数组P[6]来存储,问题的提交格式为用户id,题号,得分
默认得分为-2,表示没有提交过,规定如果得分为-1,说明本次提交没有通过编译器,还有需要注意的是,

如果提交的一次也没通过编译器或没提交过将不在排名中显示

所以我们定义一个结构体

struct node {int id, p_id, p_score, total_score, p[6], flag,//标记要不要输出 perfect,//记录满分的个数    rank;//记录排名};

输入结束后循环每个用户,计算总分的和满分的同时检查该用户是不是满足输出的条件,如果他的成绩不等于-1且不等于-2,表明该用户满足输出的条件。
然后按照要求用sort()函数排序,输出时如果成绩既不等于-2也不等于-2,直接输出。如果成绩等于-1,表示没有通过编译,输出0,否则输出’-‘。

要注意排名并列的名次

#include<cstdio>#include<vector>#include<algorithm>using namespace std;struct node {    int id, p_id, p_score, total_score, p[6], flag, perfect,rank;};bool cmp(node a, node b) {    if (a.total_score != b.total_score) {        return a.total_score > b.total_score;    }    else if (a.perfect != b.perfect) {        return a.perfect > b.perfect;    }    else return a.id < b.id;}int main(){    int N, K, M, P[6];    scanf("%d %d %d", &N, &K, &M);    vector<node> v(N + 1);    for (int i = 1; i <= K; i++)        scanf("%d", &P[i]);    for (int i = 0; i <= N; i++) {        /*        默认为-2,表示没提交过,        -1表示表示没通过编译器        */        fill(v[i].p, v[i].p + 6, -2);        v[i].flag = 0;    }    for (int i = 0; i < M; i++) {        int id, p_id, p_score;        scanf("%d %d %d", &id, &p_id, &p_score);        v[id].id = id;        if (v[id].p[p_id] < p_score) {            v[id].p[p_id] = p_score;        }     }    for (int i = 1; i <= N; i++) {            v[i].flag = 0;            /*如果成绩有大于等于0的,标记flag=1,表示可以输出            */        for (int j = 1; j <= K; j++) {            if (v[i].p[j] != -1 && v[i].p[j] != -2) {                v[i].total_score += v[i].p[j];                v[i].flag = 1;            }            if (v[i].p[j] == P[j])v[i].perfect++;        }    }    int rank = 1;    sort(v.begin()+1, v.end(), cmp);    for (int i = 1; i <= N; i++) {        v[i].rank = i;        if (i != 1 && v[i].total_score == v[i - 1].total_score) {            v[i].rank = v[i - 1].rank;        }    }    for (int i = 1; i <=N; i++) {        if (v[i].flag) {            printf("%d %05d %d", v[i].rank, v[i].id, v[i].total_score);            for (int j = 1; j <= K; j++) {                if (v[i].p[j] != -1&& v[i].p[j] != -2)                    printf(" %d", v[i].p[j]);                else if(v[i].p[j] == -1)printf(" 0");                else printf(" -");            }            printf("\n");        }    }    return 0;}

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(圣人)”; 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 (<=105), 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 8010000001 64 9010000002 90 6010000011 85 8010000003 85 8010000004 80 8510000005 82 7710000006 83 7610000007 90 7810000008 75 7910000009 59 9010000010 88 4510000012 80 10010000013 90 9910000014 66 60

Sample Output:

1210000013 90 9910000012 80 10010000003 85 8010000011 85 8010000004 80 8510000007 90 7810000006 83 7610000005 82 7710000002 90 6010000014 66 6010000008 75 7910000001 64 90

分析
给定人数N,最低分数L,高品质分数线H,
题目要求进入排名首要条件是Virtue_Grade和Talent_Grade的得分都得大于等于L分,然后根据Virtue_Grade和Talent_Grade的分数将分为四个等级:

如果Virtue_Grade>=H&&Talent_Grade>=H则为sages,如果Virtue_Grade>=H&&Talent_Grade<H 则为noblemen如果Virtue_Grade<H&&Talent_Grade<H&&Virtue_Grade>Talent_Grade 则为noblemen其他的为fool men

并且按照总成绩的非递增序列排序,如果总成绩相等按照Virtue的非递增序列排序,如果还相等,按照ID的递增序列排序
结构体定义如下:

struct node {int ID, Virtue, Talent;}V;

定义一个vector P(4),分别把四个等级的人放到P[0],P[1],P[2],P[3]中,输出四个向量时先排序,在按照要求输出。

代码:

#include<cstdio>#include<vector>#include<string.h>#include<algorithm>using namespace std;struct node {    int ID, Virtue, Talent;}V;bool cmp(node a, node b) {    int sum1 = a.Virtue + a.Talent, sum2 = b.Virtue + b.Talent;    if (sum1 != sum2)        return sum1 > sum2;    else if (a.Virtue != b.Virtue)        return a.Virtue > b.Virtue;    else return a.ID<b.ID;}int main(){    int N, L, H,M=0;    scanf("%d %d %d", &N, &L, &H);    //vector<node> V(N);    M = N;    vector<node> P[4];    for (int i = 0; i < N; i++) {        scanf("%d %d %d", &V.ID, &V.Virtue, &V.Talent);        if(V.Talent >=L&&V.Virtue >=L){            if (V.Virtue >= H&&V.Talent >= H) {                P[0].push_back(V);            }            else if (V.Talent < H&&V.Virtue >= H) {                P[1].push_back(V);            }            else if (V.Talent < H&&V.Virtue < H&&V.Virtue >= V.Talent) {                P[2].push_back(V);            }            else{                P[3].push_back(V);            }        }        else M--;    }    //printf("\n");    printf("%d\n", M);    for (int i = 0; i < 4; i++) {        sort(P[i].begin(), P[i].end(), cmp);        for (int j = 0; j < P[i].size(); j++) {            printf("%d %d %d\n", P[i][j].ID, P[i][j].Virtue, P[i][j].Talent);        }        //printf("\n");    }    return 0;}

1055. 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 (<=105) - the total number of people, and K (<=103) - 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 [-106, 106]) of a person. Finally there are K lines of queries, each contains three positive integers: M (<= 100) - the maximum number of outputs, and [Amin, Amax] 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 [Amin, Amax]. 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 4Zoe_Bill 35 2333Bob_Volk 24 5888Anny_Cin 95 999999Williams 30 -22Cindy 76 76000Alice 18 88888Joe_Mike 32 3222Michael 5 300000Rosemary 40 5888Dobby 24 5888Billy 24 5888Nobody 5 04 15 454 30 354 5 951 45 50

Sample Output:

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

分析:
给定N组世界上最富裕的人,包括最富裕人的姓名,年龄和财富。
然后根据要求输出某一年龄段的人,如果有,将这组人先安装财富的非递增序列排序,如果财富相等,按照年龄的非递减顺序排序,如果还是年龄相等姓名递增顺序排序,然后输出,没有则输出None。
最初我的想法是先按年龄排序,再去找对应的年龄段,再排序,输出,结果超时了,哈哈哈哈。
那怎么办呢?我们为什么要排好么多次序呢?可以直接在刚开始就按照输出的要求排好顺序。然后找出每个年龄的前一百名,把这些人放到另一个数组中V中,最后输出时,先找到满足要求的,并压入v中,如果v大于0,输出即可,如果数组v元素个数大于M输出前M个即可,小于M,都输出即可。

代码:
#include
#include

1028. List Sorting (25)

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

Input

Each input file contains one test case. For each case, the first line contains two integers N (<=100000) 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

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 1000007 James 85000010 Amy 90000001 Zoe 60

Sample Output 1

000001 Zoe 60000007 James 85000010 Amy 90

Sample Input 2

4 2000007 James 85000010 Amy 90000001 Zoe 60000002 James 98

Sample Output 2

000010 Amy 90000002 James 98000007 James 85000001 Zoe 60

Sample Input 3

4 3000007 James 85000010 Amy 90000001 Zoe 60000002 James 90

Sample Output 3

000001 Zoe 60000007 James 85000002 James 90000010 Amy 90

代码

#include<iostream>#include<string.h>#include<algorithm>using namespace std;int N, C;struct node {     char name[10];    int Grade, ID;}V[100010];bool cmp(node a, node b) {    if (C == 1)return a.ID < b.ID;    else if (C == 2) {        if(strcmp(a.name, b.name))        return strcmp(a.name, b.name) < 0;        else return a.ID < b.ID;    }    else if (C == 3) {        if(a.Grade != b.Grade)            return a.Grade < b.Grade;        else return a.ID < b.ID;    }}int main(){    cin >> N >> C;    for (int i = 0; i < N; i++) {        scanf("%d %s %d", &V[i].ID, V[i].name, &V[i].Grade);    }    sort(V, V+N, cmp);    for (int i = 0; i < N; i++) {        printf("%06d %s %d\n", V[i].ID, V[i].name, V[i].Grade);    }    return 0;}

1025. PAT Ranking (25)

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 is your job to write a program to correctly merge all the ranklists and generate the final rank.

Input Specification:

Each input file contains one test case. For each case, the first line contains a positive number N (<=100), the number of test locations. Then N ranklists follow, each starts with a line containing a positive integer K (<=300), the number of testees, and then K lines containing the registration number (a 13-digit number) and the total score of each testee. All the numbers in a line are separated by a space.

Output Specification:

For each test case, first print in one line the total number of testees. Then print the final ranklist in the following format:

registration_number final_rank location_number local_rank

The locations are numbered from 1 to N. The output must be sorted in nondecreasing order of the final ranks. The testees with the same score must have the same rank, and the output must be sorted in nondecreasing order of their registration numbers.

Sample Input:

251234567890001 951234567890005 1001234567890003 951234567890002 771234567890004 8541234567890013 651234567890011 251234567890014 1001234567890012 85

Sample Output:

91234567890005 1 1 11234567890014 1 2 11234567890001 3 1 21234567890003 3 1 21234567890004 5 1 41234567890012 5 2 21234567890002 7 1 51234567890013 8 2 31234567890011 9 2 4

分析:
定义结构体

struct node {    string reg_num;    int location_num, local_rank,Grade,final_rank;};

每输完一个组,排好序,用local_rank记录本地排名,然后在插入v数组中。最后再排一次序。注意并列的情况。
代码

#include<iostream>#include<string>#include<vector>#include<algorithm>using namespace std;struct node {    string reg_num;    int location_num, local_rank,Grade,final_rank;};bool cmp(node a, node b) {    if (a.Grade != b.Grade)        return a.Grade > b.Grade;    else         return a.reg_num < b.reg_num;}int main(){    int N, K,Grade;    string num;    cin >> N;    vector<node> sum;    for (int i = 1; i <=N; i++) {        cin >> K;        vector<node> v(K );        for (int j = 0; j < K; j++) {            cin >> num >> Grade;            v[j].reg_num = num;            v[j].location_num = i;            v[j].Grade = Grade;        }        sort(v.begin(), v.end(),cmp);        for (int j = 0; j < K; j++) {            if (j>0&&v[j].Grade == v[j - 1].Grade) {                v[j].local_rank = v[j-1].local_rank;            }else                v[j].local_rank = j + 1;                sum.push_back(v[j]);        }    }    sort(sum.begin(), sum.end(),cmp);    cout << sum.size() << endl;    for (int i = 0; i < sum.size(); i++) {        if (i > 0 && sum[i].Grade == sum[i - 1].Grade)            sum[i].final_rank = sum[i - 1].final_rank;        else            sum[i].final_rank = i + 1;            printf("%s %d %d %d\n", sum[i].reg_num.c_str(), sum[i].final_rank, sum[i].location_num, sum[i].local_rank);    }    return 0;}

1016. Phone Bills (25)

A long-distance telephone company charges its customers by the following rules:

Making a long-distance call costs a certain amount per minute, depending on the time of day when the call is made. When a customer starts connecting a long-distance call, the time will be recorded, and so will be the time when the customer hangs up the phone. Every calendar month, a bill is sent to the customer for each minute called (at a rate determined by the time of day). Your job is to prepare the bills for each month, given a set of phone call records.

Input Specification:

Each input file contains one test case. Each case has two parts: the rate structure, and the phone call records.

The rate structure consists of a line with 24 non-negative integers denoting the toll (cents/minute) from 00:00 - 01:00, the toll from 01:00 - 02:00, and so on for each hour in the day.

The next line contains a positive number N (<= 1000), followed by N lines of records. Each phone call record consists of the name of the customer (string of up to 20 characters without space), the time and date (mm:dd:hh:mm), and the word “on-line” or “off-line”.

For each test case, all dates will be within a single month. Each “on-line” record is paired with the chronologically next record for the same customer provided it is an “off-line” record. Any “on-line” records that are not paired with an “off-line” record are ignored, as are “off-line” records not paired with an “on-line” record. It is guaranteed that at least one call is well paired in the input. You may assume that no two records for the same customer have the same time. Times are recorded using a 24-hour clock.

Output Specification:

For each test case, you must print a phone bill for each customer.

Bills must be printed in alphabetical order of customers’ names. For each customer, first print in a line the name of the customer and the month of the bill in the format shown by the sample. Then for each time period of a call, print in one line the beginning and ending time and date (dd:hh:mm), the lasting time (in minute) and the charge of the call. The calls must be listed in chronological order. Finally, print the total charge for the month in the format shown by the sample.

Sample Input:

10 10 10 10 10 10 20 20 20 15 15 15 15 15 15 15 20 30 20 15 15 10 10 1010CYLL 01:01:06:01 on-lineCYLL 01:28:16:05 off-lineCYJJ 01:01:07:00 off-lineCYLL 01:01:08:03 off-lineCYJJ 01:01:05:59 on-lineaaa 01:01:01:03 on-lineaaa 01:02:00:01 on-lineCYLL 01:28:15:41 on-lineaaa 01:05:02:24 on-lineaaa 01:04:23:59 off-line

Sample Output:

CYJJ 0101:05:59 01:07:00 61 $12.10Total amount: $12.10CYLL 0101:06:01 01:08:03 122 $24.4028:15:41 28:16:05 24 $3.85Total amount: $28.25aaa 0102:00:01 04:23:59 4318 $638.80Total amount: $638.80

分析:
计算电话费,给定开始打电话的时间和挂掉电话的时间,但没有顺序。
我们首先把时间以月初为起始点按分钟计时,然后排序。
排好序后一个人打电话和挂掉电话的事件紧挨着,定义一个map数组custom,即map<string, vector<Phone_Bills>> custom,把某一个人打电话和挂电话的事件压进去。随后以此弹出,计算费用。
注意跨天打电话的。

代码:

#include<iostream>#include<string>#include<vector>#include<map>#include<algorithm>using namespace std;int cost[25] = { 0 }, month, day, hour, minute, N;struct Phone_Bills {    string name;    int month, day, hour, minute,status,time;};bool cmp(Phone_Bills a, Phone_Bills b) {    if(a.name!=b.name)        return a.name < b.name;    return  a.time < b.time;}double rate(Phone_Bills a) {    double total = cost[a.hour] * a.minute + cost[24] * 60 * a.day;    for (int i = 0; i < a.hour; i++)        total += cost[i] * 60;    return total / 100.0;}int main(){    string name, flag;    for (int i = 0; i < 24; i++) {        cin >> cost[i];        cost[24] += cost[i];    }    cin >> N;    vector<Phone_Bills> data(N);    for (int i = 0; i < N; i++) {        cin >> data[i].name;        scanf("%d:%d:%d:%d", &data[i].month, &data[i].day, &data[i].hour, &data[i].minute);        cin >> flag;        if (flag == "on-line")data[i].status = 1;        else data[i].status = 0;        data[i].time = data[i].day * 24 * 60 + data[i].hour * 60 + data[i].minute;      }    sort(data.begin(), data.end(),cmp);    map<string, vector<Phone_Bills>> custom;    for (int i = 1; i < N; i++) {        if (data[i].name == data[i - 1].name&&data[i-1].status == 1 && data[i].status == 0) {            custom[data[i - 1].name].push_back(data[i - 1]);            custom[data[i].name].push_back(data[i]);        }    }    for (auto it : custom) {        vector<Phone_Bills> temp = it.second;        cout << it.first;        printf(" %02d\n",temp[0].month);        double total = 0;        for (int i = 1; i < temp.size(); i += 2) {            double t = rate(temp[i])- rate(temp[i-1]);            printf("%02d:%02d:%02d %02d:%02d:%02d %d $%0.2lf\n", temp[i - 1].day, temp[i - 1].hour, temp[i - 1].minute, temp[i].day, temp[i].hour, temp[i].minute, temp[i ].time - temp[i-1].time, t);            total += t;        }        printf("Total amount: $%.2f\n", total);    }    return 0;}

1012. 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 Algebra), 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 C, M, E 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

Each input file contains one test case. Each case starts with a line containing 2 numbers N and M (<=2000), 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 C, M and E. Then there are M lines, each containing a student ID.

Output

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 6310101 98 85 88310102 70 95 88310103 82 87 94310104 91 91 91310105 85 90 90310101310102310103310104310105999999

Sample Output

1 C1 M1 E1 A3 AN/A

分析:
定义结构体

struct node {        int ID, score[4], rank[4];    };score分别用于记录A,C,M,E的分数      rank 分别用于记录A,C,M,E的名次  

在输上成绩时计算平均值,然后按照每个科目从小到大排名,另外还要定义一个m数组用于标记某个同学是否存在,m[ID]=1,我用的map方法,不知道为什么,我原先定义的m[1000001],根本就不能运行。
在查找时,先判断m【ID】是否等于1,不是输出N/A,是的话在通过ID找到元素,再寻找排名最小的。

最后在输出排序时永远不要忘记值相等的情况

代码

#include<iostream>#include<vector>#include<map>#include<algorithm>using namespace std;struct node {    int ID, score[4], rank[4];};int k;//用于标记要排哪一科的名次bool cmp1(node a, node b) {    return a.score[k] > b.score[k];}int main(){    int N, M, ID;    char C[5] = "ACME";    cin >> N >> M;    vector<node> v(N);    map<int, int> m;    for (int i = 0; i < N; i++) {        cin >> v[i].ID >> v[i].score[1] >> v[i].score[2] >> v[i].score[3];        v[i].score[0] = (v[i].score[1] + v[i].score[2] + v[i].score[3]) / 3;        m[v[i].ID] = 1;    }    for (k = 0; k < 4; k++) {        sort(v.begin(), v.end(), cmp1);        for (int i = 0; i < N; i++) {            if (i > 0 && v[i].score[k] == v[i - 1].score[k])                v[i].rank[k] = v[i - 1].rank[k];            else                v[i].rank[k] = i;        }    }    for (int i = 0; i < M; i++) {        cin >> ID;        if (m[ID]) {            int i = 0;            for (i = 0; i < N; i++)                if (v[i].ID == ID) break;            int best = 0;            for (int j = 1; j < 4; j++)                if (v[i].rank[best] > v[i].rank[j])best = j;            printf("%d %c\n", v[i].rank[best]+1, C[best]);        }        else {            printf("N/A\n");        }    }    return 0;}
原创粉丝点击