PAT甲级刷题记录-(AcWing)-(Day04排序)
课程来源AcWing 其中AcWing中的题目为翻译好的中文题目
今日刷题列表
- 1012 The Best Rank
- 1022 Digital Library
- 1025 PAT Ranking
- 1028 List Sorting
- 1039 Course List for Student
- 1052 Linked List Sorting
- 1075 PAT Judge
- 1098 Insertion or Heap Sort
1012 The Best Rank
AcWing链接 PAT链接
英语单词
- evaluate 评估 评价
- At the mean time 与此同时
- with respect to 关于
解析
- 使用
map 来存储学生的信息 - 分别对每个成绩建立一个
vecor 对其排序,在查询学生成绩的时候在排好序的vector里面找排名。 - 这边的查找排名也可以用二分查找来做,可能更快一点
注意点
- 我第一次做题的时候用了
int rank = n + 1; 本来是想让rank 初试为一个最大数的,但是忘了之前while(n--) 的时候已经把n搞成0 了,这里卡了半天,后来终于找到了 - 这道题AcWing的测试点比PAT上准一点, 在求
grade 的时候我写了round(A / 3) 在PAT上也过了, 但是在AcWing上没过, 错误案例如下, 应该用round(A / 3.0) 才行。 测试用例
100 1
135431 4 73 15
368745 43 94 38
201256 51 71 91
330141 36 32 85
716013 16 91 71
769920 45 2 60
511204 68 86 20
898775 49 53 14
112884 55 36 1
776469 29 54 38
738731 89 30 79
907419 71 17 58
383651 60 11 36
426729 23 99 32
503408 29 88 88
415325 29 31 57
164362 90 99 96
865207 39 43 95
745915 85 74 67
326962 36 26 46
848993 7 40 11
289416 27 36 15
704145 63 46 95
697517 10 56 82
886800 49 83 67
518567 54 9 20
158371 31 11 31
426712 58 52 8
768560 57 26 54
147783 58 29 35
900145 76 66 74
811907 56 32 91
117719 92 32 43
869277 17 9 3
507275 54 25 44
777986 50 49 76
763103 79 45 8
547321 74 38 35
385514 79 71 31
276025 51 57 1
734645 62 43 86
341135 26 9 79
474150 18 4 22
361938 57 75 18
374423 58 69 3
198468 84 50 33
362674 23 52 3
391470 62 70 36
133655 96 62 73
527967 73 64 28
469313 57 88 10
878081 9 49 38
604614 63 23 41
217877 4 63 17
435030 15 66 46
211277 26 86 60
186493 55 85 3
616715 87 13 90
916960 11 75 28
611032 5 60 74
500081 61 28 27
763375 91 24 73
104276 4 90 76
212765 33 89 32
796626 76 47 54
380053 46 31 22
155429 80 99 45
716284 70 89 31
671732 6 84 51
648859 9 20 55
914689 93 96 80
375198 66 37 88
590224 56 6 60
313037 79 65 38
508622 56 18 75
983349 44 0 15
479853 59 54 23
274852 12 34 44
490099 27 81 52
427390 91 75 37
823659 24 33 4
989022 90 90 8
882082 15 62 47
218210 73 49 78
760582 70 80 10
682419 32 37 45
953690 23 80 92
879559 61 39 41
499622 13 82 87
377547 88 0 32
916659 33 95 56
883351 35 35 69
760773 10 98 81
855530 45 42 32
148220 47 43 19
140953 22 94 18
466785 91 58 8
770231 19 83 33
198004 54 40 55
802080 6 67 62
886800
#include <iostream>
#include <algorithm>
#include <vector>
#include <cmath>
#include <map>
using namespace std;
map<string, vector<int>> students;
vector<int> grade[4];
int get_rank(int score, int idx) {
int res = 0;
vector<int> course = grade[idx];
if (score == course[0]) return 1;
int rank = 1;
for (int i = 1; i < course.size(); ++i) {
if (course[i] < course[i - 1])
rank = i + 1;
if (score == course[i])
return rank;
}
return res;
}
int main() {
int n, m;
cin >> n >> m;
while (n--) {
string id;
int score[4];
int A = 0;
cin >> id;
for (int i = 1; i < 4; ++i) {
cin >> score[i];
A += score[i];
}
score[0] = round(A / 3.0);
for (int i = 0; i < 4; ++i) {
grade[i].push_back(score[i]);
students[id].push_back(score[i]);
}
}
for (int i = 0; i < 4; ++i)
sort(grade[i].begin(), grade[i].end(), greater<int>());
while (m--) {
string id;
cin >> id;
if (students.count(id) == 0) puts("N/A");
else {
int rank = students.size() + 1;
int res;
string names = "ACME";
vector<int> cur_scores = students[id];
for (int i = 0; i < 4; ++i) {
int cur_rank = get_rank(cur_scores[i], i);
if (cur_rank < rank) {
rank = cur_rank;
res = i;
}
}
cout << rank << " " << names[res] << endl;
}
}
return 0;
}
1022 Digital Library
AcWing链接 PAT链接
英语单词
- is assigned 被分配
- any query 任何疑问
解析
- 主要是选择合适的存储方式
- 仔细的根据各个点来输出
注意点 - 在创建结构体的时候用
set 来存keywords , 可以在查询的时候使用cout 方法来确定是否存在(本题的输入中只包含一个关键词,也就是一个单词) cin 和getline 之间一定要加getchar() , 我在这边卡了一些时间.
第一次的答案(能通过PAT,但是在AcWing上会超时)
#include <iostream>
#include <cstdio>
#include <vector>
#include <sstream>
#include <algorithm>
#include <set>
using namespace std;
struct Book {
string id, title, author, publisher;
set<string> keywords;
int year;
} books[10010];
int main() {
int n;
cin >> n;
for (int i = 0; i < n; ++i) {
string id, title, author, publisher;
set<string> keywords;
int year;
cin >> id;
getchar();
getline(cin, title);
getline(cin, author);
string line;
getline(cin, line);
stringstream ssin(line);
string word;
while (ssin >> word) keywords.insert(word);
getline(cin, publisher);
cin >> year;
books[i] = {id, title, author, publisher, keywords, year};
}
int m;
cin >> m;
getchar();
while (m--) {
string line;
getline(cin, line);
puts(line.c_str());
vector<string> res;
if (line[0] == '1')
for (auto &book:books)
if (book.title == line.substr(3))
res.push_back(book.id);
if (line[0] == '2')
for (auto &book:books)
if (book.author == line.substr(3))
res.push_back(book.id);
if (line[0] == '3') {
for (auto &book:books)
if (book.keywords.count(line.substr(3)))
res.push_back(book.id);
}
if (line[0] == '4')
for (auto &book:books)
if (book.publisher == line.substr(3))
res.push_back(book.id);
if (line[0] == '5')
for (auto &book:books)
if (to_string(book.year) == line.substr(3))
res.push_back(book.id);
if (res.empty()) cout << "Not Found" << endl;
else {
sort(res.begin(), res.end());
for (int i = 0; i < res.size(); ++i) {
cout << res[i] << endl;
}
}
}
return 0;
}
第二次的答案 都能通过
#include <iostream>
#include <cstdio>
#include <vector>
#include <sstream>
#include <algorithm>
#include <set>
using namespace std;
struct Book {
string id, title, author, publisher;
set<string> keywords;
string year;
};
vector<Book> books;
int main() {
int n;
cin >> n;
for (int i = 0; i < n; ++i) {
string id, title, author, publisher;
set<string> keywords;
string year;
cin >> id;
getchar();
getline(cin, title);
getline(cin, author);
string line;
getline(cin, line);
stringstream ssin(line);
string word;
while (ssin >> word) keywords.insert(word);
getline(cin, publisher);
cin >> year;
books.push_back({id, title, author, publisher, keywords, year});
}
int m;
cin >> m;
getchar();
while (m--) {
string line;
getline(cin, line);
puts(line.c_str());
vector<string> res;
string info = line.substr(3);
if (line[0] == '1')
for (auto &book:books)
if (book.title == info)
res.push_back(book.id);
if (line[0] == '2')
for (auto &book:books)
if (book.author == info)
res.push_back(book.id);
if (line[0] == '3') {
for (auto &book:books)
if (book.keywords.count(info))
res.push_back(book.id);
}
if (line[0] == '4')
for (auto &book:books)
if (book.publisher == info)
res.push_back(book.id);
if (line[0] == '5')
for (auto &book:books)
if (book.year == info)
res.push_back(book.id);
if (res.empty()) cout << "Not Found" << endl;
else {
sort(res.begin(), res.end());
for (int i = 0; i < res.size(); ++i) {
cout << res[i] << endl;
}
}
}
return 0;
}
1025 PAT Ranking
AcWing链接 PAT链接
英语单词
解析
注意点
- 在计算区域排名的时候卡了一会,这里的做法是创建一个
vector<Student> local[110]; 数组来先计算学生的区域成绩,然后一个个插入到vector<Student> students (总学生榜)中,最后对总的学生计算他们的总排名
我的解答
#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
struct Student {
string id;
int grade;
int location;
int local_rank;
int final_rank;
bool operator<(const Student &s) {
if (grade != s.grade) return grade > s.grade;
return id < s.id;
}
};
vector<Student> local[110];
vector<Student> students;
int main() {
int n, k;
cin >> n;
for (int i = 1; i <= n; ++i) {
cin >> k;
string id;
int grade;
for (int j = 0; j < k; ++j) {
cin >> id >> grade;
local[i].push_back({id, grade, i});
}
auto &s = local[i];
sort(s.begin(), s.end());
for (int j = 0; j < s.size(); ++j) {
if (!j || s[j].grade < s[j - 1].grade) s[j].local_rank = j + 1;
else s[j].local_rank = s[j - 1].local_rank;
students.push_back(s[j]);
}
}
cout << students.size() << endl;
sort(students.begin(), students.end());
for (int i = 0; i < students.size(); ++i) {
if (!i || students[i].grade < students[i - 1].grade)
students[i].final_rank = i + 1;
else
students[i].final_rank = students[i - 1].final_rank;
}
for (auto &s:students) {
cout << s.id << " " << s.final_rank << " " <<
s.location << " " << s.local_rank << endl;
}
return 0;
}
1028 List Sorting
AcWing链接 PAT链接
英语单词
解析
- 主要使用自定义排序方式对结构体进行排序
一般题目里面出现了
1
0
5
10^5
105数量级就用scanf 和printf 比较稳妥
我的方法(PAT通过,AcWing超时)
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <vector>
using namespace std;
struct Records {
string id;
string name;
int grade;
};
int c;
bool cmp(Records r1, Records r2) {
if (c == 1) {
return r1.id < r2.id;
} else if (c == 2) {
if (r1.name != r2.name) return r1.name < r2.name;
return r1.id < r2.id;
} else {
if (r1.grade != r2.grade) return r1.grade < r2.grade;
return r1.id < r2.id;
}
}
int main() {
int n;
cin >> n >> c;
vector<Records> records;
for (int i = 0; i < n; ++i) {
string id, name;
int grade;
cin >> id >> name >> grade;
records.push_back({id, name, grade});
}
sort(records.begin(), records.end(), cmp);
for (int i = 0; i < records.size(); ++i) {
cout << records[i].id << " " << records[i].name << " " << records[i].grade << endl;
}
return 0;
}
把所有的cin ,cout 换为scanf 和printf 就能在两边都通过了
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <vector>
using namespace std;
struct Records {
string id;
string name;
int grade;
};
int c;
bool cmp(Records r1, Records r2) {
if (c == 1) {
return r1.id < r2.id;
} else if (c == 2) {
if (r1.name != r2.name) return r1.name < r2.name;
return r1.id < r2.id;
} else {
if (r1.grade != r2.grade) return r1.grade < r2.grade;
return r1.id < r2.id;
}
}
int main() {
int n;
scanf("%d %d", &n, &c);
vector<Records> records;
for (int i = 0; i < n; ++i) {
char id[10], name[10];
int grade;
scanf("%s %s %d", id, name, &grade);
records.push_back({id, name, grade});
}
sort(records.begin(), records.end(), cmp);
for (int i = 0; i < records.size(); ++i) {
printf("%s %s %d\n",records[i].id.c_str(),records[i].name.c_str(), records[i].grade);
}
return 0;
}
1039 Course List for Student
AcWing链接 PAT链接
英语单词
解析
- 思路较为简单,在输入课程的同时按学生姓名来存储选的课程
在查询学生课程那边我使用stringstream作为输入产生了一些问题,后来换了之后就对了,没仔细研究哪里的问题
使用map只能在PAT上通过,使用unordered_map 则两边都能过
#include <sstream>
#include <iostream>
#include <vector>
#include <algorithm>
#include <unordered_map>
using namespace std;
unordered_map<string, vector<int>> records;
int main() {
int n, k;
cin >> n >> k;
while (k--) {
int c_id, t;
cin >> c_id >> t;
for (int i = 0; i < t; ++i) {
string name;
cin >> name;
records[name].push_back(c_id);
}
}
while (n--) {
string name;
cin >> name;
auto &stu = records[name];
if (stu.empty()) cout << name << " 0" << endl;
else {
sort(stu.begin(), stu.end());
cout << name << " " << stu.size();
for (auto x:stu) {
cout << " " << x;
}
cout << endl;
}
}
return 0;
}
1052 Linked List Sorting
AcWing链接 PAT链接
英语单词
解析 使用vector来代替传统的链表完成排序操作
注意点
- 注意本题不能用
cin - 注意当链表为空的时候要输出
0 -1
#include <iostream>
#include <cstdio>
#include <unordered_map>
#include <vector>
#include <algorithm>
using namespace std;
struct Node {
string address;
int value;
string next;
};
unordered_map<string, Node> list;
bool cmp(Node n1, Node n2) {
return n1.value < n2.value;
}
int main() {
int N;
char head[10];
scanf("%d %s", &N, head);
while (N--) {
char address[10], next[10];
int value;
scanf("%s %d %s", address, &value, next);
list[address] = {address, value, next};
}
vector<Node> nodes;
for (string i = head; i != "-1"; i = list[i].next)nodes.push_back(list[i]);
if (nodes.size() == 0) printf("0 -1\n");
else {
sort(nodes.begin(), nodes.end(), cmp);
printf("%d %s\n", nodes.size(), nodes[0].address.c_str());
for (int i = 0; i < nodes.size(); ++i) {
if (i < nodes.size() - 1)
printf("%s %d %s\n", nodes[i].address.c_str(), nodes[i].value, nodes[i + 1].address.c_str());
else
printf("%s %d -1\n", nodes[i].address.c_str(), nodes[i].value);
}
}
return 0;
}
1075 PAT Judge
AcWing链接 PAT链接
英语单词
解析
注意点 这里用到了结构体内部定义函数,用法和类和对象差不多 结构体初始化函数格式
struct Student {
Student(){};
Student(string id) : s_id(id) {...}
}
我的答案
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <vector>
#include <unordered_map>
using namespace std;
int n, k, m;
int perfect[6];
struct Student {
string s_id;
int grade[6];
int total, cnt;
Student() {};
Student(string id) : s_id(id) {
for (int i = 0; i < k; ++i) {
grade[i] = -2;
total = cnt = 0;
}
}
void cal() {
for (int i = 0; i < k; ++i) {
if (grade[i] >= 0) {
total += grade[i];
if (grade[i] == perfect[i]) cnt++;
}
}
}
bool is_submit() {
int s = 0;
for (int i = 0; i < k; ++i) {
if (grade[i] >=0) return true;
}
return false;
}
bool operator<(const Student &t) {
if (total != t.total)return total > t.total;
if (cnt != t.cnt)return cnt > t.cnt;
return s_id < t.s_id;
}
};
int main() {
cin >> n >> k >> m;
for (int i = 0; i < k; ++i)cin >> perfect[i];
unordered_map<string, Student> map;
while (m--) {
string s_id;
int q_idx, grade;
cin >> s_id >> q_idx >> grade;
if (map.count(s_id) == 0)map[s_id] = Student(s_id);
map[s_id].grade[q_idx - 1] = max(grade, map[s_id].grade[q_idx - 1]);
}
vector<Student> students;
for (auto &item:map) {
auto stu = item.second;
if (stu.is_submit()) {
stu.cal();
students.push_back(stu);
}
}
sort(students.begin(), students.end());
int rank = 1;
for (int i = 0; i < students.size(); ++i) {
if (!i || students[i].total < students[i - 1].total) rank = i + 1;
cout << rank << " " << students[i].s_id
<< " " << students[i].total;
for (int j = 0; j < k; ++j) {
int g = students[i].grade[j];
if (g == -2)
cout << " -";
else
cout << " " << max(0, g);
}
cout << endl;
}
return 0;
}
1098 Insertion or Heap Sort
AcWing链接 PAT链接
注意点 这边还是要补一下堆排序和插入排序的知识 注意堆排序为了让下标能够正确的表示子孙,需要从1开始存
#include <iostream>
const int N = 101;
using namespace std;
int a[N], b[N];
void down(int u, int size) {
int t = u;
if (u * 2 <= size && b[t] < b[u * 2])t = u * 2;
if (u * 2 + 1 <= size && b[t] < b[u * 2 + 1]) t = u * 2 + 1;
if (t != u) {
swap(b[t], b[u]);
down(t, size);
}
}
int main() {
int n;
cin >> n;
for (int i = 1; i <= n; i++) cin >> a[i];
for (int i = 1; i <= n; i++) cin >> b[i];
int k = 1;
for (int i = 2; i <= n; ++i) {
if (b[i] < b[i - 1]) {
k = i;
break;
}
}
int i;
for (i = k; i <= n; ++i) {
if (b[i] != a[i])break;
}
if (i == n + 1) {
cout << "Insertion Sort" << endl;
for (int j = k; j >= 2; j--) {
if (b[j] < b[j - 1])
swap(b[j], b[j - 1]);
else
break;
}
for (int j = 1; j <= n; ++j) {
if (j==1) cout << b[j];
else cout << " " << b[j];
}
} else {
cout << "Heap Sort" << endl;
int p = n;
while (b[1] <= b[p]) p--;
swap(b[1], b[p]);
down(1, p - 1);
for (int j = 1; j <= n; ++j) {
if (j==1) cout << b[j];
else cout << " " << b[j];
}
}
return 0;
}
|