接上一篇 PAT 甲级 - 入门模拟 ,自我感觉这部分才是真正的算法入门,对基础的数据结构提供了很好的类型题进行匹配练习
包括分类:排序 、 散列 、 贪心 、 二分 、 双指针 、 打表、递推
排序
思想解释
排序题主要是获取排序后的结果而不是过程,大部分代码可以使用 sort()
函数进行直接处理,要熟练编写 cmp 排序规则(包括结构体形式的多变量规则)
有些题需要获取排名,只需在已经排序好的数组或容器中遍历全部的数据,如果和上一个数据相同,则排名相同,否则排名加 1
类型练习
1062
题目: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: , the total number of people to be ranked; , 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 , 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 . All the numbers are separated by a space.
Output Specification:
The first line of output must give , 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
思路: 使用结构体对每个学生的信息进行存储,根据题意编写排序规则
-
存储学生信息的结构体除了基本信息外还应包含总成绩 (total) 与类别 (rank)
-
编写排序规则,升序用小于号 "<",降序反之
-
使用动态容器 vector 创建一个结构体数组,处理时将及格的放入数组,最后输出 size
-
在循环中创建一个临时结构体变量进行数据的处理,符合哪种条件就将 rank 置于相应的等级
-
需要注意读题,
not lower than
就代表>=
代码:
1 |
|
1012
题目: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 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:
1 | StudentID C M E A |
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
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
思路: 编写排序规则对每一科进行排序将排名放到结构体相应位置,使用 Map 集合创建索引,进行查询
-
使用结构体对每个学生进行存储,成绩和排名用数组的方式创建
-
循环输入,平均分要四舍五入,使用
answer+0.5
的方式实现 -
对每一科进行排序,编写循环式排序规则时,下标变量必须提前定义,处理并列排名的情况
-
将最后一轮排序(数据全部处理完)后的顺序,以 ID 为键,下标为值的方式放入 Map 集合方便查询 (unordered_map 时间更短)
-
对每一个被查询学生查找排名最小的一项,返回其值并获得课程下标,按格式输出
代码:
1 |
|
1016
题目: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 , the toll from , and so on for each hour in the day.
The next line contains a positive number , 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 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
思路: 使用 Map 集合对名字自动排序,集合值为通话记录结构体组成的动态数组
-
使用结构体存储通话记录,定义一个 time 用来记录开年零点到记录的时间(分钟为单位)方便后续比较和处理
-
使用 Map 集合存储姓名对应的结构体数组,Map 自动排序,处理时遍历取出即可
-
对取出的数组中对所有的通话记录进行排序,判断每两条记录的状态进行话费的计算
代码:
1 |
|
1025
题目: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 , the number of test locations. Then N ranklists follow, each starts with a line containing a positive integer , 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
思路: 结构体 + 动态数组存储,分情况处理排名,考场内排名的处理用临时数组每输入完一个考场处理一次的形式
代码:
1 |
|
1028
题目: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 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 then the records must be sorted in increasing order according to ID’s; if then the records must be sorted in non-decreasing order according to names; and if 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
思路: 设置变量 C 在排序规则之外,根据 C 的值返回相应的规则;注意 non-decreasing 表示非降序(≠升序)比较运算符要用 <=
代码:
1 |
|
1055
题目: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: - the total number of people, and - the number of queries. Then N lines follow, each contains the name (string of no more than 8 characters without space), age (integer in ), and the net worth (integer in ) of a person. Finally there are K lines of queries, each contains three positive integers: - 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 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
思路: 使用多个结构体动态数组,挑选数据后只排序一次,减少复杂度
-
结构体的字符串使用字符数组,配合 scanf() 减少复杂度
-
输入数据后按规则进行排序,如果年龄相同只保存 100 人,减少遍历长度
代码:
1 |
|
1075
题目: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, , the total number of users, , the total number of problems, and , 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 −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 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 -
思路: 创建一个 N 人的结构体数组,输入时直接以 ID 作为下标进行输入
-
结构体进行存储,需要自行添加的变量有:
isShow
只要有一条通过编译,置为 true 表示可以输出;passnum
表示满分题目数量 -
输入记录时会有一个人重复提交的情况,每次比对相同 ID 是不现实的,直接创建一个数据规模为 的结构体数组,以 ID 作为下标进行记录提交处理
-
输入的成绩不止未通过和有成绩两种状态,还有未提交的情况,将成绩的初始值置为 -2 表示未提交
-
记录输入完成根据有效成绩,计算 total_score 和 passnum
-
进行排序后为每名同学赋值 rank,然后判断 isShow 的值循环输出
代码:
1 |
|
1083
题目: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:
1 | N |
where name[i]
and ID[i]
are strings of no more than 10 characters with no space, grade[i]
is an integer in , 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:
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
思路: 输入完成后根据区间判断,记录符合范围的个数,不符合将值改为 -1,排序输出
代码:
1 |
|
1080
题目: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 , and the interview grade . 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 . 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: , the total number of applicants; , the total number of graduate schools; and , 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+K integers separated by a space. The first 2 integers are the applicant’s and , respectively. The next K 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 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
思路: 同时建立学生学校两个结构体分别进行处理
-
学校结构体创建一个 last 变量,方便比对招满后最后一人的排名是否有与之并列的存在
-
学生结构体创建 ID 变量和 rank 保存原始编号和排名
-
按成绩排序分配排名后,对每个学生进行处理,遍历每个学生的志愿,判断是否达到入校条件
-
对每个学校的招入名单排序输出
代码:
1 |
|
1095
题目:Cars on Campus
Zhejiang University has 8 campuses and a lot of gates. From each gate we can collect the in/out times and the plate numbers of the cars crossing the gate. Now with all the information available, you are supposed to tell, at any specific time point, the number of cars parking on campus, and at the end of the day find the cars that have parked for the longest time period.
Input Specification:
Each input file contains one test case. Each case starts with two positive integers , the number of records, and the number of queries. Then N lines follow, each gives a record in the format:
plate_number hh:mm:ss status
where plate_number
is a string of 7 English capital letters or 1-digit numbers; hh:mm:ss
represents the time point in a day by hour:minute:second, with the earliest time being 00:00:00
and the latest 23:59:59
; and status
is either in
or out
.
Note that all times will be within a single day. Each in
record is paired with the chronologically next record for the same car provided it is an out
record. Any in
records that are not paired with an out
record are ignored, as are out
records not paired with an in
record. It is guaranteed that at least one car is well paired in the input, and no car is both in
and out
at the same moment. Times are recorded using a 24-hour clock.
Then K lines of queries follow, each gives a time point in the format hh:mm:ss
. Note: the queries are given in ascending order of the times.
Output Specification:
For each query, output in a line the total number of cars parking on campus. The last line of output is supposed to give the plate number of the car that has parked for the longest time period, and the corresponding time length. If such a car is not unique, then output all of their plate numbers in a line in alphabetical order, separated by a space.
Sample Input:
16 7
JH007BD 18:00:01 in
ZD00001 11:30:08 out
DB8888A 13:00:00 out
ZA3Q625 23:59:50 out
ZA133CH 10:23:00 in
ZD00001 04:09:59 in
JH007BD 05:09:59 in
ZA3Q625 11:42:01 out
JH007BD 05:10:33 in
ZA3Q625 06:30:50 in
JH007BD 12:23:42 out
ZA3Q625 23:55:00 in
JH007BD 12:24:23 out
ZA133CH 17:11:22 out
JH007BD 18:07:01 out
DB8888A 06:30:50 in
05:10:00
06:30:50
11:00:00
12:23:42
14:00:00
18:00:00
23:59:00
Sample Output:
1
4
5
2
1
0
1
JH007BD ZD00001 07:20:09
思路: 使用 MAP 集合存储数据,车牌号为键,结构体数组为值
-
使用结构体对出入记录进行存储,同时计算记录是在一天中的第几秒
-
遍历集合,将每个车牌对应的记录数组进行排序,进行出入配对,将当前时间点放入出入数组中,并累积一个车牌号停车的时长
-
遍历一天中的 86400 秒,将每秒的停车数量记录下来,公式:时间点前的所有进减去所有出
-
比较所有时长取出停车时间最长的,并列也放入数组,然后对车牌号排序
代码:
1 |
|
总结
- 如果需要对排序进行查询,一定要数据全部处理完成后再放入 MAP 集合或其他容器中,不然会导致下标混乱,如 T1012
- 排序型算法要处理的数据难免过大,可以采用以下方式缩小复杂度:
- 将局部变量定义在循环外,尽量缩小循环内的执行语句量
- 输入输出函数使用 scanf() 和 printf(),字符串可以使用字符数组,排序使用 strcmp() 函数
- 局部多次排序可以使用单次排序,尤其对大型数据的小型查询,如 T1028
- 循环中进行比较的动态数组,不要直接放入,存在每次比较过后要清空之前数据的可能,直接赋值,如 T095
散列
思想解释
将元素通过某种方式转换为整数使其尽量唯一的表示这个元素的特质
如:求在长度为 N 的数组中,求 M 个数有没有出现过,就可以设置一个 judge[] 以 Ni 作为下标,将值置为 true,查询时只需判断 Mi 作为下标时值是否为 true 即可
将直接输入的数作为数组下标直接表示这个数的特质的方式经常使用
类型练习
1084
题目:Broken Keyboard
On a broken keyboard, some of the keys are worn out. So when you type some sentences, the characters corresponding to those keys will not appear on screen.
Now given a string that you are supposed to type, and the string that you actually type out, please list those keys which are for sure worn out.
Input Specification:
Each input file contains one test case. For each case, the 1st line contains the original string, and the 2nd line contains the typed-out string. Each string contains no more than 80 characters which are either English letters (case insensitive), digital numbers , or _
(representing the space). It is guaranteed that both strings are non-empty.
Output Specification:
For each test case, print in one line the keys that are worn out, in the order of being detected. The English letters must be capitalized. Each worn out key must be printed once only. It is guaranteed that there is at least one worn out key.
Sample Input:
7_This_is_a_test
_hs_s_a_es
Sample Output:
7TI
思路:
-
字符串写法:遍历预想字符串的每个字符去实际字符串中查找,如果本身和它大写形式查找的返回值都是
string::npos
,保留其大写形式 -
散列写法:设立一个标记数组(字符会自动转为 ASCII 码作为数字下标),遍历预想字符串,如果不相同且没被标记过,放入数组
代码:
1 |
|
1092
题目:To Buy or Not to Buy
Eva would like to make a string of beads with her favorite colors so she went to a small shop to buy some beads. There were many colorful strings of beads. However the owner of the shop would only sell the strings in whole pieces. Hence Eva must check whether a string in the shop contains all the beads she needs. She now comes to you for help: if the answer is Yes
, please tell her the number of extra beads she has to buy; or if the answer is No
, please tell her the number of beads missing from the string.
For the sake of simplicity, let’s use the characters in the ranges , , and to represent the colors. For example, the 3rd string in Figure 1 is the one that Eva would like to make. Then the 1st string is okay since it contains all the necessary beads with 8 extra ones; yet the 2nd one is not since there is no black bead and one less red bead.
Input Specification:
Each input file contains one test case. Each case gives in two lines the strings of no more than 1000 beads which belong to the shop owner and Eva, respectively.
Output Specification:
For each test case, print your answer in one line. If the answer is Yes
, then also output the number of extra beads Eva has to buy; or if the answer is No
, then also output the number of beads missing from the string. There must be exactly 1 space between the answer and the number.
Sample Input 1:
ppRYYGrrYBR2258
YrR8RrY
Sample Output 1:
Yes 8
Sample Input 2:
ppRYYGrrYB225
YrR8RrY
Sample Output 2:
No 2
思路: 使用数组或集合对每个颜色的个数进行记录,减去需要购买的值(且个数不为 0),不存在将 lack++;根据 lack 进行输出
代码:
1 |
|
1041
题目:Be Unique
Being unique is so important to people on Mars that even their lottery is designed in a unique way. The rule of winning is simple: one bets on a number chosen from . The first one who bets on a unique number wins. For example, if there are 7 people betting on {5 31 5 88 67 88 17}, then the second one who bets on 31 wins.
Input Specification:
Each input file contains one test case. Each case contains a line which begins with a positive integer and then followed by N bets. The numbers are separated by a space.
Output Specification:
For each test case, print the winning number in a line. If there is no winner, print None
instead.
Sample Input 1:
7 5 31 5 88 67 88 17
Sample Output 1:
31
Sample Input 2:
5 888 666 666 888 888
Sample Output 2:
None
思路: 使用两个数组分别记录个数和输入顺序
代码:
1 |
|
1050
题目:String Subtraction
Given two strings S1 and S2, is defined to be the remaining string after taking all the characters in S2 from S1. Your task is simply to calculate for any given strings. However, it might not be that simple to do it fast.
Input Specification:
Each input file contains one test case. Each case consists of two lines which gives S1 and S2, respectively. The string lengths of both strings are no more than . It is guaranteed that all the characters are visible ASCII codes and white space, and a new line character signals the end of a string.
Output Specification:
For each test case, print in one line.
Sample Input:
They are students.
aeiou
Sample Output:
Thy r stdnts.
思路: 使用数组以字符的 ASCII 码为下标标记 S1 中每个出现的字符值为 1,S2 出现的字符置为 0,遍历 S1 只输出标记数组值为 1 的字符
代码:
1 |
|
1048
题目:Find Coins
Eva loves to collect coins from all over the universe, including some other planets like Mars. One day she visited a universal shopping mall which could accept all kinds of coins as payments. However, there was a special requirement of the payment: for each bill, she could only use exactly two coins to pay the exact amount. Since she has as many as coins with her, she definitely needs your help. You are supposed to tell her, for any given amount of money, whether or not she can find two coins to pay for it.
Input Specification:
Each input file contains one test case. For each case, the first line contains 2 positive numbers: , the total number of coins) and , the amount of money Eva has to pay). The second line contains N face values of the coins, which are all positive numbers no more than 500. All the numbers in a line are separated by a space.
Output Specification:
For each test case, print in one line the two face values V1 and V2 (separated by a space) such that and . If such a solution is not unique, output the one with the smallest V1. If there is no solution, output No Solution
instead.
Sample Input 1:
8 15
1 2 8 7 2 4 11 15
Sample Output 1:
4 11
Sample Input 2:
7 14
1 8 7 2 4 11 15
Sample Output 2:
No Solution
思路: 使用数组标记每个面值出现的次数,然后从 1 到 bill 对每一个面值进行遍历(规则就是从小到大),判断输出
代码:
1 |
|
贪心
思想解释
总是做出在当前看来最好的选择。也就是说贪心算法并不从整体最优考虑,它所作出的选择只是在某种意义上的局部最优选择
类型练习
1070
题目:Mooncake
Mooncake is a Chinese bakery product traditionally eaten during the Mid-Autumn Festival. Many types of fillings and crusts can be found in traditional mooncakes according to the region’s culture. Now given the inventory amounts and the prices of all kinds of the mooncakes, together with the maximum total demand of the market, you are supposed to tell the maximum profit that can be made.
Note: partial inventory storage can be taken. The sample shows the following situation: given three kinds of mooncakes with inventory amounts being 180, 150, and 100 thousand tons, and the prices being 7.5, 7.2, and 4.5 billion yuans. If the market demand can be at most 200 thousand tons, the best we can do is to sell 150 thousand tons of the second kind of mooncake, and 50 thousand tons of the third kind. Hence the total profit is (billion yuans).
Input Specification:
Each input file contains one test case. For each case, the first line contains 2 positive integers , the number of different kinds of mooncakes, and thousand tons), the maximum total demand of the market. Then the second line gives the positive inventory amounts (in thousand tons), and the third line gives the positive prices (in billion yuans) of N kinds of mooncakes. All the numbers in a line are separated by a space.
Output Specification:
For each test case, print the maximum profit (in billion yuans) in one line, accurate up to 2 decimal places.
Sample Input:
3 200
180 150 100
7.5 7.2 4.5
Sample Output:
9.45
思路: 使用结构体放入数组,根据单价排序,循环判断需求量计算收益
代码:
1 |
|
1033
题目:To Fill or Not to Fill
With highways available, driving a car from Hangzhou to any other city is easy. But since the tank capacity of a car is limited, we have to find gas stations on the way from time to time. Different gas station may give different price. You are asked to carefully design the cheapest route to go.
Input Specification:
Each input file contains one test case. For each case, the first line contains 4 positive numbers: , the maximum capacity of the tank; , the distance between Hangzhou and the destination city; , the average distance per unit gas that the car can run; and , the total number of gas stations. Then N lines follow, each contains a pair of non-negative numbers: Pi, the unit gas price, and , the distance between this station and Hangzhou, for . All the numbers in a line are separated by a space.
Output Specification:
For each test case, print the cheapest price in a line, accurate up to 2 decimal places. It is assumed that the tank is empty at the beginning. If it is impossible to reach the destination, print The maximum travel distance = X
where X
is the maximum possible distance the car can run, accurate up to 2 decimal places.
Sample Input 1:
50 1300 12 8
6.00 1250
7.00 600
7.00 150
7.10 0
7.20 200
7.50 400
7.30 1000
6.85 300
Sample Output 1:
749.17
Sample Input 2:
50 1300 12 2
7.10 0
7.00 600
Sample Output 2:
The maximum travel distance = 1200.00
思路: 将终点也作为加油站的形式进行存储,对所有的加油站按照距离进行排序,每次从起点判断满油状态下可以到达的加油站中油价最便宜的一个,根据价格进行不同的处理
代码:
1 |
|
1037
题目:Magic Coupon
The magic shop in Mars is offering some magic coupons. Each coupon has an integer N printed on it, meaning that when you use this coupon with a product, you may get N times the value of that product back! What is more, the shop also offers some bonus product for free. However, if you apply a coupon with a positive N to this bonus product, you will have to pay the shop N times the value of the bonus product… but hey, magically, they have some coupons with negative N’s!
For example, given a set of coupons {1 2 4 −1}, and a set of product values {7 6 −2 −3} (in Mars dollars M$) where a negative value corresponds to a bonus product. You can apply coupon 3 (with N being 4) to product 1 (with value M$7) to get M$28 back; coupon 2 to product 2 to get M$12 back; and coupon 4 to product 4 to get M$3 back. On the other hand, if you apply coupon 3 to product 4, you will have to pay M$12 to the shop.
Each coupon and each product may be selected at most once. Your task is to get as much money back as possible.
Input Specification:
Each input file contains one test case. For each case, the first line contains the number of coupons NC, followed by a line with NC coupon integers. Then the next line contains the number of products NP, followed by a line with NP product values. Here , and it is guaranteed that all the numbers will not exceed .
Output Specification:
For each test case, simply print in a line the maximum amount of money you can get back.
Sample Input:
4
1 2 4 -1
4
7 6 -2 -3
Sample Output:
43
思路: 将两组数据放入两个数组,将数据从小到大排序,负数从小到大分别相乘,正数从大到小分别相乘,0 不做处理
代码:
1 |
|
1067
题目:Sort with Swap(0, i)
Given any permutation of the numbers {0, 1, 2,…, N−1}, it is easy to sort them in increasing order. But what if Swap(0, *)
is the ONLY operation that is allowed to use? For example, to sort {4, 0, 2, 1, 3} we may apply the swap operations in the following way:
1 | Swap(0, 1) => {4, 1, 2, 0, 3} |
Now you are asked to find the minimum number of swaps need to sort the given permutation of the first N nonnegative integers.
Input Specification:
Each input file contains one test case, which gives a positive followed by a permutation sequence of {0, 1, …, N−1}. All the numbers in a line are separated by a space.
Output Specification:
For each case, simply print in a line the minimum number of swaps need to sort the given permutation.
Sample Input:
10
3 5 7 2 6 4 9 0 8 1
Sample Output:
9
思路: 使用数字作为下标顺序,作为位置的方式存储数组,当每个位置上数字与位置相同表示交换完毕(这样无需进行下标查找)
-
遍历位置与数字是否对应,当不对应且 0 未处于排列首位时交换 0 与本该在 0 的位置上的数字
swap(per[0], per[per[0]]);
-
当 0 回到首位继续判断位置是否对应,若未成功将 0 换到不对应的位置继续判断操作
代码:
1 |
|
1038
题目:Recover the Smallest Number
Given a collection of number segments, you are supposed to recover the smallest number from them. For example, given
{}, we can recover many numbers such like or with respect to different orders of combinations of these segments, and the smallest number is .
Input Specification:
Each input file contains one test case. Each case gives a positive integer followed by N number segments. Each segment contains a non-negative integer of no more than 8 digits. All the numbers in a line are separated by a space.
Output Specification:
For each test case, print the smallest number in one line. Notice that the first digit must not be zero.
Sample Input:
5 32 321 3214 0229 87
Sample Output:
22932132143287
思路: 采用字符串进行读取,定义一个等式相加的排序规则
代码:
1 |
|
二分
思想解释
在有序的排列中,根据目标值 goal 与中间值 mid () 的大小关系不断缩小范围的查找方式
mid 的求值:有些数据长度过大,导致 超出当前数据类型的范围,可以采用 的式子
常使用 [algorithm] 下的 upper_bound(lower_bound) 和 binary_search 方法
类型练习
1085
题目:Perfect Sequence
Given a sequence of positive integers and another positive integer p. The sequence is said to be a perfect sequence if where M and m are the maximum and minimum numbers in the sequence, respectively.
Now given a sequence and a parameter p, you are supposed to find from the sequence as many numbers as possible to form a perfect subsequence.
Input Specification:
Each input file contains one test case. For each case, the first line contains two positive integers N and p, where is the number of integers in the sequence, and is the parameter. In the second line there are N positive integers, each is no greater than .
Output Specification:
For each test case, print in one line the maximum number of integers that can be chosen to form a perfect subsequence.
Sample Input:
10 8
2 3 20 4 5 1 6 7 8 9
Sample Output:
8
思路: 将输入的数据从小到大排序,遍历每一个数将它作为 m 计算 M,使用 upper_bound() 函数求出 完美队列 的长度,取长度最大值
注意:数据范围为 那么 可能溢出 int 型,所以使用 long long
强转
代码:
1 |
|
1010
题目:Radix
Given a pair of positive integers, for example, 6 and 110, can this equation 6 = 110 be true? The answer is yes
, if 6 is a decimal number and 110 is a binary number.
Now for any pair of positive integers and , your task is to find the radix of one number while that of the other is given.
Input Specification:
Each input file contains one test case. Each case occupies a line which contains 4 positive integers:
N1 N2 tag radix
Here N1
and N2
each has no more than 10 digits. A digit is less than its radix and is chosen from the set {0-9, a
-z
} where 0-9 represent the decimal numbers 0-9, and a
-z
represent the decimal numbers 10-35. The last number radix
is the radix of N1
if tag
is 1, or of N2
if tag
is 2.
Output Specification:
For each test case, print in one line the radix of the other number so that the equation N1
= N2
is true. If the equation is impossible, print Impossible
. If the solution is not unique, output the smallest possible radix.
Sample Input 1:
6 110 1 10
Sample Output 1:
2
Sample Input 2:
1 ab 1 2
Sample Output 2:
Impossible
思路: 将确定进制的数转换为十进制,将为判断的数采用二分法来确定进制;一个数的进制越大,转换为十进制的结果越大:101 的二进制为 5,但十六进制为 272
-
编写一个转换函数,其中要解决字符映射问题,手动转换十进制思路:反向循环相加 当前数×指数的位数幂
-
编写查找进制函数,其中要解决的时上下界的确定,下界 low 为单个位最大数 +1,上界 height 位 max(low, 要求数字的十进制),每次二分 作为指数转换为十进制,如果得到的数为负数(过大溢出)或超过要求数字的十进制,表示当前进制过大,否者过小,每次更换范围,直到相等
代码:
1 |
|
1044
题目:Shopping in Mars
Shopping in Mars is quite a different experience. The Mars people pay by chained diamonds. Each diamond has a value (in Mars dollars M). When making the payment, the chain can be cut at any position for only once and some of the diamonds are taken off the chain one by one. Once a diamond is off the chain, it cannot be taken back. For example, if we have a chain of 8 diamonds with values M , and we must pay M 15. We may have 3 options:
-
Cut the chain between 4 and 6, and take off the diamonds from the position 1 to 5
with values -
Cut before 5 or after 6, and take off the diamonds from the position 4 to 6 (with values ).
-
Cut before 8, and take off the diamonds from the position 7 to 8 (with values ).
Now given the chain of diamond values and the amount that a customer has to pay, you are supposed to list all the paying options for the customer.
If it is impossible to pay the exact amount, you must suggest solutions with minimum lost.
Input Specification:
Each input file contains one test case. For each case, the first line contains 2 numbers: N (≤105), the total number of diamonds on the chain, and , the amount that the customer has to pay. Then the next line contains N positive numbers which are the values of the diamonds. All the numbers in a line are separated by a space.
Output Specification:
For each test case, print i-j
in a line for each pair of i
≤ j
such that D i
+ … + D j
= M. Note that if there are more than one solution, all the solutions must be printed in increasing order of i
.
If there is no solution, output i-j
for pairs of i
≤ j
such that D i
+ … + D j
>M with (D i
+ … + D j
−M) minimized. Again all the solutions must be printed in increasing order of i
.
It is guaranteed that the total value of diamonds is sufficient to pay the given amount.
Sample Input 1:
16 15
3 2 1 5 4 6 8 7 16 10 15 11 9 12 14 13
Sample Output 1:
1-5
4-6
7-8
11-11
Sample Input 2:
5 13
2 4 5 7 9
Sample Output 2:
2-4
4-5
思路: 序列的和是有序递增的,因此一个连续序列和的右端减去左端就是该子序列的和 (must pay)
-
对有序序列可以采用二分查找的方式,遍历左端点,二分查找右端点,查找值是 >=m,因为可能有无法匹配求最小损失的情况
-
方法函数的参数可以使用
(int i, int &j, int &tempsum)
的方式直接改变 j 和 tempsum 的值
代码:
1 |
|
双指针
思想解释
使用两个指针指向序列的不同位置,用指针的移动操作减少处理复杂度的方式
其中归并排序和快速排序都可以使用双指针的方式进行编写
-
归并排序: 常使用的多为二路归并排序,将一组数分为两两一组进行组内排序,再将每组两两合并进行排序,以此类推
-
快速排序: 每次挑选一个数字作为比较参照,将大于参照数的值放入右侧,小于放左侧
类型练习
1089
题目:Insert or Merge
According to Wikipedia:
Insertion sort iterates, consuming one input element each repetition, and growing a sorted output list. 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.
Merge sort works as follows: Divide the unsorted list into N sublists, each containing 1 element (a list of 1 element is considered sorted). Then repeatedly merge two adjacent sublists to produce new sorted sublists until there is only 1 sublist remaining.
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 “Merge 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:
10
3 1 2 8 7 5 9 4 6 0
1 2 3 7 8 5 9 4 6 0
Sample Output 1:
Insertion Sort
1 2 3 5 7 8 9 4 6 0
Sample Input 2:
10
3 1 2 8 7 5 9 4 0 6
1 3 2 8 5 7 4 9 0 6
Sample Output 2:
Merge Sort
1 2 3 8 4 5 7 9 0 6
思路: 先判断是否为插入排序,如果不是则一定是归并排序
-
建立两个初始数组,和目标数组,初始数组中一个用于插入排序,一个用于归并排序
-
注意初始数组不能直接和目标数组相同,否者容易出现双解
代码:
1 |
|
1029
** 题目:Median **
Given an increasing sequence S of N integers, the median is the number at the middle position. For example, the median of is 12, and the median of is 15. The median of two sequences is defined to be the median of the nondecreasing sequence which contains all the elements of both sequences. For example, the median of S1 and S2 is 13.
Given two increasing sequences of integers, you are asked to find their median.
Input Specification:
Each input file contains one test case. Each case occupies 2 lines, each gives the information of a sequence. For each sequence, the first positive integer is the size of that sequence. Then N integers follow, separated by a space. It is guaranteed that all the integers are in the range of long int.
Output Specification:
For each test case you should output the median of the two given sequences in a line.
Sample Input:
4 11 12 13 14
5 9 10 15 16 17
Sample Output:
13
思路: 只需要输出中位数而无需对整个序列进行处理,所以不必采用合并后排序的方式进行判断,使用双指针判断相应位置
-
设置 i、j 两个指针分别指向两个数组,每次判断较小值后指针后移,当后移次数为 输出
-
可能存在一个数组的整体数字过于小导致真个数组全部判断完成,两个指针的移动次数和还未到达中位数,所以要在数组的后边界设置一个较大数,int 型最大为 (代码可以写作
0x7fffffff
或(1<<31)-1
)的形式 -
最后到达中位位置时,两个数的值还未进行判断,再次判断指针输出较小值
代码:
1 |
|
其他
思想解释
- 打表: 将小范围结果计算出来,直接在程序中调用,用空间换时间
- 递推: 大部分算法都是有递推规则的,根据规则编写仅适合这一道题的程序
- 随机选择:有点玄学
类型练习
1093
题目:Count PAT’s
The string APPAPT
contains two PAT
’s as substrings. The first one is formed by the 2nd, the 4th, and the 6th characters, and the second one is formed by the 3rd, the 4th, and the 6th characters.
Now given any string, you are supposed to tell the number of PAT
’s contained in the string.
Input Specification:
Each input file contains one test case. For each case, there is only one line giving a string of no more than 105 characters containing only P
, A
, or T
.
Output Specification:
For each test case, print in one line the number of PAT
’s contained in the string. Since the result may be a huge number, you only have to output the result moded by 1000000007.
Sample Input:
APPAPT
Sample Output:
2
思路: 根据递推思想,组成 "PAT" 的个数就是字符’A’左边’P’的个数乘右边’T’的个数
-
遍历字符串求出每个字符左边 P 的个数
-
反向遍历,遇到 T 计数器 +1,遇到 A 累加相乘取模
代码:
1 |
|
1101
题目:Quick Sort
There is a classical process named partition in the famous quick sort algorithm. In this process we typically choose one element as the pivot. Then the elements less than the pivot are moved to its left and those larger than the pivot to its right. Given N distinct positive integers after a run of partition, could you tell how many elements could be the selected pivot for this partition?
For example, given N=5 and the numbers 1, 3, 2, 4, and 5. We have:
-
1 could be the pivot since there is no element to its left and all the elements to its right are larger than it;
-
3 must not be the pivot since although all the elements to its left are smaller, the number 2 to its right is less than it as well;
-
2 must not be the pivot since although all the elements to its right are larger, the number 3 to its left is larger than it as well;
-
and for the similar reason, 4 and 5 could also be the pivot.
Hence in total there are 3 pivot candidates.
Input Specification:
Each input file contains one test case. For each case, the first line gives a positive integer N (≤105). Then the next line contains N distinct positive integers no larger than 109. The numbers in a line are separated by spaces.
Output Specification:
For each test case, output in the first line the number of pivot candidates. Then in the next line print these candidates in increasing order. There must be exactly 1 space between two adjacent numbers, and no extra space at the end of each line.
Sample Input:
5
1 3 2 4 5
Sample Output:
3
1 4 5
思路: 双向遍历,保留每个数字左边的最大值和右边的最小值,最后遍历判断是否大于左边最大值并小于右边最小值
代码:
1 |
|
- 本文标题:PAT 甲级 - 算法初步
- 本文作者:Aidan
- 创建时间:2021-08-09 07:49:46
- 本文链接:https://aidanblog.top/pat_level_a-elementary_algorithm/
- 版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!