2019年9月PAT - 练习笔记——4.1
以下页码标注的是阅读器中实际页码,而不是书本身自印的页码。
第4章 入门篇(2)——算法初步
4.1 排序
注意
-
优先队列
- 头文件 < queue >
- 升序队列:priority_queue <int,vector< int >,greater< int > > q;
- 降序队列(默认):priority_queue <int,vector< int >,less< int > >q; 相当于 priority_queue < int >
-
注意排名并列时是“1、2、3、3、5”而不是“1、2、3、3、4”
-
sort自写的cmp函数中,参数类型若漏const会报奇奇怪怪的错误
-
若vector< int > vec(n + 1)且使用1-n而不使用vec[0],注意vec[0]的值对排序等后续算法造成的影响
- 排序时不应从begin开始而应从begin+1开始
目录
- B1015/A1062 德才论
- A1012 The Best Rank
- A1016 Phone Bills
- A1025 PAT Ranking
- A1028 List Sorting
- A1055 The World’s Richest
- A1075 PAT Judge
- A1083 List Grades
- A1080 Graduate Admission
- A1095 Cars on Campus
-
B1015/A1062 德才论
宋代史学家司马光在《资治通鉴》中有一段著名的“德才论”:“是故才德全尽谓之圣人,才德兼亡谓之愚人,德胜才谓之君子,才胜德谓之小人。凡取人之术,苟不得圣人,君子而与之,与其得小人,不若得愚人。”
现给出一批考生的德才分数,请根据司马光的理论给出录取排名。
输入格式:
输入第一行给出 3 个正整数,分别为:N(≤105),即考生总数;L(≥60),为录取最低分数线,即德分和才分均不低于 L 的考生才有资格被考虑录取;H(<100),为优先录取线——德分和才分均不低于此线的被定义为“才德全尽”,此类考生按德才总分从高到低排序;才分不到但德分到线的一类考生属于“德胜才”,也按总分排序,但排在第一类考生之后;德才分均低于 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 <iostream> #include <vector> #include <algorithm> using namespace std; int low = 0, high = 0; typedef struct { int id; int de; int cai; }Student; bool Cmp(const Student&a, const Student&b) { int suma = a.de + a.cai, sumb = b.de + b.cai; if (suma != sumb) return suma > sumb; else if (a.de != b.de) return a.de > b.de; else return a.id < b.id; } void Output(vector<Student>&students) { sort(students.begin(), students.end(), Cmp); for (int i = 0;i < students.size();++i) { cout << students[i].id << " " << students[i].de << " " << students[i].cai << endl; } } int main(void) { int n = 0; cin >> n >> low >> high; vector<Student> students1, students2, students3, students4; for (int i = 0;i < n;++i) { int id = 0, de = 0, cai = 0; cin >> id >> de >> cai; if (de >= low && cai >= low) { Student student = {id, de, cai}; if (de >= high && cai >= high) students1.push_back({id, de, cai}); else if (de >= high && cai < high) students2.push_back({id, de, cai}); else if (de >= cai) students3.push_back({id, de, cai}); else students4.push_back({id, de, cai}); } } cout << students1.size() + students2.size() + students3.size() + students4.size() << endl; Output(students1); Output(students2); Output(students3); Output(students4); return 0; }
上面代码试了3次,两次通过,一次测试点3、4超时
把上面重复部分写成函数调用试了,测试点3、4超时
-
《算法笔记》P96
结构体里还存考生类别
-
-
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), andE
- 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
andA
- 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 (≤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
andE
. 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 <iostream> #include <vector> #include <map> #include <algorithm> using namespace std; const char COURSES[] = {'A', 'C', 'M', 'E'}; int main(void) { int n = 0, m = 0; cin >> n >> m; map<int, vector<int>> grades; vector<vector<int>> ranks(4, vector<int>(n, 0)); for (int i = 0;i < n;++i) { int id = 0; vector<int> courses(4, 0); cin >> id >> courses[1] >> courses[2] >> courses[3]; courses[0] = (courses[1] + courses[2] + courses[3]) / 3; grades[id] = courses; for (int j = 0;j < 4;++j) ranks[j].push_back(courses[j]); } for (int i = 0;i < 4;++i) sort(ranks[i].begin(), ranks[i].end(), greater<int>()); for (int i = 0;i < m;++i) { int id = 0; cin >> id; if (grades.end() == grades.find(id)) cout << "N/A" << endl; else { int rank = n; char course = 0; for (int j = 0;j < 4;++j) { int pos = find(ranks[j].begin(), ranks[j].end(), grades[id][j]) - ranks[j].begin(); if (pos < rank) { rank = pos; course = COURSES[j]; } } cout << rank + 1 << " " << course << endl; } } return 0; }
-
《算法笔记》P99
“……应该算作1、2、3、3、5。在具体实现时,切记不要算作1、2、3、3、4,否则中间3个测试点至少会错一个”
“本题没有明示平均分是否需要取整以及取整方式,根据题目描述中的例子可以看出是四舍五入。但本题采用向下取整的方式也能通过,或者采用更简洁的方式——不取平均,直接存储三门课的总分”
-
-
A1016 Phone Bills
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 wordon-line
oroff-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 anoff-line
record. Anyon-line
records that are not paired with anoff-line
record are ignored, as areoff-line
records not paired with anon-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 10 10 CYLL 01:01:06:01 on-line CYLL 01:28:16:05 off-line CYJJ 01:01:07:00 off-line CYLL 01:01:08:03 off-line CYJJ 01:01:05:59 on-line aaa 01:01:01:03 on-line aaa 01:02:00:01 on-line CYLL 01:28:15:41 on-line aaa 01:05:02:24 on-line aaa 01:04:23:59 off-line
Sample Output:
CYJJ 01 01:05:59 01:07:00 61 $12.10 Total amount: $12.10 CYLL 01 01:06:01 01:08:03 122 $24.40 28:15:41 28:16:05 24 $3.85 Total amount: $28.25 aaa 01 02:00:01 04:23:59 4318 $638.80 Total amount: $638.80
-
我的
#include <iostream> #include <vector> #include <map> #include <string> #include <algorithm> #include <iomanip> using namespace std; typedef struct { string name; string time; string state; }Record; int rates[24] = {0}; int total = 0; bool Cmp(const Record&a, const Record&b) { if (a.name != b.name) return a.name < b.name; else return a.time < b.time; } float Cal(const string&start, const string&end) { int period = 0; float bill = 0; int day1 = 0, hour1 = 0, minute1 = 0; sscanf(start.c_str(),"%d:%d:%d", &day1, &hour1, &minute1); int day2 = 0, hour2 = 0, minute2 = 0, second2 = 0; sscanf(end.c_str(),"%d:%d:%d", &day2, &hour2, &minute2); for (int i = day1 + 1; i <= day2 - 1;++i) { period += 24 * 60; bill += total; } if (day1 != day2) { for (int i = hour1 + 1; i < 24;++i) { period += 60; bill += rates[i] * 60; } period += 60 - minute1; bill += (float)rates[hour1] * (60 - minute1); for (int i = 0; i < hour2;++i) { period += 60; bill += rates[i] * 60; } period += minute2; bill += (float)rates[hour2] * minute2; } else { for (int i = hour1 + 1; i < hour2;++i) { period += 60; bill += rates[i] * 60; } if (hour1 != hour2) { period += 60 - minute1; bill += (float)rates[hour1] * (60 - minute1); period += minute2; bill += (float)rates[hour2] * minute2; } else { period += minute2 - minute1; bill = (float)rates[hour1] * (minute2 - minute1); } } cout << period << " $" << setiosflags(ios::fixed) << setprecision(2) << bill / 100 << endl; return bill; } int main(void) { for (int i = 0; i < 24;++i) { cin >> rates[i]; total += rates[i] * 60; } int n = 0; cin >> n; map<string, float> bills; vector<Record> records; for (int i = 0;i < n;++i) { string name = "", time = "", state = ""; cin >> name >> time >> state; records.push_back({name, time, state}); } sort(records.begin(), records.end(), Cmp); string name = ""; float sum = 0; for (int i = 0;i + 1 < n;++i) { if (records[i].name == records[i + 1].name && records[i].state == "on-line" && records[i + 1].state == "off-line") { if (records[i].name != name) { if (name != "") cout << "Total amount: $" << setiosflags(ios::fixed) << setprecision(2) << sum / 100 << endl;; name = records[i].name; cout << name << " " << records[i].time[0] << records[i].time[1] << endl; sum = 0; } string start = records[i].time.substr(3); string end = records[i + 1].time.substr(3); cout << start << " " << end << " "; sum += Cal(start, end); } } if (name != "") cout << "Total amount: $" << setiosflags(ios::fixed) << setprecision(2) << sum / 100 << endl;; return 0; }
泪如雨下,我把‘$’打成’&'找了半天错在哪
-
《算法笔记》P102
-
“注意:资费的输出需要进行单位换算,即把cent换算为dollar,所以结果要除以100”
-
”给出一组边界数据供读者测试:“
10 10 10 10 10 10 20 20 20 15 15 15 15 15 15 15 20 30 20 15 15 10 10 10 5 aaa 01:01:01:03 on-line aaa 01:02:00:01 on-line CYLL 01:28:15:41 on-line aaa 01:05:02:24 on-line aa 01:02:00:02 off-line
-
“……对已知的起始时间和终止时间,只需要不断将起始时间加1,判断其是否到达终止时间即可”
temp = rec[on]; while (temp.dd < rec[off].dd || temp.hh < rec[off].hh || temp.mm < rec[off].mm) { time++; money += toll[temp.hh]; temp.mm++; if (temp.mm >= 60) { temp.mm = 0; temp.hh++; } if (temp.hh >= 24) { temp.hh = 0; temp.dd++; } }
-
-
-
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 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:
2 5 1234567890001 95 1234567890005 100 1234567890003 95 1234567890002 77 1234567890004 85 4 1234567890013 65 1234567890011 25 1234567890014 100 1234567890012 85
Sample Output:
9 1234567890005 1 1 1 1234567890014 1 2 1 1234567890001 3 1 2 1234567890003 3 1 2 1234567890004 5 1 4 1234567890012 5 2 2 1234567890002 7 1 5 1234567890013 8 2 3 1234567890011 9 2 4
-
我的
#include <iostream> #include <vector> #include <algorithm> using namespace std; typedef struct { long long id; int score; int localNumber; }Testee; bool Cmp(const Testee&a, const Testee&b) { if (a.score != b.score) return a.score > b.score; else return a.id < b.id; } int main(void) { int n = 0, total = 0; cin >> n; vector<Testee> testees; for (int i = 0;i < n;++i) { int k = 0; cin >> k; total += k; for (int j = 0;j < k;++j) { long long id = 0; int score = 0; cin >> id >> score; testees.push_back({id, score, i + 1}); } } sort(testees.begin(), testees.end(), Cmp); cout << total << endl; int final = 1, local[301] = {0}, localScore[301] = {0}, localNow[301] = {0}; printf("%013lld", testees[0].id); cout << " " << 1 << " " << testees[0].localNumber << " " << 1 << endl; local[testees[0].localNumber] = 1; localScore[testees[0].localNumber] = testees[0].score; localNow[testees[0].localNumber] = 1; for (int i = 1;i < total;++i) { if (testees[i].score != testees[i - 1].score) final = i + 1; if (testees[i].score != localScore[testees[i].localNumber]) { local[testees[i].localNumber] = localNow[testees[i].localNumber] + 1; localScore[testees[i].localNumber] = testees[i].score; } ++localNow[testees[i].localNumber]; printf("%013lld", testees[i].id); cout << " " << final << " " << testees[i].localNumber << " " << local[testees[i].localNumber] << endl; } return 0; }
绝了:https://blog.csdn.net/qq_41325698/article/details/98032791
测试点4会考id不够13位需要补0的情况,巨坑
-
《算法笔记》P109
参考代码的结构体里存了local_rank,当读完一个考场的所有考生信息,就对该考场所有考生成绩进行排序(sort(stu + num - k, stu + num, cmp)),得到考场内排名
-
-
A1028 List Sorting
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 (≤105) 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 <iostream> #include <string> #include <vector> #include <algorithm> using namespace std; int c = 0; typedef struct { int id; string name; int grade; }Record; bool Cmp(const Record&a, const Record&b) { if (1 == c) return a.id < b.id; else if (2 == c) { if (a.name != b.name) return a.name < b.name; else return a.id < b.id; } else { if (a.grade != b.grade) return a.grade < b.grade; else return a.id < b.id; } } int main(void) { int n = 0; cin >> n >> c; vector<Record> records; for (int i = 0;i < n;++i) { int id = 0, grade = 0; string name = ""; cin >> id >> name >> grade; records.push_back({id, name, grade}); } sort(records.begin(), records.end(), Cmp); for (int i = 0;i < n;++i) { printf("%06d", records[i].id); cout << " " << records[i].name << " " << records[i].grade << endl; } return 0; }
- 《算法笔记》P112
-
-
A1055 The World’s Richest
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:
whereX
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 formatName 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 <iostream> #include <string> #include <vector> #include <algorithm> using namespace std; typedef struct { string name; int age; int worth; }Info; bool Cmp(const Info&a, const Info&b) { if (a.worth != b.worth) return a.worth > b.worth; else if (a.age != b.age) return a.age < b.age; else return a.name < b.name; } int main(void) { int n = 0, k = 0; cin >> n >> k; vector<Info> info; for (int i = 0;i < n;++i) { string name = ""; int age = 0, worth = 0; cin >> name >> age >> worth; info.push_back({name, age, worth}); } sort(info.begin(), info.end(), Cmp); for (int i = 1;i <= k;++i) { int m = 0, amin = 0, amax = 0; cin >> m >> amin >> amax; cout << "Case #" << i << ":" << endl; int count = 0; for (int j = 0;j < n && count < m;++j) { if (amin <= info[j].age && info[j].age <= amax) { ++count; cout << info[j].name << " " << info[j].age << " " << info[j].worth << endl; } } if (!count) cout << "None" << endl; } return 0; }
测试点1可能运行超时,可以再点一次
或者把cin, cout换成scanf, printf可能会好一点
-
《算法笔记》P115
“步骤2:==注意到M的范围仅在100以内,因此可以进行预处理,即将每个年龄中财富在前100名以内的人全都存到另一个数组中(因为某个年龄中财富值在100名外的人永远不会被输出),后面查询的操作均在这个新数组中进行。==这个预处理操作将显著降低查询的复杂度,使得K次查询不会超时”
“如果不进行步骤2的预处理,那么2号测试点会超时。如果在查询时单独对某个年龄区间内的人排序,也会超时”
-
-
A1075 PAT Judge
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 (≤104), the total number of users, K (≤5), the total number of problems, and M (≤105), 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), wherep[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 −1 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 thetotal_score
, and all the users with the sametotal_score
obtain the samerank
; ands[i]
is the partial score obtained for thei
-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 countedThe 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 <iostream> #include <vector> #include <algorithm> using namespace std; int k = 0; vector<int> fullMark(6, 0); bool Cmp(const vector<int>&a, const vector<int>&b) { if (a[0] != b[0]) return a[0] > b[0]; else { int count1 = 0, count2 = 0; for (int i = 1;i <= k;++i) { if (a[i] == fullMark[i]) ++count1; if (b[i] == fullMark[i]) ++count2; } if (count1 != count2) return count1 > count2; else return a[k + 1] < b[k + 1]; } } int main(void) { int n = 0, m = 0; cin >> n >> k >> m; for (int i = 1;i <= k;++i) cin >> fullMark[i]; vector<vector<int>> submissions(n + 1, vector<int>(k + 2, -2)); for (int i = 0;i < m;++i) { int id = 0, problem = 0, grade = 0; cin >> id >> problem >> grade; if (grade > submissions[id][problem]) submissions[id][problem] = grade; } for (int i = 1;i <= n;++i) { submissions[i][k + 1] = i; for (int j = 1;j <= k;++j) { if (submissions[i][j] >= 0) { if (-2 == submissions[i][0]) submissions[i][0] = 0; submissions[i][0] += submissions[i][j]; } else if (-1 == submissions[i][j]) ++submissions[i][j]; } } sort(submissions.begin() + 1, submissions.end(), Cmp); int rank = 1, pre = submissions[1][0]; for (int i = 1;i <= n;++i) { if (submissions[i][0] >= 0) { if (submissions[i][0] != pre) { pre = submissions[i][0]; rank = i; } printf("%d %05d %d", rank, submissions[i][k + 1], submissions[i][0]); for (int j = 1;j <= k;++j) { if (-2 == submissions[i][j]) cout << " -"; else cout << " " << submissions[i][j]; } cout << endl; } } return 0; }
注意排序要从begin + 1开始
-
《算法笔记》P118
-
-
A1083 List Grades
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]
andID[i]
are strings of no more than 10 characters with no space,grade[i]
is an integer in [0, 100],grade1
andgrade2
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, outputNONE
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 <iostream> #include <string> #include <vector> #include <algorithm> using namespace std; typedef struct { string name; string id; int grade; }Record; bool Cmp(const Record&a, const Record&b) { return a.grade > b.grade; } int main(void) { int n = 0; cin >> n; vector<Record> records; for (int i = 0;i < n;++i) { string name = "", id = ""; int grade = 0; cin >> name >> id >> grade; records.push_back({name, id, grade}); } sort(records.begin(), records.end(), Cmp); int grade1 = 0, grade2 = 0; cin >> grade1 >> grade2; int count = 0; for (int i = 0;i < n;++i) { if (grade1 <= records[i].grade && records[i].grade <= grade2) { ++count; cout << records[i].name << " " << records[i].id << endl; } } if (!count) cout << "NONE"; return 0; }
-
《算法笔记》P123
-
-
A1080 Graduate Admission
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 (GE+GI)/2. 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 (≤40,000), the total number of applicants; M (≤100), the total number of graduate schools; and K (≤5), 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 iii-th graduate school respectively.
Then N lines follow, each contains 2+K integers separated by a space. The first 2 integers are the applicant’s GE and GI, respectively. The next KKK integers represent the preferred schools. For the sake of simplicity, we assume that the schools are numbered from 0 to M−1, and the applicants are numbered from 0 to N−1.
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 <iostream> #include <vector> #include <algorithm> #include <queue> using namespace std; typedef struct { int id; int sum; int ge; vector<int> choices; int school; }Info; bool Cmp(const Info&a, const Info&b) { if (a.sum != b.sum) return a.sum > b.sum; else return a.ge > b.ge; } int main(void) { int n = 0, m = 0, k = 0; cin >> n >> m >> k; vector<int> quota(m, 0); for (int i = 0;i < m;++i) cin >> quota[i]; vector<Info> info; for (int i = 0;i < n;++i) { int ge = 0, gi = 0; cin >> ge >> gi; vector<int> choices(k, 0); for (int j = 0;j < k;++j) cin >> choices[j]; info.push_back({i, ge + gi, ge, choices}); } sort(info.begin(), info.end(), Cmp); vector<int> lastid(m, -1); vector<priority_queue<int, vector<int>, greater<int>>> admissions(m); for (int i = 0;i < n;++i) { for (int j = 0;j < k;++j) { int school = info[i].choices[j]; if (quota[school]) { --quota[school]; lastid[school] = i; admissions[school].push(info[i].id); break; } else if (lastid[school] != -1 && info[i].sum == info[lastid[school]].sum && info[i].ge == info[lastid[school]].ge) { admissions[school].push(info[i].id); break; } } } for (int i = 0;i < m;++i) { for (int j = 0;!admissions[i].empty();admissions[i].pop(), ++j) j ? (cout << " " << admissions[i].top()) : (cout << admissions[i].top()); cout << endl; } return 0; }
因为vector info写成vector info(n),最后一个测试点老是段错误,找bug找到失去理智
知道应该是数组越界,但找了其它所有我觉得可能越界的地方,愣是没看到这一行,orz
-
《算法笔记》P126
“……下面这组数据,输出应为5个空行“
5 5 3 0 0 0 5 5 100 100 0 1 2 100 99 1 2 0 99 100 2 1 0 99 99 1 0 2 98 98 2 0 1
-
A1095 Cars on Campus
-
我的
#include <iostream> #include <string> #include <vector> #include <algorithm> #include <map> using namespace std; typedef struct { string id; string time; string state; }Record; bool Cmp1(const Record&a, const Record&b) { if (a.id != b.id) return a.id < b.id; else return a.time < b.time; } bool Cmp2(const Record&a, const Record&b) { if (a.state.size() == 1 && b.state.size() > 1) return true; else if (a.state.size() > 1 && b.state.size() == 1) return false; else return a.time < b.time; } int main(void) { int n = 0, k = 0; cin >> n >> k; vector<Record> records; for (int i = 0;i < n;++i) { string id = "", time = "", state = ""; cin >> id >> time >> state; records.push_back({id, time, state}); } sort(records.begin(), records.end(), Cmp1); int count = 0; map<string, int> periods; for (int i = 0;i + 1 < n;++i) { if (records[i].id == records[i + 1].id && records[i].state == "in" && records[i + 1].state == "out") { records[i].state = "i"; records[i + 1].state = "o"; count += 2; int h1 = 0, m1 = 0, s1 = 0; sscanf(records[i].time.c_str(), "%d:%d:%d", &h1, &m1, &s1); int start = h1*3600+m1*60+s1; int h2 = 0, m2 = 0, s2 = 0; sscanf(records[i + 1].time.c_str(), "%d:%d:%d", &h2, &m2, &s2); int end = h2*3600+m2*60+s2; periods[records[i].id] += end - start; } } sort(records.begin(), records.end(), Cmp2); vector<int> cars(24*3600, 0); int h1 = 0, m1 = 0, s1 = 0; sscanf(records[0].time.c_str(), "%d:%d:%d", &h1, &m1, &s1); int start = h1*3600+m1*60+s1; int car = 1; for (int i = 1;i < count;++i) { int h2 = 0, m2 = 0, s2 = 0; sscanf(records[i].time.c_str(), "%d:%d:%d", &h2, &m2, &s2); int end = h2*3600+m2*60+s2; for (int j = start;j < end;++j) cars[j] = car; records[i].state == "i" ? ++car : --car; start = end; } for (int i = 0;i < k;++i) { string time = ""; cin >> time; int h1 = 0, m1 = 0, s1 = 0; sscanf(time.c_str(), "%d:%d:%d", &h1, &m1, &s1); cout << cars[h1*3600+m1*60+s1] << endl; } map<string, int>::iterator iter = periods.begin(); vector<string> ids; ids.push_back(iter->first); for(++iter;iter != periods.end();++iter) { if (iter->second > periods[ids[0]]) { ids.clear(); ids.push_back(iter->first); } else if (iter->second == periods[ids[0]]) ids.push_back(iter->first); } for (int i = 0;i < (int)ids.size();++i) cout << ids[i] << " "; int period = periods[ids[0]]; printf("%02d:%02d:%02d", period / 3600, (period % 3600) / 60, period % 60); return 0; }
这题印象很深,半年前第一次做的时候超时了,后来看牛客网的题解茅塞顿开。这次再做就比较顺了
-
《算法笔记》P132
“……由于查询的时刻是按照时间顺序递增的,因此可以设置一个变量now,用以指向valid数组里面的记录,使得now指向的记录的时刻不超过本次欲查询的时刻;同时设置一个变量numCar,以记录当前校园内的车辆数。显然,当valid[now]为"in"时,numCar加1;而当valid[now]是“out”时,numCar减1”
-