1012 The Best Rank (25 分)

  • 题意 :给ID和3门成绩,计算其平均分A,输出每位学生最好的排名,A>C>M>E
  • 思路 :如果将所需的若干个元素中使第一个元素为后几个的平均值;容器内二分找值;题目所给ACME决定了搜索顺序,因此决定了容器顺序;二分时,如果是倒序的,就应该找最前面的,这里我们为了省事不写cmp说明是从小到大的,那么我们要找的就是最后一个,最后一个等于x的数的位置,然后如果说r是a.size() - 1,说明排名是第一,那么返回1,也就是说返回值是a.size() - r
  • 语法 :round函数四舍五入,头文件是cmath;map的count用来找是否存在这个左值;int t[4]= {0];数组内统一初始值
#include <iostream>
#include <vector>
#include <unordered_map>
#include <algorithm>
#include <cmath>using namespace std;unordered_map<string, vector<int>> grades;
vector<int> q[4];       // A C M Eint get_grade(vector<int> &a, int x)
{int l = 0, r = a.size() - 1;while (l < r){int mid = (l + r + 1) >> 1;if (a[mid] <= x) l = mid;else r = mid - 1;}return a.size() - r;
}int main()
{int n, m;cin >> n >> m;for (int i = 0; i < n; i ++ ){string id;cin >> id;int t[4] = {0};for (int j = 1; j < 4; j ++ ){cin >> t[j];t[0] += t[j];}t[0] = round(t[0] / 3.0);for (int j = 0; j < 4; j ++ ){grades[id].push_back(t[j]);q[j].push_back(t[j]);}}for (int i = 0; i < 4; i ++ ) sort(q[i].begin(), q[i].end());char names[] = "ACME";while (m -- ){string id;cin >> id;if (grades.count(id) == 0) puts("N/A");else{int res = n + 1;char c;for (int i = 0; i < 4; i ++ ){int rank = get_grade(q[i], grades[id][i]);// int rank = 1 + n - (upper_bound(q[i].begin(), q[i].end(), grades[id][i]) - q[i].begin());      // 在vector要逆序的情况下if (res > rank){res = rank;c = names[i];}}cout << res << ' ' << c << endl;}}
}

1022 Digital Library (30 分)

语法 :

  • 要用getline,转战cin
  • auto 后面不加& 会超时 :Book结构体里的内容很多,不用引用的话,每次会将整个结构体复制一遍,效率较低。
  • 查询出版年限。注意,这个年限可能包含前导 0。因此,我们用字符串存
  • 使用getline前要检查是否需要getchar,cin前则不用
  • getline会把换行符也吃掉,因此一个getline前如果还是getline就不需要getchar;一个getline前如果是cin,则必须getchar
  • stringstream ssin(line); string keyword; while (ssin >> keyword) keywords.insert(keyword);
  • 注意容器定义的位置在循环内还是外,不像例如string类型可以重新被定义
#include <iostream>
#include <vector>
#include <algorithm>
#include <unordered_set>
#include <sstream>
using namespace std;#define pb push_backstruct Book
{string id, name, author;unordered_set<string> keywords;string publisher, year;
};int main()
{int n; cin >> n;vector<Book> books;string id, name, author, keyword, publisher, year;while (n -- ){unordered_set<string> keywords;cin >> id;getchar();getline(cin, name), getline(cin, author);string line;getline(cin, line);stringstream ssin(line);while (ssin >> keyword) keywords.insert(keyword);getline(cin, publisher), getline(cin, year);books.push_back({id, name, author, keywords, publisher, year});}int m; cin >> m;getchar();string query;while (m -- ){getline(cin, query);cout << query << endl;char t = query[0];string info = query.substr(3);vector<string> res;if (t == '1'){for (auto &book : books)if (book.name == info)res.pb(book.id);}else if (t == '2'){for (auto &book : books)if (book.author == info)res.pb(book.id);}else if (t == '3'){for (auto &book : books)if (book.keywords.count(info))res.pb({book.id});}else if (t == '4'){for (auto &book : books)if (book.publisher == info)res.pb(book.id);}else{for (auto &book : books)if (book.year == info)res.pb(book.id);}if (res.empty()) puts("Not Found");else{sort(res.begin(), res.end());for (auto &id : res)cout << id << endl;}}
}

1025 PAT Ranking (25 分)

题意 :

  • 给n个考场排行表,排行表中包含准考证以及成绩
  • 求输出总的排行表,包含 准考证,总排名(含并列),考场号,原考场中排名,

思路 :

  • 13位准考证号 用 字符串 存
  • 先按照各个考场内存每个学生信息,排好序后得到了原考场中的排名,再放入总的学生信息容器中
  • 再对总容器排序,得到总排名
  • 在排名时,按照从大到小(重载)的顺序,如果是最大的或者与上一个不相等(即不并列),直接排名等于i+1,否则,等于上一个的排名
  • 重载时注意,先按成绩降序,然后是准考证升序

语法 :

  • auto& g = grades[i];
  • 结构体赋值的{}方法可以不对结构体所有信息存储,是按顺序的,比如一共有5个信息,我们可以只存前三个
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;#define pb push_backconst int N = 110;struct Student
{string id;int grade;int location_number, local_rank, final_rank;bool operator<(const Student &t) const{if (grade != t.grade) return grade > t.grade;return id < t.id;}
};vector<Student> grades[N];
vector<Student> all;int main()
{int n; cin >> n;for (int i = 1; i <= n; i ++ ){int k; cin >> k;for (int j = 0; j < k; j ++ ){string id;int grade;cin >> id >> grade;grades[i].pb({id, grade, i});}auto &g = grades[i];sort(g.begin(), g.end());for (int j = 0; j < g.size(); j ++ ){if (!j || g[j].grade != g[j - 1].grade)g[j].local_rank = j + 1;elseg[j].local_rank = g[j - 1].local_rank;all.pb(g[j]);}}sort(all.begin(), all.end());for (int i = 0; i < all.size(); i ++ ){if (!i || all[i].grade != all[i - 1].grade)all[i].final_rank = i + 1;elseall[i].final_rank = all[i - 1].final_rank;}cout << all.size() << endl;for (auto &x : all)cout << x.id << ' ' << x.final_rank << ' ' << x.location_number << ' ' << x.local_rank << endl;
}

1028 List Sorting (25 分)

题意 :

  • 给所有学生的id,名字,成绩,要求你按照其中一个排序并输出排行榜
#include <iostream>
#include <algorithm>
using namespace std;const int N = 1e5 + 10;struct Row
{string id, name;int grade;
}rows[N];bool cmp1(Row a, Row b)
{return a.id < b.id;
}bool cmp2(Row a, Row b)
{if (a.name != b.name) return a.name < b.name;return a.id < b.id;
}bool cmp3(Row a, Row b)
{if (a.grade != b.grade) return a.grade < b.grade;return a.id < b.id;
}int main()
{int n, c;scanf("%d%d", &n, &c);char id[10], name[10];int grade;for (int i = 0; i < n; i ++ ){scanf("%s%s%d", id, name, &grade);rows[i] = {id, name, grade};}if (c == 1) sort(rows, rows + n, cmp1);if (c == 2) sort(rows, rows + n, cmp2);if (c == 3) sort(rows, rows + n, cmp3);for (int i = 0; i < n; i ++ )printf("%s %s %d\n", rows[i].id.c_str(), rows[i].name.c_str(), rows[i].grade);
}

1039 Course List for Student (25 分)

题意 :

  • 给出每门课程号参与的学生,询问每个学生参加了哪些课程

语法 :

  • auto& ls = students[name];,等效于操作后者
#include <iostream>
#include <unordered_map>
#include <vector>
#include <algorithm>
using namespace std;#define pb push_backint n, k;
unordered_map<string, vector<int>> students;int main()
{scanf("%d%d", &n, &k);while (k -- ){int id, m;scanf("%d%d", &id, &m);char name[10];while (m -- ){scanf("%s", name);students[name].pb(id);}}char name[10];while (n -- ){scanf("%s", name);auto& ls = students[name];printf("%s %d", name, ls.size());sort(ls.begin(), ls.end());for (auto l : ls) printf(" %d", l);puts("");}
}

1075 PAT Judge (25 分)

题意 :

  • n个用户(1-n),k个问题(1-k),并给出k个问题分别的分值,m个提交记录(用户,问题,所得分值)。
  • 求最后的排名表,总分相同排名并列(但以满分题数降序输出,如果仍相同,以id升序),输出 【排名,用户名,总分,1-k题分别分值】,没有提交输出’-’。同一题多次提交以最高分记录。如果某用户未曾提交或者所有提交记录都不能编译(-1),不输出该用户

语法 :

  • u_id = u_id_s;表示将char数组转换成string
  • map中的count返回值如果是0,说明没有这个左值
  • students[u_id] = Student(u_id);表示创建一个Student结构体,且赋值函数传入一个u_id
  • 注意赋值函数写的方式;Student(){}Student(string _id) : id(_id)
  • id(_id)表示将_id的值赋给id
  • 在结构体中写函数 bool has_submit()
  • 初始化grade[i]为-2,表示未曾提交本题,与提交后得0分和不能编译得-1分作区别
  • 注意排名的写法,一开始rank是1,只有在与上一个的总分不同时(要保证不是第一个元素),rank才会等于i+1,注意不是++
#include <iostream>
#include <unordered_map>
#include <vector>
#include <algorithm>
using namespace std;const int K = 6;int n, k, m;
int p_score[K];struct Student
{string id;int grade[K];int total, cnt;Student(){}Student(string _id) : id(_id){for (int i = 1; i <= k; i ++ ) grade[i] = -2;total = cnt = 0;}bool has_submit(){for (int i = 1; i <= k; i ++ )if (grade[i] >= 0)return true;return false;}void calc(){for (int i = 1; i <= k; i ++ ){total += max(0, grade[i]);if (grade[i] == p_score[i]) cnt ++ ;}}bool operator< (const Student &t) const{if (total != t.total) return total > t.total;if (cnt != t.cnt) return cnt > t.cnt;return id < t.id;}
};int main()
{scanf("%d%d%d", &n, &k, &m);for (int i = 1; i <= k; i ++ ) scanf("%d", &p_score[i]);unordered_map<string, Student> students;string u_id;char u_id_s[10];int p_id, score;while (m -- ){scanf("%s%d%d", u_id_s, &p_id, &score);u_id = u_id_s;if (students.count(u_id) == 0) students[u_id] = Student(u_id);students[u_id].grade[p_id] = max(students[u_id].grade[p_id], score);}vector<Student> res;for (auto &item : students){auto &s = item.second;if (s.has_submit()){s.calc();res.push_back(s);}}sort(res.begin(), res.end());for (int i = 0, rank = 1; i < res.size(); i ++ ){if (i && res[i].total != res[i - 1].total) rank = i + 1;printf("%d %s %d", rank, res[i].id.c_str(), res[i].total);for (int j = 1; j <= k; j ++ ){printf(" ");if (res[i].grade[j] != -2) printf("%d", max(0, res[i].grade[j]));else printf("-");}puts("");}
}

1089 Insert or Merge (25 分)

题意 :

  • 插入排序迭代,每次将一个插入元素插入到排好序的输出序列中,每次迭代插入排序都会从输入数据中移除一个元素,并在已排好序的序列中找到它所属的位置,然后将其插入。直到没有输入元素剩余为止。
  • 归并排序的工作方式如下:将未排序的序列划分为 N 个子序列,每个子序列包含 1 个元素(将 1 个元素的序列视为已排序)。然后重复合并两个相邻的子序列以产生新的排序子序列,直到仅剩 1 个子序列为止。
  • 现在,给定初始序列,以及经过某种排序方法多次迭代后的序列,请你判断我们使用的哪一种排序方法。
  • 假定排序的目标序列总是递增的。

思路 :

  • 归并排序,一开始是每个数字自己一组,然后第一轮迭代是两两分组,然后先把组内排好序,第二轮是四四分组,然后再下一轮就是八八分组;归并排序是O(logN)O(logN)O(logN)的
  • 如果判断出不是插入排序,说明是归并排序
  • 那么怎么样才能弄出归并排序的下一轮呢?不如还是从a数组开始一轮轮模拟下去,如果当前等于b数组了,再迭代一轮就是答案;注意循环内是先判断当前是否相等,然后再迭代一轮,如果刚才判断相等,现在这个就输出
  • sort(a + i, a + min(n + 1, i + len));,不然会段错误
  • 注意这里判断是否是插入排序时,最好是while (p <= n && b[p] >= b[p - 1]) p ++ ;的形式,而不是判断与下一个,且是大于等于,我们的目的是找到第一个小于前一个数的,不然可能会导致段错误
#include <iostream>
#include <algorithm>
using namespace std;const int N = 110;int n;
int a[N], b[N];bool check()
{for (int i = 1; i <= n; i ++ )if (a[i] != b[i])return false;return true;
}int main()
{scanf("%d", &n);for (int i = 1; i <= n && scanf("%d", &a[i]); i ++ );for (int i = 1; i <= n && scanf("%d", &b[i]); i ++ );int p = 2;while (p <= n && b[p] >= b[p - 1]) p ++ ;int k = p;while (p <= n && b[p] == a[p]) p ++ ;if (p == n + 1){puts("Insertion Sort");while (k > 1 && b[k] < b[k - 1]) swap(b[k], b[k - 1]), k -- ;printf("%d", b[1]);for (int i = 2; i <= n; i ++ ) printf(" %d", b[i]);}else{puts("Merge Sort");bool match;k = 1;while (true){match = check();int len = 1 << k;for (int i = 1; i <= n; i += len){sort(a + i, a + min(n + 1, i + len));}if (match) break;k ++ ;}printf("%d", a[1]);for (int i = 2; i <= n; i ++ ) printf(" %d", a[i]);}
}

1098 Insertion or Heap Sort (25 分)

题意 :

  • 插入排序迭代,每次将一个插入元素插入到排好序的输出序列中,每次迭代插入排序都会从输入数据中移除一个元素,并在已排好序的序列中找到它所属的位置,然后将其插入。直到没有输入元素剩余为止。
  • 堆排序将其输入分为已排序和未排序两个区域,并通过提取未排序区域中的最大元素并将其移至已排序的区域来迭代地缩小未排序的区域。它通过使用堆数据结构而非线性时间搜索来找到最大值。
  • 现在,给定初始序列,以及经过某种排序方法多次迭代后的序列,请你判断我们使用的哪一种排序方法。运用此方法再进行一次迭代,并在第二行输出本次迭代后的序列。假定排序的目标序列总是递增的。

思路 :

  • 堆排序是先把整个数组建成一个大根堆,先把最大值放最后,然后删掉,然后把次大值放最后,然后删掉, 所以堆排序实际上从后往前排,后面那几个已经弹出堆的数,一定是最大的几个而且排好序的,而前半部分是不一定有序的,前半部分就是这个堆
  • 而插入排序 找规律可以发现前半部分是有序的,后半部分是保持原序的
  • 由于插入排序比堆排序好判断,所以先判断它是不是插入排序。先找到无序的第一个,然后如果后半部分原序,说明就是插入排序。
  • 如果确认不是插入排序,那么就是堆排序,先找到分界线,后半部分是最大的k个数,前半部分是一个堆,堆中应该是第一个位置,第一个位置就是前半部分中的最大值;如果一个元素大于堆顶,一定在后半部分,如果等于堆顶,可以在后面;所以我们找大于等于堆顶的元素
  • 堆排序中,大根堆小根堆都能实现从小到大排序,如果用小根堆,那每次把最小值放到序列开头;如果用大根堆,那就每次把最大值放到序列结尾。
  • 注意down的时候堆的大小是p - 1,不是n,也不是p
  • 这里的堆排序认为与堆内没有与堆顶元素等值的元素,在堆外
#include <iostream>
using namespace std;const int N = 110;int n;
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()
{scanf("%d", &n);for (int i = 1; i <= n && scanf("%d", &a[i]); i ++ );for (int i = 1; i <= n && scanf("%d", &b[i]); i ++ );int p = 2;while (p <= n && b[p] >= b[p - 1]) p ++ ;int k = p;while (p <= n && b[p] == a[p]) p ++ ;if (p == n + 1){puts("Insertion Sort");while (k > 1 && b[k] < b[k - 1]) swap(b[k], b[k - 1]), k -- ;}else{puts("Heap Sort");p = n;while (p > 1 && b[p] >= b[1]) p -- ;swap(b[1], b[p]);down(1, p - 1);}printf("%d", b[1]);for (int i = 2; i <= n; i ++ ) printf(" %d", b[i]);
}

PAT甲级题目翻译+答案 AcWing(排序)相关推荐

  1. PAT甲级题目翻译+答案 AcWing(模拟)

    1008 Elevator (20 分) 思路 :last可能等于cur,而无论是否相等,res都是+5的 #include <iostream>using namespace std;i ...

  2. PAT甲级题目翻译+答案 AcWing(数学)

    1059 Prime Factors (25 分) 题意 : 给一正整数,要求分解质因数 思路 : 使用is_first,来完成除了第一个质因数前都有*的效果 如果n=1,要特判 最后如果n>1 ...

  3. PAT甲级题目翻译+答案 AcWing(字符串处理)

    1001 A+B Format (20 分) 题意 :将整数转换成标准格式 思路 :从后往前遍历字符串进行模拟,每三个数字加一个逗号,但不能是在最前面加逗号,也不能是加在负号后面 #include & ...

  4. PAT甲级题目翻译+答案 AcWing(链表)

    1032 Sharing (25 分) 题意 : suffix后缀:prefix前缀 每个结点存一个字母,一共存两个单词 分别给两个单词的第一个字母的地址以及总共的结点数 给出所有结点的地址数值和下一 ...

  5. PAT甲级题目翻译+答案 AcWing(基础算法与数据结构)

    1029 Median (25 分) 题意 : median中位数 给两个升序的序列,要求它们两个合并后的中位数 思路 : 双指针 语法 : long int #include <iostrea ...

  6. PAT甲级题目翻译+答案 AcWing(动态规划)

    1007 Maximum Subsequence Sum (25 分) 题意 :注意最后输出的不是索引而是在那个索引的数 思路 :f为当前的假设开始指针,每一次累加到sum,如果sum大于res,就更 ...

  7. PAT甲级题目翻译+答案 AcWing(图论)

    1003 Emergency (25 分) 题意 :求无向图中最短路的数量,以及在最短路情况下,点权之和最大是多少 思路 :dijkstra的扩展一般在第三步"用t更新其它点":s ...

  8. PAT甲级题目翻译+答案 AcWing(进位制)

    1010 Radix (25 分) 题意 :radix进制 题意 :给两个数和其中一个数的进制,问另一个数能否在某一进制下与这数相等 思路 :如果tag等于2就交换,最后还是只需要处理tag为1这种情 ...

  9. PAT甲级题目翻译+答案 AcWing(高精度)

    1002 A+B for Polynomials (25 分) 题意 :给两个多项式,输出两个多项式相加结果的系数和次数 思路 :用double数组记录多项式,正好数组下标是整数,系数是double ...

最新文章

  1. 如何用JavaScript操作form表单组件?
  2. (无奈之举)2011年01月26号日志
  3. 皮一皮:中国好邻居!
  4. 小朋友学C++(1)
  5. mysql 索引_MySQL之索引
  6. (37)FPGA三种基本逻辑门(非门)
  7. Zookeeper-02-概念
  8. Facebook将偷来的3D对象数据库用于其AI项目:被诉讼
  9. windows搭建yolo环境
  10. Vmware虚拟机全屏
  11. C语言ASCII码转换
  12. oralce 表字段扩容(修改表字段长度)
  13. Mathematica仿真竞争性Lotka-Volterra方程(3种群)
  14. 盘点那些年BAT字节跳动等互联网公司的程序员、工程师一夜暴富的都市传说
  15. 变量命名神器Codelf
  16. 2020 dns排名_《2020年全球DNS威胁报告》:DNS攻击平均损失高达92万美元
  17. html hr代码的效果,HTML hr是什么意思
  18. python网络安全论文题目_自动化毕业论文题目119个免费参考
  19. MyBatis逆向工程去除表名前缀
  20. 2021泰安市地区高考成绩排名查询,泰安高中学校实力排名,2021年泰安所有的高中分数线排名...

热门文章

  1. LSMW、BDC、CATT 区别
  2. 导出SAP表结构到EXCEl
  3. 云计算被视为继计算机,8+第八章+计算机网络技术分析.ppt
  4. 俄罗斯计算机科学留学,中南大学计算机科学与技术、俄罗斯硕士留学有没有寒暑假班?...
  5. oracle 数字不用,oracle – Plsql将数字(货币)拼写为意大利货币而不用硬编码的翻译编号...
  6. java map类型转换_Java string类型转换成map代码实例
  7. fastbin attack攻击中关于 malloc__hook
  8. fullbnt matlab,FullBNT学习笔记之一(matlab)
  9. 提升win双屏体验_海信双屏A6L评测,在自由阅读中植入护眼水墨屏
  10. Python itertools 操作迭代对象