├── .gitignore ├── CCF CSP ├── 201312-1. 出现次数最多的数.md ├── 201312-2. ISBN号码.md ├── 201312-3. 最大的矩形.cpp ├── 201312-4. 有趣的数.cpp ├── 201403-1. 相反数.md ├── 201403-2. 窗口.cpp ├── 201403-3. 命令行选项.cpp ├── 201403-4. 无线网络.cpp ├── 201409-1. 相邻数对.md ├── 201409-2. 画图.cpp ├── 201409-3. 字符串匹配.cpp ├── 201409-4. 最优配餐.cpp ├── 201412-1. 门禁系统.cpp ├── 201412-2. Z字形扫描.cpp ├── 201412-3. 集合竞价.cpp ├── 201412-4. 最优灌溉.cpp ├── 201503-1. 图像旋转.cpp ├── 201503-2. 数字排序.md ├── 201503-3. 节日.cpp ├── 201503-4. 网络延时(动态规划).cpp ├── 201503-4. 网络延时(深度优先遍历).cpp ├── 201509-1. 数列分段.md ├── 201509-2. 日期计算.cpp ├── 201509-3. 模板生成系统.cpp ├── 201509-4. 高速公路.cpp ├── 201512-1. 数位之和.md ├── 201512-2. 消除类游戏.cpp ├── 201512-3. 画图.cpp ├── 201512-4. 送货.cpp ├── 201604-1. 折点计数.md ├── 201604-2. 俄罗斯方块.cpp ├── 201604-3. 路径解析.cpp ├── 201604-4. 游戏.cpp ├── 201609-1. 最大波动.md ├── 201609-2. 火车购票.cpp ├── 201609-3. 炉石传说.cpp ├── 201609-4. 交通规划.cpp ├── 201612-1. 中间数.md ├── 201612-2. 工资计算.cpp ├── 201612-3. 权限查询.cpp ├── 201703-1. 分蛋糕.md ├── 201703-2. 学生排队.cpp ├── 201703-3. Markdown.cpp ├── 201703-4. 地铁修建.cpp ├── 201709-1. 打酱油.md ├── 201709-2. 公共钥匙盒.cpp ├── 201709-3. JSON查询.cpp ├── 201709-4. 通信网络.cpp ├── 201712-1. 最小差值.md ├── 201712-2. 游戏.cpp ├── 201712-3. Crontab.cpp ├── 201803-1. 跳一跳.cpp ├── 201803-2. 碰撞的小球.cpp ├── 201803-3. URL映射.cpp ├── 201809-1. 卖菜.cpp ├── 201809-2. 买菜.cpp ├── 201809-3. 元素选择器.cpp ├── 201812-1. 小明上学.cpp ├── 201812-2. 小明放学.cpp ├── 201812-3. CIDR合并.cpp ├── 201812-4. 数据中心.cpp ├── 201903-1. 小中大.md ├── 201903-2. 二十四点.cpp ├── 201903-3. 损坏的RAID5.md ├── 201903-4. 消息传递接口.md ├── 201909-1. 小明种苹果.cpp ├── 201909-2. 小明种苹果(续).cpp ├── 201909-3. 字符画.md ├── 201909-4. 推荐系统.md ├── 201912-1. 报数.md ├── 201912-2. 回收站选址.cpp ├── 201912-3. 化学方程式.md ├── 201912-4. 区块链.md ├── 202006-1. 线性分类器.cpp ├── 202006-1. 线性分类器.md ├── 202006-2. 稀疏向量.cpp ├── 202006-2. 稀疏向量.md ├── 202009-1. 称检测点查询.md ├── 202009-2. 风险人群筛查 copy.md ├── 202009-3. 点亮数字人生.md ├── 202012-1. 期末预测之安全指数.md ├── 202012-2. 期末预测之最佳阈值.md ├── 202012-3. 带配额的文件系统.md ├── 202012-4. 食材运输.md ├── 202012-5. 星际旅行.md ├── 202104-1. 灰度直方图.md ├── 202104-2. 领域均值.md └── 202104-4. 校门外的树.md ├── PAT ├── Advanced Level │ ├── 1001. A+B Format.md │ ├── 1002. A+B for Polynomials.cpp │ ├── 1003. Emergency.md │ ├── 1004. Counting Leaves.cpp │ ├── 1005. Spell It Right.md │ ├── 1006. Sign In and Sign Out.cpp │ ├── 1007. Maximum Subsequence Sum.md │ ├── 1008. Elevator.cpp │ ├── 1009. Product of Polynomials.md │ ├── 1010. Radix.cpp │ ├── 1011. World Cup Betting.md │ ├── 1012. The Best Rank.md │ ├── 1013. Battle Over Cities.cpp │ ├── 1014. Waiting in Line.cpp │ ├── 1015. Reversible Primes.md │ ├── 1016. Phone Bills.cpp │ ├── 1017. Queueing at Bank.cpp │ ├── 1018. Public Bike Management.md │ ├── 1019. General Palindromic Number.cpp │ ├── 1020. Tree Traversals.cpp │ ├── 1021. Deepest Root.md │ ├── 1022. Digital Library.md │ ├── 1023. Have Fun with Numbers.cpp │ ├── 1024. Palindromic Number.md │ ├── 1025. PAT Ranking.cpp │ ├── 1026. Table Tennis.cpp │ ├── 1027. Colors in Mars.cpp │ ├── 1028. List Sorting.cpp │ ├── 1029. Median.cpp │ ├── 1030. Travel Plan.md │ ├── 1031. Hello World for U.cpp │ ├── 1032. Sharing.cpp │ ├── 1033. To Fill or Not to Fill.cpp │ ├── 1034. Head of a Gang.md │ ├── 1035. Password.md │ ├── 1036. Boys vs Girls.md │ ├── 1037. Magic Coupon.md │ ├── 1038. Recover the Smallest Number.cpp │ ├── 1039. Course List for Student.md │ ├── 1040. Longest Symmetric String.md │ ├── 1041. Be Unique.md │ ├── 1042. Shuffling Machine.cpp │ ├── 1043. Is It a Binary Search Tree.cpp │ ├── 1044. Shopping in Mars.cpp │ ├── 1045. Favorite Color Stripe.md │ ├── 1046. Shortest Distance.cpp │ ├── 1047. Student List for Course.cpp │ ├── 1048. Find Coins.md │ ├── 1049. Counting Ones.md │ ├── 1050. String Subtraction.md │ ├── 1051. Pop Sequence.cpp │ ├── 1052. Linked List Sorting.md │ ├── 1053. Path of Equal Weight.md │ ├── 1054. The Dominant Color.cpp │ ├── 1055. The World's Richest.md │ ├── 1056. Mice and Rice.md │ ├── 1057. Stack.md │ ├── 1058. A+B in Hogwarts.md │ ├── 1059. Prime Factors.cpp │ ├── 1060. Are They Equal.cpp │ ├── 1061. Dating.cpp │ ├── 1062. Talent and Virtue.cpp │ ├── 1063. Set Similarity.md │ ├── 1064. Complete Binary Search Tree.cpp │ ├── 1065. A+B and C.md │ ├── 1066. Root of AVL Tree.md │ ├── 1067. Sort with Swap(0, i).md │ ├── 1068. Find More Coins.md │ ├── 1069. The Black Hole of Numbers.cpp │ ├── 1070. Mooncake.cpp │ ├── 1071. Speech Patterns.md │ ├── 1072. Gas Station.cpp │ ├── 1073. Scientific Notation.cpp │ ├── 1074. Reversing Linked List.cpp │ ├── 1075. PAT Judge.md │ ├── 1076. Forwards on Weibo.md │ ├── 1077. Kuchiguse.cpp │ ├── 1078. Hashing.md │ ├── 1079. Total Sales of Supply Chain.cpp │ ├── 1080. Graduate Admission.md │ ├── 1081. Rational Sum.md │ ├── 1082. Read Number in Chinese.md │ ├── 1083. List Grades.md │ ├── 1084. Broken Keyboard.cpp │ ├── 1085. Perfect Sequence.cpp │ ├── 1086. Tree Traversals Again.cpp │ ├── 1087. All Roads Lead to Rome.md │ ├── 1088. Rational Arithmetic.cpp │ ├── 1089. Insert or Merge.cpp │ ├── 1090. Highest Price in Supply Chain.cpp │ ├── 1091. Acute Stroke.md │ ├── 1092. To Buy or Not to Buy.cpp │ ├── 1093. Count PAT's.md │ ├── 1094. The Largest Generation.md │ ├── 1095. Cars on Campus.cpp │ ├── 1096. Consecutive Factors.md │ ├── 1097. Deduplication on a Linked List.md │ ├── 1098. Insertion or Heap Sort.cpp │ ├── 1099. Build A Binary Search Tree.cpp │ ├── 1100. Mars Numbers.cpp │ ├── 1101. Quick Sort.md │ ├── 1102. Invert a Binary Tree.cpp │ ├── 1103. Integer Factorization.md │ ├── 1104. Sum of Number Segments.md │ ├── 1105. Spiral Matrix.cpp │ ├── 1106. Lowest Price in Supply Chain.md │ ├── 1107. Social Clusters.cpp │ ├── 1108. Finding Average.cpp │ ├── 1109. Group Photo.md │ ├── 1110. Complete Binary Tree.cpp │ ├── 1111. Online Map.md │ ├── 1112. Stucked Keyboard.cpp │ ├── 1113. Integer Set Partition.md │ ├── 1114. Family Property.md │ ├── 1115. Counting Nodes in a BST.cpp │ ├── 1116. Come on! Let's C.cpp │ ├── 1117. Eddington Number.md │ ├── 1118. Birds in Forest.cpp │ ├── 1119. Pre- and Post-order Traversals.md │ ├── 1120. Friend Numbers.cpp │ ├── 1121. Damn Single.cpp │ ├── 1122. Hamiltonian Cycle.cpp │ ├── 1123. Is It a Complete AVL Tree.md │ ├── 1124. Raffle for Weibo Followers.cpp │ ├── 1125. Chain the Ropes.md │ ├── 1126. Eulerian Path.cpp │ ├── 1127. ZigZagging on a Tree.md │ ├── 1128. N Queens Puzzle.cpp │ ├── 1129. Recommendation System.md │ ├── 1130. Infix Expression.cpp │ ├── 1131. Subway Map.md │ ├── 1132. Cut Integer.cpp │ ├── 1133. Splitting A Linked List.cpp │ ├── 1134. Vertex Cover.cpp │ ├── 1135. Is It A Red-Black Tree.md │ ├── 1136. A Delayed Palindrome.cpp │ ├── 1137. Final Grading.cpp │ ├── 1138. Postorder Traversal.md │ ├── 1139. First Contact.md │ ├── 1140. Look-and-say Sequence.cpp │ ├── 1141. PAT Ranking of Institutions.cpp │ ├── 1142. Maximal Clique.md │ ├── 1143. Lowest Common Ancestor.cpp │ ├── 1144. The Missing Number.md │ ├── 1145. Hashing - Average Search Time.md │ ├── 1146. Topological Order.cpp │ ├── 1147. Heaps.cpp │ ├── 1148. Werewolf - Simple Version.cpp │ ├── 1149. Dangerous Goods Packaging.cpp │ ├── 1150. Travelling Salesman Problem.md │ ├── 1151. LCA in a Binary Tree.cpp │ ├── 1152. Google Recruitment.cpp │ ├── 1153. Decode Registration Card of PAT.md │ ├── 1154. Vertex Coloring.cpp │ └── 1155. Heap Paths.cpp └── Basic Level │ ├── 1001. 害死人不偿命的(3n+1)猜想.cpp │ ├── 1002. 写出这个数.cpp │ ├── 1003. 我要通过!.cpp │ ├── 1004. 成绩排名.cpp │ ├── 1005. 继续(3n+1)猜想.cpp │ ├── 1006. 换个格式输出整数.cpp │ ├── 1007. 素数对猜想.cpp │ ├── 1008. 数组元素循环右移问题.md │ ├── 1009. 说反话.cpp │ ├── 1010. 一元多项式求导.cpp │ ├── 1011. A+B和C.cpp │ ├── 1012. 数字分类.cpp │ ├── 1013. 数素数.md │ ├── 1014. 福尔摩斯的约会.cpp │ ├── 1015. 德才论.cpp │ ├── 1016. 部分A+B.md │ ├── 1017. A除以B.cpp │ ├── 1018. 锤子剪刀布.md │ ├── 1019. 数字黑洞.cpp │ ├── 1020. 月饼.cpp │ ├── 1021. 个位数统计.cpp │ ├── 1022. D进制的A+B.cpp │ ├── 1023. 组个最小数.cpp │ ├── 1024. 科学计数法.cpp │ ├── 1025. 反转链表.cpp │ ├── 1026. 程序运行时间.cpp │ ├── 1027. 打印沙漏.cpp │ ├── 1028. 人口普查.cpp │ ├── 1029. 旧键盘.cpp │ ├── 1030. 完美数列.cpp │ ├── 1031. 查验身份证.cpp │ ├── 1032. 挖掘机技术哪家强.cpp │ ├── 1033. 旧键盘打字.cpp │ ├── 1034. 有理数四则运算.cpp │ ├── 1035. 插入与归并.cpp │ ├── 1036. 跟奥巴马一起编程.md │ ├── 1037. 在霍格沃茨找零钱.cpp │ ├── 1038. 统计同成绩学生.cpp │ ├── 1039. 到底买不买.cpp │ ├── 1040. 有几个PAT.md │ ├── 1041. 考试座位号.md │ ├── 1042. 字符统计.md │ ├── 1043. 输出PATest.cpp │ ├── 1044. 火星数字.cpp │ ├── 1045. 快速排序.md │ ├── 1046. 划拳.md │ ├── 1047. 编程团体赛.md │ ├── 1048. 数字加密.md │ ├── 1049. 数列的片段和.md │ ├── 1050. 螺旋矩阵.cpp │ ├── 1051. 复数乘法.cpp │ ├── 1052. 卖个萌.cpp │ ├── 1053. 住房空置率.md │ ├── 1054. 求平均值.cpp │ ├── 1055. 集体照.md │ ├── 1056. 组合数的和.md │ ├── 1057. 数零壹.cpp │ ├── 1058. 选择题.cpp │ ├── 1059. C语言竞赛.cpp │ ├── 1060. 爱丁顿数.md │ ├── 1061. 判断题.md │ ├── 1062. 最简分数.md │ ├── 1063. 计算谱半径.cpp │ ├── 1064. 朋友数.cpp │ ├── 1065. 单身狗.cpp │ ├── 1066. 图像过滤.cpp │ ├── 1067. 试密码.cpp │ ├── 1068. 万绿丛中一点红.cpp │ ├── 1069. 微博转发抽奖.cpp │ ├── 1070. 结绳.md │ ├── 1071. 小赌怡情.cpp │ ├── 1072. 开学寄语.cpp │ ├── 1073. 多选题常见计分法.cpp │ ├── 1074. 宇宙无敌加法器.md │ ├── 1075. 链表元素分类.cpp │ ├── 1076. Wifi密码.md │ ├── 1077. 互评成绩计算.cpp │ ├── 1078. 字符串压缩与解压.cpp │ ├── 1079. 延迟的回文数.cpp │ ├── 1080. MOOC期终成绩.cpp │ ├── 1081. 检查密码.md │ ├── 1082. 射击比赛.md │ ├── 1083. 是否存在相等的差.cpp │ ├── 1084. 外观数列.cpp │ ├── 1085. PAT单位排行.cpp │ ├── 1086. 就不告诉你.md │ ├── 1087. 有多少不同的值.cpp │ ├── 1088. 三人行.md │ ├── 1089. 狼人杀-简单版.cpp │ ├── 1090. 危险品装箱.cpp │ ├── 1091. N-自守数.md │ ├── 1092. 最好吃的月饼.md │ ├── 1093. 字符串A+B.md │ ├── 1094. 谷歌的招聘.cpp │ └── 1095. 解码PAT准考证.md ├── README.md ├── 书籍勘误.md └── 题解目录 ├── CCF CSP题解目录.md ├── PAT乙级题解目录.md └── PAT甲级题解目录.md /.gitignore: -------------------------------------------------------------------------------- 1 | .gitignore 2 | /.vscode 3 | /.history 4 | /test 5 | # Created by https://www.toptal.com/developers/gitignore/api/c++ 6 | # Edit at https://www.toptal.com/developers/gitignore?templates=c++ 7 | 8 | ### C++ ### 9 | # Prerequisites 10 | *.d 11 | 12 | # Compiled Object files 13 | *.slo 14 | *.lo 15 | *.o 16 | *.obj 17 | 18 | # Precompiled Headers 19 | *.gch 20 | *.pch 21 | 22 | # Linker files 23 | *.ilk 24 | 25 | # Debugger Files 26 | *.pdb 27 | 28 | # Compiled Dynamic libraries 29 | *.so 30 | *.dylib 31 | *.dll 32 | 33 | # Fortran module files 34 | *.mod 35 | *.smod 36 | 37 | # Compiled Static libraries 38 | *.lai 39 | *.la 40 | *.a 41 | *.lib 42 | 43 | # Executables 44 | *.exe 45 | *.out 46 | *.app 47 | 48 | # End of https://www.toptal.com/developers/gitignore/api/c++ 49 | -------------------------------------------------------------------------------- /CCF CSP/201312-1. 出现次数最多的数.md: -------------------------------------------------------------------------------- 1 | # 【CCF CSP-20131201】出现次数最多的数 2 | 3 | ## 题意概述 4 | 5 | 给定 n 个正整数,找出它们中出现次数最多的数。如果这样的数有多个,请输出其中最小的一个。 6 | 7 | ## 输入输出格式 8 | 9 | 输入的第一行只有一个正整数 n,表示数字的个数。输入的第二行有 n 个整数$a_1,a_2,\cdots,a_n$。相邻的数用空格分隔。 10 | 11 | 输出这 n 个次数中出现次数最多的数。如果这样的数有多个,输出其中最小的一个。 12 | 13 | ## 数据规模 14 | 15 | $$1\le n\le1000,1\le a_i\le10000$$ 16 | 17 | ## 算法设计 18 | 19 | 可以使用 map 来存储数字及其对应的出现次数,然后使用 max_element 函数统计出现次数最多的数字即可。 20 | 21 | ## C++代码 22 | 23 | ```cpp 24 | #include 25 | using namespace std; 26 | using gg = long long; 27 | int main() { 28 | ios::sync_with_stdio(false); 29 | cin.tie(0); 30 | gg ni, ai; 31 | cin >> ni; 32 | map m; 33 | while (ni--) { 34 | cin >> ai; 35 | ++m[ai]; 36 | } 37 | cout << max_element(m.begin(), m.end(), 38 | [](const pair& p1, const pair& p2) { 39 | return p1.second < p2.second; 40 | }) ->first; 41 | return 0; 42 | } 43 | ``` 44 | -------------------------------------------------------------------------------- /CCF CSP/201312-2. ISBN号码.md: -------------------------------------------------------------------------------- 1 | # 【CCF CSP-20131202】ISBN 号码 2 | 3 | ## 题意概述 4 | 5 | 每一本正式出版的图书都有一个 ISBN 号码与之对应,ISBN 码包括 9 位数字、1 位识别码和 3 位分隔符,其规定格式如`x-xxx-xxxxx-x`,其中符号`-`是分隔符(键盘上的减号),最后一位是识别码。识别码的计算方法如下: 6 | 7 | 首位数字乘以 1 加上次位数字乘以 2……以此类推,用所得的结果 mod 11,所得的余数即为识别码,如果余数为 10,则识别码为大写字母 X。例如 ISBN 号码 0-670-82162-4 中的识别码 4 是这样得到的:对 067082162 这 9 个数字,从左至右,分别乘以 1,2,…,9,再求和,即 0×1+6×2+……+2×9=158,然后取 158 mod 11 的结果 4 作为识别码。 8 | 9 | 编写程序判断输入的 ISBN 号码中识别码是否正确,如果正确,则仅输出`Right`;如果错误,则输出是正确的 ISBN 号码。 10 | 11 | ## 输入输出格式 12 | 13 | 输入只有一行,是一个字符序列,表示一本书的 ISBN 号码(保证输入符合 ISBN 号码的格式要求)。 14 | 15 | 输出一行,假如输入的 ISBN 号码的识别码正确,那么输出`Right`,否则,按照规定的格式,输出正确的 ISBN 号码(包括分隔符`-`)。 16 | 17 | ## C++代码 18 | 19 | ```cpp 20 | #include 21 | using namespace std; 22 | using gg = long long; 23 | int main() { 24 | ios::sync_with_stdio(false); 25 | cin.tie(0); 26 | string si; 27 | cin >> si; 28 | gg num = 1, s = 0; 29 | for (gg i = 0; i < si.size() - 1; ++i) { 30 | if (isdigit(si[i])) { 31 | s += (si[i] - '0') * (num++); 32 | } 33 | } 34 | char c = s % 11 == 10 ? 'X' : s % 11 + '0'; 35 | if (si.back() == c) { 36 | cout << "Right\n"; 37 | } else { 38 | si.back() = c; 39 | cout << si; 40 | } 41 | return 0; 42 | } 43 | ``` 44 | -------------------------------------------------------------------------------- /CCF CSP/201312-3. 最大的矩形.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | gg ni, ans = 0; 8 | cin >> ni; 9 | vector v(ni); 10 | for (gg& i : v) { 11 | cin >> i; 12 | } 13 | for (gg i = 0; i < ni; ++i) { 14 | gg m = v[i]; //最小高度 15 | for (gg j = i; j < ni; ++j) { 16 | m = min(m, v[j]); 17 | ans = max(ans, (j - i + 1) * m); 18 | } 19 | } 20 | cout << ans; 21 | return 0; 22 | } -------------------------------------------------------------------------------- /CCF CSP/201403-1. 相反数.md: -------------------------------------------------------------------------------- 1 | # 【CCF CSP-20140301】相反数 2 | 3 | ## 题意概述 4 | 5 | 有 N 个非零且各不相同的整数。请你编一个程序求出它们中有多少对相反数。 6 | 7 | ## 输入输出格式 8 | 9 | 输入第一行包含一个正整数 N。第二行为 N 个用单个空格隔开的非零整数,每个数的绝对值不超过 1000,保证这些整数各不相同。 10 | 11 | 输出一个整数,即这 N 个数中包含多少对相反数。 12 | 13 | ## 数据规模 14 | 15 | $$1\le N \le500$$ 16 | 17 | ## 算法设计 18 | 19 | 可以暴力枚举每一对整数对,检验它们的和是否为 0 即可。为此可以先将这 n 个整数存储在一个数组中,然后枚举两个变量:i 枚举的区间为$\left[0,n\right)$,j 枚举的区间为$\left[i+1,n\right)$,j 之所以从 i+1 开始枚举,是为了防止重复枚举同一对整数对。最后统计和为 0 的整数对的个数即可。 20 | 21 | ## C++代码 22 | 23 | ```cpp 24 | #include 25 | using namespace std; 26 | using gg = long long; 27 | int main() { 28 | ios::sync_with_stdio(false); 29 | cin.tie(0); 30 | gg ni; 31 | cin >> ni; 32 | vector ai(ni); 33 | for (gg& i : ai) { 34 | cin >> i; 35 | } 36 | gg ans = 0; 37 | for (gg i = 0; i < ni; ++i) { 38 | for (gg j = i + 1; j < ni; ++j) { 39 | if (ai[i] + ai[j] == 0) { 40 | ++ans; 41 | } 42 | } 43 | } 44 | cout << ans; 45 | return 0; 46 | } 47 | ``` 48 | -------------------------------------------------------------------------------- /CCF CSP/201403-2. 窗口.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | struct Window { 5 | gg num, x1, y1, x2, y2; 6 | }; 7 | int main() { 8 | ios::sync_with_stdio(false); 9 | cin.tie(0); 10 | gg ni, mi; 11 | cin >> ni >> mi; 12 | list windows(ni); 13 | gg num = 1; 14 | //输入是按从最下层到最顶层的顺序输入的,要用反向迭代器读取 15 | for (auto i = windows.rbegin(); i != windows.rend(); ++i) { 16 | cin >> i->x1 >> i->y1 >> i->x2 >> i->y2; 17 | i->num = num++; 18 | } 19 | gg x, y; 20 | while (mi--) { 21 | cin >> x >> y; 22 | auto i = //查找第一个包含点击点的窗口 23 | find_if(windows.begin(), windows.end(), [x, y](const Window& w) { 24 | return w.x1 <= x and w.x2 >= x and w.y1 <= y and w.y2 >= y; 25 | }); 26 | if (i == windows.end()) { //没有这样的窗口 27 | cout << "IGNORED\n"; 28 | continue; 29 | } 30 | cout << i->num << "\n"; 31 | windows.push_front(*i); //插入到链表头部 32 | windows.erase(i); 33 | } 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /CCF CSP/201403-3. 命令行选项.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | string s, t; 8 | cin >> s; 9 | vector type(128); //值为0表示该字母不是命令行选项 10 | for (gg i = 0; i < s.size(); ++i) { 11 | type[s[i]] = 1; //不带参数选项 12 | if (i + 1 < s.size() and s[i + 1] == ':') { 13 | type[s[i]] = 2; //带参数选项 14 | } 15 | } 16 | gg ni; 17 | cin >> ni; 18 | cin.get(); //吸收换行符 19 | for (gg ii = 1; ii <= ni; ++ii) { 20 | getline(cin, s); 21 | map ans; 22 | stringstream ss(s); 23 | ss >> s; //命令行工具名 24 | while (ss >> s) { 25 | if (s.size() == 2 and s[0] == '-' and type[s[1]] == 1) { 26 | ans[s[1]] = ""; //不带参数选项,map中对应值为空字符串 27 | } else if (s.size() == 2 and s[0] == '-' and type[s[1]] == 2 and 28 | ss >> t) { 29 | ans[s[1]] = t; //带参数选项,map中对应值为t 30 | } else { //错误选项,跳出循环 31 | break; 32 | } 33 | } 34 | cout << "Case " << ii << ":"; 35 | for (auto& i : ans) { 36 | cout << " -" << i.first; 37 | if (not i.second.empty()) { 38 | cout << " " << i.second; 39 | } 40 | } 41 | cout << "\n"; 42 | } 43 | return 0; 44 | } -------------------------------------------------------------------------------- /CCF CSP/201403-4. 无线网络.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | using coord = array; //用维度为2的一维数组存储坐标 5 | gg n, m, k, r; 6 | vector routers(205); //存储路由器的坐标 7 | vector ans; //存储最终结果 8 | inline bool canReach(const coord& r1, const coord& r2) { return hypot(r1[0] - r2[0], r1[1] - r2[1]) <= r * 1.0; } 9 | int main() { 10 | cin >> n >> m >> k >> r; 11 | for (int i = 0; i < n + m; ++i) { 12 | cin >> routers[i][0] >> routers[i][1]; 13 | } 14 | queue> q; // array分别存储routers下标,经过的路由器个数,经过的增设路由器个数 15 | vector> inQueue(205); 16 | q.push({0, 0, 0}); 17 | inQueue[0][0] = true; 18 | while (not q.empty()) { 19 | auto i = q.front(); 20 | q.pop(); 21 | if (i[0] == 1) 22 | ans.push_back(i[1]); 23 | const auto& v = routers[i[0]]; 24 | for (int j = 0; j < n + m; ++j) { 25 | int t = i[2] + (j < n ? 0 : 1); //到达j号路由器经过的增设路由器数 26 | if (not inQueue[j][t] and canReach(routers[j], v) and t <= k) { 27 | q.push({j, i[1] + 1, t}); 28 | inQueue[j][t] = true; 29 | } 30 | } 31 | } 32 | cout << *min_element(ans.begin(), ans.end()) - 1; 33 | return 0; 34 | } -------------------------------------------------------------------------------- /CCF CSP/201409-1. 相邻数对.md: -------------------------------------------------------------------------------- 1 | # 【CCF CSP-20140901】相邻数对 2 | 3 | ## 题意概述 4 | 5 | 给定 n 个不同的整数,问这些数中有多少对整数,它们的值正好相差 1。 6 | 7 | ## 输入输出格式 8 | 9 | 输入的第一行包含一个整数 n,表示给定整数的个数。第二行包含所给定的 n 个整数。 10 | 11 | 输出一个整数,表示值正好相差 1 的数对的个数。 12 | 13 | ## 数据规模 14 | 15 | $1\le n \le1000$,给定的整数为不超过 10000 的非负整数。 16 | 17 | ## 算法设计 18 | 19 | 可以暴力枚举每一对整数对,检验它们的差是否为 1 即可。为此可以先将这 n 个整数存储在一个数组中,然后枚举两个变量:i 枚举的区间为$\left[0,n\right)$,j 枚举的区间为$\left[i+1,n\right)$,j 之所以从 i+1 开始枚举,是为了防止重复枚举同一对整数对。最后统计相差为 1 的整数对的个数即可。 20 | 21 | ## C++代码 22 | 23 | ```cpp 24 | #include 25 | using namespace std; 26 | using gg = long long; 27 | int main() { 28 | ios::sync_with_stdio(false); 29 | cin.tie(0); 30 | gg ni, ans = 0; 31 | cin >> ni; 32 | vector ai(ni); 33 | for (gg& i : ai) { 34 | cin >> i; 35 | } 36 | for (gg i = 0; i < ni; ++i) { 37 | for (gg j = i + 1; j < ni; ++j) { 38 | if (abs(ai[i] - ai[j]) == 1) { 39 | ++ans; 40 | } 41 | } 42 | } 43 | cout << ans; 44 | return 0; 45 | } 46 | ``` 47 | -------------------------------------------------------------------------------- /CCF CSP/201409-2. 画图.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | set> s; 8 | gg ni, a, b, c, d; 9 | cin >> ni; 10 | while (ni--) { 11 | cin >> a >> b >> c >> d; 12 | for (gg i = a; i < c; ++i) { 13 | for (gg j = b; j < d; ++j) { 14 | s.insert({i, j}); 15 | } 16 | } 17 | } 18 | cout << s.size(); 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /CCF CSP/201409-3. 字符串匹配.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | gg ni, mi; 8 | string si; 9 | cin >> si; 10 | cin >> mi >> ni; 11 | regex r(si, mi == 0 ? regex::icase : regex::ECMAScript); 12 | while (cin >> si) { 13 | if (regex_search(si, r)) { 14 | cout << si << "\n"; 15 | } 16 | } 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /CCF CSP/201412-1. 门禁系统.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | gg ni, ai; 8 | cin >> ni; 9 | unordered_map um; 10 | while (ni--) { 11 | cin >> ai; 12 | cout << ++um[ai] << " "; 13 | } 14 | return 0; 15 | } -------------------------------------------------------------------------------- /CCF CSP/201412-4. 最优灌溉.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | const gg MAX = 1005; 5 | struct Edge { 6 | gg u, v, cost; 7 | Edge(gg up, gg vp, gg cp) : u(up), v(vp), cost(cp) {} 8 | }; 9 | vector edges; 10 | vector ufs(MAX); 11 | gg findRoot(gg x) { return ufs[x] == x ? x : ufs[x] = findRoot(ufs[x]); } 12 | gg Kruskal() { 13 | iota(ufs.begin(), ufs.end(), 0); 14 | gg sumCost = 0; 15 | sort(edges.begin(), edges.end(), 16 | [](const Edge& e1, const Edge& e2) { return e1.cost < e2.cost; }); 17 | for (auto& e : edges) { 18 | gg ua = findRoot(e.u), ub = findRoot(e.v); 19 | if (ua != ub) { 20 | sumCost += e.cost; 21 | ufs[ua] = ub; 22 | } 23 | } 24 | return sumCost; 25 | } 26 | int main() { 27 | ios::sync_with_stdio(false); 28 | cin.tie(0); 29 | gg ni, mi; 30 | cin >> ni >> mi; 31 | while (mi--) { 32 | gg ai, bi, ci; 33 | cin >> ai >> bi >> ci; 34 | edges.push_back(Edge(ai, bi, ci)); 35 | } 36 | cout << Kruskal(); 37 | return 0; 38 | } -------------------------------------------------------------------------------- /CCF CSP/201503-1. 图像旋转.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | gg ni, mi; 8 | cin >> ni >> mi; 9 | vector> ai(ni, vector(mi)); 10 | for (auto& i : ai) { 11 | for (auto& j : i) { 12 | cin >> j; 13 | } 14 | } 15 | for (gg j = mi - 1; j >= 0; --j) { 16 | for (gg i = 0; i < ni; ++i) { 17 | cout << ai[i][j] << " "; 18 | } 19 | cout << "\n"; 20 | } 21 | return 0; 22 | } -------------------------------------------------------------------------------- /CCF CSP/201503-2. 数字排序.md: -------------------------------------------------------------------------------- 1 | # 【CCF CSP-20150302】数字排序 2 | 3 | ## 题意概述 4 | 5 | 给定 n 个整数,请统计出每个整数出现的次数,按出现次数从多到少的顺序输出。 6 | 7 | ## 输入输出格式 8 | 9 | 输入的第一行包含一个整数 n,表示给定数字的个数。第二行包含 n 个整数,相邻的整数之间用一个空格分隔,表示所给定的整数。 10 | 11 | 输出多行,每行包含两个整数,分别表示一个给定的整数和它出现的次数。按出现次数递减的顺序输出。如果两个整数出现的次数一样多,则先输出值较小的,然后输出值较大的。 12 | 13 | ## 数据规模 14 | 15 | $1\le n\le 1000$,给出的数都是不超过 1000 的非负整数。 16 | 17 | ## 算法设计 18 | 19 | 题目比较简单,先用 unordered_map 将遇到的数字及其出现次数储存起来,然后将 unordered_map 中所有元素搬迁到 vector 中,对 vector 按要求排序输出即可。 20 | 21 | ## C++代码 22 | 23 | ```cpp 24 | #include 25 | using namespace std; 26 | using gg = long long; 27 | int main() { 28 | ios::sync_with_stdio(false); 29 | cin.tie(0); 30 | gg ni, ai; 31 | cin >> ni; 32 | unordered_map um; 33 | while (ni--) { 34 | cin >> ai; 35 | ++um[ai]; 36 | } 37 | vector> ans(um.begin(), um.end()); 38 | sort(ans.begin(), ans.end(), 39 | [](const pair& p1, const pair& p2) { 40 | return tie(p2.second, p1.first) < tie(p1.second, p2.first); 41 | }); 42 | for (auto& i : ans) { 43 | cout << i.first << " " << i.second << "\n"; 44 | } 45 | return 0; 46 | } 47 | ``` 48 | -------------------------------------------------------------------------------- /CCF CSP/201503-3. 节日.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int a,b,c,y1,y2; 4 | int monthdays[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};//平年时每个月有多少天 5 | int daysOfMonth(int y,int m){//判断y年m月有几天 6 | if((y%400==0||y%4==0&&y%100!=0)&&m==2)//y年是闰年且查询2月有几天 7 | return 29;//闰年2月有29天 8 | return monthdays[m];//直接返回monthdays的相应位置的天数 9 | } 10 | int determineWeek(int y,int m,int d,int week=2){//根据1850年1月1日是周二,返回y年m月d日是周几,注意周日用0表示 11 | for(int i=1850;i 2 | using namespace std; 3 | vectortree[20005];//存储整棵树 4 | int n,m,a; 5 | int dp1[20005],dp2[20005]; 6 | void DP(int v){//深度优先遍历 7 | int max1=0,max2=0; 8 | for(int i:tree[v]){ 9 | DP(i); 10 | if(dp1[i]+1>max1){//计算到根结点v到叶子结点的最远距离 11 | max2=max1; 12 | max1=dp1[i]+1; 13 | }else if(dp1[i]+1>max2)//计算到根结点v到叶子结点的第二远距离 14 | max2=dp1[i]+1; 15 | } 16 | dp1[v]=max1; 17 | dp2[v]=max1+max2; 18 | } 19 | int main(){ 20 | scanf("%d%d",&n,&m); 21 | for(int i=2;i<=n+m;++i){ 22 | scanf("%d",&a); 23 | tree[a].push_back(i); 24 | } 25 | DP(1); 26 | printf("%d",*max_element(dp2+1,dp2+n+m+1));//dp2中最大值即为所求 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /CCF CSP/201503-4. 网络延时(深度优先遍历).cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | vectortree[20005];//存储整棵树 4 | int n,m,a,ansV=-1,ansLevel=0;//ansV表示距离最远的结点编号,ansLevel表示最远距离 5 | bool visit[20005];//标记每个节点是否已被访问 6 | void DFS(int v,int level){//深度优先遍历 7 | visit[v]=true; 8 | if(level>ansLevel){ 9 | ansLevel=level; 10 | ansV=v; 11 | } 12 | for(int i:tree[v]) 13 | if(!visit[i]) 14 | DFS(i,level+1); 15 | } 16 | int main(){ 17 | scanf("%d%d",&n,&m); 18 | for(int i=2;i<=n+m;++i){ 19 | scanf("%d",&a); 20 | tree[a].push_back(i); 21 | tree[i].push_back(a);//将树的边存储为无向边 22 | } 23 | DFS(1,0);//第一次深度优先遍历 24 | memset(visit,0,sizeof(visit)); 25 | DFS(ansV,0);//二次遍历 26 | printf("%d",ansLevel); 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /CCF CSP/201509-1. 数列分段.md: -------------------------------------------------------------------------------- 1 | # 【CCF CSP-20150901】数列分段 2 | 3 | ## 题意概述 4 | 5 | 给定一个整数数列,数列中连续相同的最长整数序列算成一段,问数列中共有多少段? 6 | 7 | ## 输入输出格式 8 | 9 | 输入的第一行包含一个整数 n,表示数列中整数的个数。第二行包含 n 个整数,表示给定的数列,相邻的整数之间用一个空格分隔。 10 | 11 | 输出一个整数,表示给定的数列有多个段。 12 | 13 | ## 数据规模 14 | 15 | $1\le n \le 1000$,数列中的整数都是不超过 1000 的正整数。 16 | 17 | ## 算法设计 18 | 19 | 很简单的一道题,用好 find_if 函数可以让代码更简洁。 20 | 21 | ## C++代码 22 | 23 | ```cpp 24 | #include 25 | using namespace std; 26 | using gg = long long; 27 | int main() { 28 | ios::sync_with_stdio(false); 29 | cin.tie(0); 30 | gg ni, ans = 0; 31 | cin >> ni; 32 | vector ai(ni); 33 | for (gg& i : ai) { 34 | cin >> i; 35 | } 36 | for (gg i = 0, j; i < ai.size(); i = j) { 37 | //找到ai[i]右侧第一个不等于ai[i]的值 38 | j = find_if(ai.begin() + i, ai.end(), 39 | [&ai, i](gg a) { return a != ai[i]; }) - ai.begin(); 40 | ++ans; 41 | } 42 | cout << ans; 43 | return 0; 44 | } 45 | ``` 46 | -------------------------------------------------------------------------------- /CCF CSP/201509-2. 日期计算.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | gg yi, di; 7 | cin >> yi >> di; 8 | //存储每个月的天数 9 | array month = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 10 | if (yi % 400 == 0 or (yi % 100 != 0 and yi % 4 == 0)) //闰年2月有29天 11 | month[2] = 29; 12 | gg i = 0; 13 | while (di > month[++i]) 14 | di -= month[i]; 15 | cout << i << '\n' << di; 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /CCF CSP/201509-3. 模板生成系统.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | gg ni, mi; 8 | cin >> ni >> mi; 9 | string line; 10 | vector input(ni); 11 | cin.get(); //吸收换行符 12 | for (gg i = 0; i < ni; ++i) { //读取输入 13 | getline(cin, input[i]); 14 | } 15 | unordered_map um; 16 | smatch result; 17 | regex r("([^ ]+) +\"(.+)\""); 18 | while (mi--) { 19 | getline(cin, line); 20 | if (regex_search(line, result, r)) { //分割变量名和值 21 | um[result.str(1)] = result.str(2); 22 | } 23 | } 24 | r = "\\{\\{ (.*?) \\}\\}"; 25 | for (auto& i : input) { 26 | for (sregex_iterator it(i.begin(), i.end(), r), e; it != e; ++it) { 27 | cout << it->prefix() << um[it->str(1)]; 28 | if (next(it) == e) { //到达最后一个匹配位置 29 | cout << it->suffix() << "\n"; 30 | goto loop; 31 | } 32 | } 33 | cout << i << "\n"; 34 | loop:; 35 | } 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /CCF CSP/201509-4. 高速公路.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | const int MAX=10005; 4 | vectorgraph[MAX]; 5 | //index[i]表示i是第几个被访问的结点,lowLink[i]表示从i出发经有向边可到达的所有节点中最小的index,sccno[i]表示i所属的强连通分量的编号 6 | int index[MAX],lowLink[MAX],sccno[MAX],dfsNo=0,scc_cnt=0; 7 | int ans=0;//最终结果 8 | stacks; 9 | void DFS(int v){ 10 | index[v]=lowLink[v]=++dfsNo; 11 | s.push(v); 12 | for(int i:graph[v]){ 13 | if(index[i]==0){ 14 | DFS(i); 15 | lowLink[v]=min(lowLink[v],lowLink[i]); 16 | }else if(sccno[i]==0) 17 | lowLink[v]=min(lowLink[v],index[i]); 18 | } 19 | if(lowLink[v]==index[v]){//是一个强连通分支的根结点 20 | ++scc_cnt; 21 | int t,num=0;//num表示该强连通分量中结点的个数 22 | do{ 23 | t=s.top(); 24 | s.pop(); 25 | ++num; 26 | sccno[t]=scc_cnt; 27 | }while(t!=v); 28 | ans+=(num-1)*num/2;//加上该强连通分量中的便利城市对个数 29 | } 30 | } 31 | int main(){ 32 | int n,m,k,a,b; 33 | scanf("%d%d",&n,&m); 34 | while(m--){ 35 | scanf("%d%d",&a,&b); 36 | graph[a].push_back(b); 37 | } 38 | for(int i=1;i<=n;++i) 39 | if(index[i]==0) 40 | DFS(i); 41 | printf("%d",ans); 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /CCF CSP/201512-1. 数位之和.md: -------------------------------------------------------------------------------- 1 | # 【CCF CSP-20151201】数位之和 2 | 3 | ## 题意概述 4 | 5 | 给定一个十进制整数 n,输出 n 的各位数字之和。 6 | 7 | ## 输入输出格式 8 | 9 | 输入一个整数 n。 10 | 11 | 输出一个整数,表示答案。 12 | 13 | ## 数据规模 14 | 15 | $$0\len\le{10}^9$$ 16 | 17 | ## 算法设计 18 | 19 | 我们可以将输入存储在一个 string 类型变量中。然后我们可以利用 accumulate 函数求整个字符串中所有数字之和,注意,由于 string 类型中存储的是数字字符,不是真正的数字,在求和的过程中需要在每个数字字符的基础上减去字符`0`所表示的 ASCII 码。 20 | 21 | ## C++代码 22 | 23 | ```cpp 24 | #include 25 | using namespace std; 26 | using gg = long long; 27 | int main() { 28 | ios::sync_with_stdio(false); 29 | cin.tie(0); 30 | string si; 31 | cin >> si; 32 | cout << accumulate(si.begin(), si.end(), 0, 33 | [](gg a, char c) { return a + c - '0'; }); 34 | return 0; 35 | } 36 | ``` 37 | -------------------------------------------------------------------------------- /CCF CSP/201512-4. 送货.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | vectorgraph[10005],path;//图、欧拉路径 4 | int N,M; 5 | bool visit[10005][10005];//表示边是否已被访问 6 | bool f(vector&v){//顶点v的度数是否为奇数 7 | return v.size()%2==1; 8 | } 9 | int main(){ 10 | scanf("%d%d",&N,&M); 11 | for(int i=0;is; 20 | s.push(1);//1号顶点入栈 21 | while(!s.empty()){ 22 | int v=s.top(),i; 23 | for(i=0;i 25 | using namespace std; 26 | using gg = long long; 27 | int main() { 28 | ios::sync_with_stdio(false); 29 | cin.tie(0); 30 | gg ni, ans = 0; 31 | cin >> ni; 32 | vector v(ni); 33 | for (gg& i : v) { 34 | cin >> i; 35 | } 36 | for (gg i = 1; i < v.size() - 1; ++i) { 37 | if (v[i] v[i + 1]) { 38 | ++ans; 39 | } 40 | } 41 | cout << ans; 42 | return 0; 43 | } 44 | ``` -------------------------------------------------------------------------------- /CCF CSP/201604-2. 俄罗斯方块.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int main(){ 4 | int A[15][10],Atemp[10],B[4][4],Btemp[4]={-1,-1,-1,-1}; 5 | fill(Atemp,Atemp+10,15); 6 | for(int i=0;i<15;++i) 7 | for(int j=0;j<10;++j){ 8 | scanf("%d",&A[i][j]); 9 | if(A[i][j]==1&&i-1) 23 | minRow=min(minRow,Atemp[num+i-1]-Btemp[i]-1); 24 | for(int i=0;i<4&&i+minRow<15;++i) 25 | for(int j=0;j<4;++j) 26 | if(i+minRow>=0) 27 | A[i+minRow][num-1+j]=B[i][j]==1?1:A[i+minRow][num-1+j]; 28 | for(int i=0;i<15;++i){ 29 | for(int j=0;j<10;++j) 30 | printf("%d ",A[i][j]); 31 | printf("\n"); 32 | } 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /CCF CSP/201604-3. 路径解析.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | //按字符/分割字符串 5 | vector split(string& s) { 6 | vector ans; 7 | stringstream ss(s); 8 | while (getline(ss, s, '/')) { 9 | ans.push_back(s); 10 | } 11 | return ans; 12 | } 13 | int main() { 14 | ios::sync_with_stdio(false); 15 | cin.tie(0); 16 | gg ni; 17 | string si, cur; 18 | cin >> ni; 19 | cin.get(); //吸收换行符 20 | getline(cin, cur); //读取当前目录 21 | while (ni--) { 22 | getline(cin, si); //读取路径 23 | //路径为空或不是以/开始,那么该路径是以当前目录开始的 24 | if (si.empty() or si[0] != '/') { 25 | si = cur + "/" + si; //在路径首部添加当前路径 26 | } 27 | auto path = split(si); //按/分割路径 28 | vector ans; 29 | for (auto& s : path) { //遍历分割后的路径中每个目录或文件 30 | if (s == "." or s.empty() or (s == ".." and ans.empty())) { 31 | continue; //遇到.或者空字符串或遇到..但没有父目录,不进行任何操作 32 | } else if (s == "..") { //回到父目录,即从ans尾部弹出一个目录 33 | ans.pop_back(); 34 | } else { //压入ans中一个目录或文件 35 | ans.push_back(s); 36 | } 37 | } 38 | string out; 39 | for (string& i : ans) { //将各目录或文件用/连接起来 40 | out += "/" + i; 41 | } 42 | cout << (out.empty() ? "/" : out) << "\n"; 43 | } 44 | return 0; 45 | } -------------------------------------------------------------------------------- /CCF CSP/201604-4. 游戏.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | struct Vertex{ 4 | int r,c,t; 5 | Vertex(int rr,int cc,int tt):r(rr),c(cc),t(tt) {} 6 | }; 7 | bool inQueue[105][105][305];//标志一个结点是否已入队 8 | int n,m,t,direction[4][2]={{-1,0},{0,1},{1,0},{0,-1}};//方向 9 | int main(){ 10 | scanf("%d%d%d",&n,&m,&t); 11 | while(t--){ 12 | int r,c,a,b; 13 | scanf("%d%d%d%d",&r,&c,&a,&b); 14 | for(int i=a;i<=b;++i)//将处于危险时间段内的格子直接标志为已入过队 15 | inQueue[r][c][i]=true; 16 | } 17 | queueq; 18 | q.push(Vertex(1,1,0)); 19 | inQueue[1][1][0]=true; 20 | while(!q.empty()){ 21 | Vertex v=q.front(); 22 | q.pop(); 23 | if(v.r==n&&v.c==m){//到达了终点,输出时间 24 | printf("%d",v.t); 25 | return 0; 26 | } 27 | for(int i=0;i<4;++i){ 28 | int r=v.r+direction[i][0],c=v.c+direction[i][1],t=v.t+1; 29 | if(r>0&&r<=n&&c>0&&c<=m&&!inQueue[r][c][t]){ 30 | q.push(Vertex(r,c,t)); 31 | inQueue[r][c][t]=true; 32 | } 33 | } 34 | } 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /CCF CSP/201609-1. 最大波动.md: -------------------------------------------------------------------------------- 1 | # 【CCF CSP-20160901】最大波动 2 | 3 | ## 题意概述 4 | 5 | 小明正在利用股票的波动程度来研究股票。小明拿到了一只股票每天收盘时的价格,他想知道,这只股票连续几天的最大波动值是多少,即在这几天中某天收盘价格与前一天收盘价格之差的绝对值最大是多少。 6 | 7 | ## 输入输出格式 8 | 9 | 输入的第一行包含了一个整数 n,表示小明拿到的收盘价格的连续天数。第二行包含 n 个正整数,依次表示每天的收盘价格。 10 | 11 | 输出一个整数,表示这只股票这 n 天中的最大波动值。 12 | 13 | ## 数据规模 14 | 15 | $2\le n\le1000$,股票每一天的价格为 1 到 10000 之间的整数。 16 | 17 | ## C++代码 18 | 19 | ```cpp 20 | #include 21 | using namespace std; 22 | using gg = long long; 23 | int main() { 24 | ios::sync_with_stdio(false); 25 | cin.tie(0); 26 | gg ni, last, cur, ans = 0; 27 | cin >> ni >> last; 28 | while (--ni) { 29 | cin >> cur; 30 | ans = max(ans, abs(cur - last)); 31 | last = cur; 32 | } 33 | cout << ans; 34 | return 0; 35 | } 36 | ``` 37 | -------------------------------------------------------------------------------- /CCF CSP/201609-2. 火车购票.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | gg ni, pi; 8 | cin >> ni; 9 | vector v(20, 5); 10 | while (ni--) { 11 | cin >> pi; 12 | //查找有没有剩余座位大于等于pi的排 13 | auto i = find_if(v.begin(), v.end(), [pi](int a) { return a >= pi; }); 14 | if (i != v.end()) { //有 15 | gg start = (i - v.begin()) * 5 + 6 - (*i); //剩余座位起始编号 16 | *i -= pi; //该排减去pi个空闲座位 17 | for (gg j = 0; j < pi; ++j) { //输出pi个连续座位编号 18 | cout << start + j << " "; 19 | } 20 | cout << "\n"; 21 | continue; 22 | } 23 | //以下代码处理没有剩余座位大于等于pi的排的情况 24 | for (gg j = 0; pi > 0; ++j) { //遍历所有的排 25 | //输出该排空闲座位编号,直至输出pi个座位 26 | for (gg start = j * 5 + 6 - v[j]; v[j] > 0; --v[j], ++start, --pi) { 27 | cout << start << " "; 28 | } 29 | } 30 | cout << "\n"; 31 | } 32 | return 0; 33 | } -------------------------------------------------------------------------------- /CCF CSP/201609-4. 交通规划.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | struct Edge{ 4 | int v,cost; 5 | }; 6 | vectorgraph[10005];//图 7 | int N,M,result=0; 8 | bool visit[10005];//当前顶点是否已访问过 9 | int dis[10005],cost[10005]; 10 | void Dijkstra(){ 11 | for(int ii=0;iidis[v]+graph[v][i].cost)||(dis[temp]==dis[v]+graph[v][i].cost&&cost[temp]>graph[v][i].cost)){ 24 | dis[temp]=dis[v]+graph[v][i].cost; 25 | cost[temp]=graph[v][i].cost; 26 | } 27 | } 28 | } 29 | } 30 | int main(){ 31 | scanf("%d%d",&N,&M); 32 | while(M--){//读取数据,注意所给图为无向图 33 | int a,b,c; 34 | scanf("%d%d%d",&a,&b,&c); 35 | graph[a].push_back({b,c}); 36 | graph[b].push_back({a,c}); 37 | } 38 | fill(dis+2,dis+N+1,INT_MAX); 39 | Dijkstra(); 40 | printf("%d",result); 41 | return 0; 42 | } 43 | -------------------------------------------------------------------------------- /CCF CSP/201612-1. 中间数.md: -------------------------------------------------------------------------------- 1 | # 【CCF CSP-20161201】中间数 2 | 3 | ## 题意概述 4 | 5 | 在一个整数序列$a_1,a_2,\cdots,a_n$中,如果存在某个数,大于它的整数数量等于小于它的整数数量,则称其为中间数。在一个序列中,可能存在多个下标不相同的中间数,这些中间数的值是相同的。 6 | 给定一个整数序列,请找出这个整数序列的中间数的值。 7 | 8 | ## 输入输出格式 9 | 10 | 输入的第一行包含了一个整数 n,表示整数序列中数的个数。第二行包含 n 个正整数,依次表示$a_1,a_2,\cdots,a_n$。 11 | 12 | 如果约定序列的中间数存在,则输出中间数的值,否则输出-1,表示不存在中间数。 13 | 14 | ## 数据规模 15 | 16 | $$1\le n\le1000,1\le a_i\le1000$$ 17 | 18 | ## 算法设计 19 | 20 | 显然,如果存在这样的中间数,则该中间数一定是序列的中位数。可以先将读入的序列排序。这样可以很轻松地找到中位数,那么如何判断这个序列中小于中位数和大于中位数的数的个数是否相等呢?由于排序后的序列是一个有序序列,我们可以使用泛型算法库中的 equal_range 算法,它可以返回两个迭代器,第一个指向序列中第一个大于等于中位数的数的位置,第二个指向序列中第一个大于中位数的数的位置,那么通过这两个迭代器就可以得出序列中小于中位数和大于中位数的数的个数了。 21 | 22 | ## C++代码 23 | 24 | ```cpp 25 | #include 26 | using namespace std; 27 | using gg = long long; 28 | int main() { 29 | ios::sync_with_stdio(false); 30 | cin.tie(0); 31 | gg ni; 32 | cin >> ni; 33 | vector ai(ni); 34 | for (gg& i : ai) { 35 | cin >> i; 36 | } 37 | sort(ai.begin(), ai.end()); 38 | gg t = ai[ai.size() / 2]; 39 | auto p = equal_range(ai.begin(), ai.end(), t); 40 | cout << (p.first - ai.begin() == ai.end() - p.second ? t : -1); 41 | return 0; 42 | } 43 | ``` 44 | -------------------------------------------------------------------------------- /CCF CSP/201612-2. 工资计算.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int main() { 4 | ios::sync_with_stdio(false); 5 | cin.tie(0); 6 | double ti; 7 | cin >> ti; 8 | // s为税前工资、rate为纳税比率、t为税后工资 9 | array s{0, 3500, 5000, 8000, 12500, 10 | 38500, 58500, 83500, INT_MAX}, 11 | rate{0.0, 0.0, 0.03, 0.1, 0.2, 0.25, 0.3, 0.35, 0.45}, t{}; 12 | for (int i = 1; i < 9; ++i) //计算各结点处税后工资 13 | t[i] = t[i - 1] + (s[i] - s[i - 1]) * (1 - rate[i]); 14 | //查找输入的ti对应的S所在区间 15 | auto i = find_if(t.begin(), t.end(), [ti](double a) { return a >= ti; }) - 16 | t.begin(); 17 | cout << round((ti - t[i - 1]) / (1 - rate[i]) + s[i - 1]); 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /CCF CSP/201703-1. 分蛋糕.md: -------------------------------------------------------------------------------- 1 | # 【CCF CSP - 20170301】分蛋糕 2 | 3 | ## 题意概述 4 | 5 | 小明今天生日,他有 n 块蛋糕要分给朋友们吃,这 n 块蛋糕(编号为 1 到 n)的重量分别为$a_1,a_2,\cdots,a_n$。小明想分给每个朋友至少重量为 k 的蛋糕。小明的朋友们已经排好队准备领蛋糕,对于每个朋友,小明总是先将自己手中编号最小的蛋糕分给他,当这个朋友所分得蛋糕的重量不到 k 时,再继续将剩下的蛋糕中编号最小的给他,直到小明的蛋糕分完或者这个朋友分到的蛋糕的总重量大于等于 k。 6 | 7 | 请问当小明的蛋糕分完时,总共有多少个朋友分到了蛋糕。 8 | 9 | ## 输入输出格式 10 | 11 | 输入的第一行包含了两个整数 n、k,意义如上所述。第二行包含 n 个正整数,依次表示$a_1,a_2,\cdots,a_n$。 12 | 13 | 输出一个整数,表示有多少个朋友分到了蛋糕。 14 | 15 | ## C++ 代码 16 | 17 | ```cpp 18 | #include 19 | using namespace std; 20 | using gg = long long; 21 | int main() { 22 | ios::sync_with_stdio(false); 23 | cin.tie(0); 24 | gg ni, ki, ai; 25 | gg s = 0, ans = 0; 26 | cin >> ni >> ki; 27 | for (gg i = 0; i < ni; ++i) { 28 | cin >> ai; 29 | s += ai; 30 | if (i == ni - 1 or s >= ki) { 31 | ++ans; 32 | s = 0; 33 | } 34 | } 35 | cout << ans; 36 | return 0; 37 | } 38 | ``` 39 | -------------------------------------------------------------------------------- /CCF CSP/201703-2. 学生排队.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | gg ni, mi, pi, qi; 8 | cin >> ni >> mi; 9 | list lst; 10 | for (gg i = 1; i <= ni; ++i) { 11 | lst.push_back(i); 12 | } 13 | while (mi--) { 14 | cin >> pi >> qi; 15 | lst.insert(next(lst.erase(find(lst.begin(), lst.end(), pi)), qi), pi); 16 | } 17 | for (gg i : lst) { 18 | cout << i << " "; 19 | } 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /CCF CSP/201703-4. 地铁修建.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | struct Edge { //边的类,存储两个端点u,v和边的权值cost 5 | gg u, v, cost; 6 | Edge(gg up, gg vp, gg cp) : u(up), v(vp), cost(cp) {} 7 | }; 8 | vector edges; //存储所有的边 9 | vector ufs(1e5 + 5); //并查集 10 | gg findRoot(gg x) { return ufs[x] == x ? x : ufs[x] = findRoot(ufs[x]); } 11 | int main() { 12 | ios::sync_with_stdio(false); 13 | cin.tie(0); 14 | gg ni, mi; 15 | cin >> ni >> mi; 16 | while (mi--) { 17 | gg ai, bi, ci; 18 | cin >> ai >> bi >> ci; 19 | edges.push_back(Edge(ai, bi, ci)); 20 | } 21 | iota(ufs.begin(), ufs.end(), 0); 22 | gg cost = 0; //存储最长边的长度 23 | sort(edges.begin(), edges.end(), 24 | [](const Edge& e1, const Edge& e2) { return e1.cost < e2.cost; }); 25 | for (gg i = 0; i < edges.size() and findRoot(1) != findRoot(ni); ++i) { 26 | gg ua = findRoot(edges[i].u), ub = findRoot(edges[i].v); 27 | if (ua != ub) { 28 | cost = max(cost, edges[i].cost); //更新最长边 29 | ufs[ua] = ub; 30 | } 31 | } 32 | cout << cost; 33 | return 0; 34 | } -------------------------------------------------------------------------------- /CCF CSP/201709-1. 打酱油.md: -------------------------------------------------------------------------------- 1 | # 【CCF CSP-20170901】打酱油 2 | 3 | ## 题意概述 4 | 5 | 小明带着 N 元钱去买酱油。酱油 10 块钱一瓶,商家进行促销,每买 3 瓶送 1 瓶,或者每买 5 瓶送 2 瓶。请问小明最多可以得到多少瓶酱油。 6 | 7 | ## 输入输出格式 8 | 9 | 输入的第一行包含一个整数 N,表示小明可用于买酱油的钱数。 10 | 11 | 输出一个整数,表示小明最多可以得到多少瓶酱油。 12 | 13 | ## 数据规模 14 | 15 | N 是 10 的整数倍,N 不超过 300。 16 | 17 | ## C++代码 18 | 19 | ```cpp 20 | #include 21 | using namespace std; 22 | using gg = long long; 23 | int main() { 24 | ios::sync_with_stdio(false); 25 | cin.tie(0); 26 | gg n; 27 | cin >> n; 28 | cout << n / 10 + n / 50 * 2 + n % 50 / 30; 29 | return 0; 30 | } 31 | ``` 32 | -------------------------------------------------------------------------------- /CCF CSP/201709-2. 公共钥匙盒.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | struct Key { //钥匙编号,取/还时间,flag=0表示是还;flag=1表示是取 5 | gg num, time, flag; 6 | Key(gg n, gg t, gg f) : num(n), time(t), flag(f) {} 7 | }; 8 | //优先级:时间小、先还后取、编号小的优先 9 | bool operator<(const Key& k1, const Key& k2) { 10 | return tie(k1.time, k1.flag, k1.num) > tie(k2.time, k2.flag, k2.num); 11 | } 12 | int main() { 13 | ios::sync_with_stdio(false); 14 | cin.tie(0); 15 | gg ni, ki, wi, si, ci; 16 | cin >> ni >> ki; 17 | vector v(ni); //存储挂钩上所有钥匙编号 18 | iota(v.begin(), v.end(), 1); //初始时挂钩上钥匙编号为1~N 19 | priority_queue pq; 20 | while (ki--) { 21 | cin >> wi >> si >> ci; 22 | pq.push(Key(wi, si, 1)); //取钥匙 23 | pq.push(Key(wi, si + ci, 0)); //还钥匙 24 | } 25 | while (not pq.empty()) { 26 | auto k = pq.top(); 27 | pq.pop(); 28 | if (k.flag == 1) { //取钥匙 29 | *find(v.begin(), v.end(), k.num) = -1; //置为-1表示该挂钩没有放钥匙 30 | } else { //还钥匙 31 | *find(v.begin(), v.end(), -1) = k.num; //找到最左边的空的挂钩放钥匙 32 | } 33 | } 34 | for (gg i : v) { 35 | cout << i << " "; 36 | } 37 | return 0; 38 | } -------------------------------------------------------------------------------- /CCF CSP/201709-4. 通信网络.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | const gg MAX = 1005; 5 | gg ni, mi; 6 | vector> graph(MAX); 7 | vector> know(MAX, vector(MAX)); 8 | vector visit(MAX); 9 | void dfs(gg v, gg s) { 10 | visit[v] = true; 11 | know[s][v] = know[v][s] = true; 12 | for (gg i : graph[v]) { 13 | if (not visit[i]) { 14 | dfs(i, s); 15 | } 16 | } 17 | } 18 | int main() { 19 | ios::sync_with_stdio(false); 20 | cin.tie(0); 21 | cin >> ni >> mi; 22 | while (mi--) { 23 | gg ai, bi; 24 | cin >> ai >> bi; 25 | graph[ai].push_back(bi); 26 | } 27 | for (gg i = 1; i <= ni; ++i) { 28 | fill(visit.begin() + 1, visit.begin() + ni + 1, false); 29 | dfs(i, i); 30 | } 31 | gg ans = 0; 32 | for (gg i = 1; i <= ni; ++i) { 33 | if (count(know[i].begin() + 1, know[i].begin() + ni + 1, true) == ni) { 34 | ans++; 35 | } 36 | } 37 | cout << ans; 38 | return 0; 39 | } -------------------------------------------------------------------------------- /CCF CSP/201712-1. 最小差值.md: -------------------------------------------------------------------------------- 1 | # 【CCF CSP-20171201】最小差值 2 | 3 | ## 题意概述 4 | 5 | 给定 n 个数,请找出其中相差(差的绝对值)最小的两个数,输出它们的差值的绝对值。 6 | 7 | ## 输入输出格式 8 | 9 | 输入第一行包含一个整数 n。第二行包含 n 个正整数,相邻整数之间使用一个空格分隔。 10 | 输出一个整数,表示答案。 11 | 12 | ## 数据规模 13 | 14 | $2\le n\le\ 1000$,每个给定的整数都是不超过 10000 的正整数。 15 | 16 | ## 算法设计 17 | 18 | 很简单的一道题,先用 sort 函数进行从小到大排序,再利用 adjacent_difference 函数求解相邻两个数差值,最后利用 min_element 函数求出这些差值中的最小值即可。 19 | 20 | ## C++代码 21 | 22 | ```cpp 23 | #include 24 | using namespace std; 25 | using gg = long long; 26 | int main() { 27 | ios::sync_with_stdio(false); 28 | cin.tie(0); 29 | gg ni; 30 | cin >> ni; 31 | vector v(ni); 32 | for (gg& i : v) { 33 | cin >> i; 34 | } 35 | sort(v.begin(), v.end()); 36 | adjacent_difference(v.begin(), v.end(), v.begin()); 37 | cout << *min_element(v.begin() + 1, v.end()); 38 | return 0; 39 | } 40 | ``` 41 | -------------------------------------------------------------------------------- /CCF CSP/201712-2. 游戏.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | gg ni, ki; 8 | cin >> ni >> ki; 9 | queue q; 10 | for (gg i = 1; i <= ni; ++i) { //将1~n这些人的编号压入队列 11 | q.push(i); 12 | } 13 | for (gg i = 1; q.size() > 1; ++i) { // i表示当前报的数字 14 | gg t = q.front(); //弹出当前应该报数的人的编号 15 | q.pop(); 16 | if (i % ki != 0 and i % 10 != ki) { //不该被淘汰,重新入队 17 | q.push(t); 18 | } 19 | } 20 | cout << q.front(); 21 | return 0; 22 | } -------------------------------------------------------------------------------- /CCF CSP/201803-1. 跳一跳.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | // ai存储输入数据,ans为最终得分,num为连跳方块中心次数 8 | gg ai = 1, ans = 0, num = 0; 9 | while (cin >> ai and ai != 0) { 10 | if (ai == 1) { 11 | ans += ai; //加上1分 12 | num = 0; //连跳方块中心次数归零 13 | } else if (ai == 2) { 14 | ans += 2 * (++num); //递增连跳方块中心次数,得分为该次数乘2 15 | } 16 | } 17 | cout << ans; 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /CCF CSP/201803-2. 碰撞的小球.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | gg ni, li, ti; 8 | cin >> ni >> li >> ti; 9 | vector> balls(ni); 10 | for (gg i = 0; i < ni; ++i) { 11 | cin >> balls[i][0]; //记录小球初始位置 12 | balls[i][1] = 1; //默认向右运动 13 | } 14 | while (ti--) { //模拟t秒的运动 15 | unordered_map um; //哈希表,记录小球运动到的位置 16 | for (gg j = 0; j < balls.size(); ++j) { //遍历所有小球 17 | auto& i = balls[j]; 18 | i[0] += i[1]; //运动到下一秒的位置 19 | if (i[0] == 0 or i[0] == li) { //运动到端点,更改方向 20 | i[1] = -i[1]; 21 | } else if (um.count(i[0])) { //与小球碰撞 22 | i[1] = -i[1]; 23 | balls[um[i[0]]][1] = -balls[um[i[0]]][1]; 24 | } 25 | um[i[0]] = j; 26 | } 27 | } 28 | for (auto& i : balls) { 29 | cout << i[0] << " "; 30 | } 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /CCF CSP/201803-3. URL映射.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | gg ni, mi; 8 | cin >> ni >> mi; 9 | vector> rules; 10 | string si, pi; 11 | for (gg i = 0; i < ni; ++i) { 12 | cin >> si >> pi; 13 | si = regex_replace(si, regex(""), "(\\d+)"); 14 | si = regex_replace(si, regex(""), "([^/]+)"); 15 | si = regex_replace(si, regex(""), "(.+)"); 16 | rules.push_back({regex(si), pi}); 17 | } 18 | smatch result; 19 | while (mi--) { 20 | cin >> si; 21 | for (auto& i : rules) { 22 | if (regex_match(si, result, i.first)) { 23 | cout << i.second; 24 | for (gg j = 1; j < result.size(); ++j) { 25 | regex_match(result.str(j), regex("\\d+")) ? 26 | cout << " " << stoll(result.str(j)) : 27 | cout << " " << result[j]; 28 | } 29 | cout << "\n"; 30 | goto loop; 31 | } 32 | } 33 | cout << "404\n"; 34 | loop:; 35 | } 36 | return 0; 37 | } -------------------------------------------------------------------------------- /CCF CSP/201809-1. 卖菜.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | gg ni; 8 | cin >> ni; 9 | vector v(ni); 10 | for (gg& i : v) { 11 | cin >> i; 12 | } 13 | cout << (v[0] + v[1]) / 2; 14 | for (gg i = 1; i < ni - 1; ++i) { 15 | cout << " " << (v[i - 1] + v[i] + v[i + 1]) / 3; 16 | } 17 | cout << " " << (v[ni - 1] + v[ni - 2]) / 2; 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /CCF CSP/201809-2. 买菜.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | int ni, ans = 0; 8 | cin >> ni; 9 | vector> v1(ni), v2(ni); //分别存储小H和小W的装车时间段 10 | for (int i = 0; i < ni; ++i) { 11 | cin >> v1[i][0] >> v1[i][1]; 12 | } 13 | for (int i = 0; i < ni; ++i) { 14 | cin >> v2[i][0] >> v2[i][1]; 15 | } 16 | for (auto& p1 : v1) { 17 | for (auto& p2 : v2) { 18 | if (p1[0] <= p2[1] and p1[1] >= p2[0]) { //判断有无重叠区间 19 | ans += min(p1[1], p2[1]) - max(p1[0], p2[0]); 20 | } 21 | } 22 | } 23 | cout << ans; 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /CCF CSP/201812-1. 小明上学.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | gg red, yellow, green, ni, ki, ti, ans = 0; 8 | cin >> red >> yellow >> green >> ni; 9 | while (cin >> ki >> ti) { 10 | if (ki == 0 or ki == 1) { 11 | ans += ti; 12 | } else if (ki == 2) { 13 | ans += ti + red; 14 | } 15 | } 16 | cout << ans; 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /CCF CSP/201812-2. 小明放学.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | gg light[3], ni, a, b, ans = 0; 8 | cin >> light[0] >> light[2] >> light[1] >> ni; 9 | gg sum = light[0] + light[1] + light[2]; // sum为红绿灯变换一周的总时长 10 | while (cin >> a >> b) { 11 | if (a == 0) { //是道路 12 | ans += b; //时长直接递增 13 | } else { //是红绿灯 14 | if (a == 1) { //将红绿灯标号变为light数组的下标 15 | a = 0; 16 | } else if (a == 3) { 17 | a = 1; 18 | } 19 | b = (light[a] - b + ans) % sum; //该红绿灯变换的最后一周的时长 20 | while (b > light[a]) { //若b比当前红绿灯时长长 21 | b -= light[a]; //减去当前的红绿灯时长 22 | a = (a + 1) % 3; //转向下一个红绿灯 23 | } 24 | if (a == 0) { //是红灯 25 | ans += light[a] - b; //加上红灯剩余时长 26 | } else if (a == 2) { //是黄灯 27 | ans += light[a] - b + light[0]; //加上黄灯剩余时长以及红灯时长 28 | } 29 | } 30 | } 31 | cout << ans; 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /CCF CSP/201812-4. 数据中心.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | struct Edge{//边的类 4 | int v1,v2,cost; 5 | Edge(int vv1,int vv2,int c):v1(vv1),v2(vv2),cost(c){} 6 | bool operator <(const Edge&e)const{//重载小于运算符 7 | return this->cost>e.cost; 8 | } 9 | }; 10 | priority_queueedges; 11 | int father[50005];//并查集 12 | int findFather(int x){//查找根结点并进行路径压缩 13 | if(father[x]==x) 14 | return x; 15 | int temp=findFather(father[x]); 16 | father[x]=temp; 17 | return temp; 18 | } 19 | int main(){ 20 | int n,m,root,ans=0; 21 | scanf("%d%d%d",&n,&m,&root); 22 | iota(father,father+n+1,0);//初始化并查集 23 | while(m--){ 24 | int a,b,c; 25 | scanf("%d%d%d",&a,&b,&c); 26 | edges.push(Edge(a,b,c)); 27 | } 28 | while(!edges.empty()){ 29 | Edge e=edges.top(); 30 | edges.pop(); 31 | int ua=findFather(e.v1),ub=findFather(e.v2); 32 | if(ua!=ub){//边的两个端点不属于同一个集合 33 | father[ua]=ub; 34 | ans=e.cost;//更新最长边 35 | } 36 | } 37 | printf("%d",ans); 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /CCF CSP/201903-1. 小中大.md: -------------------------------------------------------------------------------- 1 | # 【CCF CSP-20190301】小中大 2 | 3 | ## 题意概述 4 | 5 | 给出一个有序序列,按从大到小的顺序输出最大值、中位数和最小值。注意有偶数个数时,中位数为中间两个数的平均值。 6 | 7 | ## 输入输出格式 8 | 9 | 第一行输入一个整数 n,在第二行中存在 n 个有序的整数,可能为升序或降序排列,可能存在连续多个整数相等,整数与整数之间使用空格隔开。 10 | 11 | 输出一行,包括最大值、中位数以及最小值共三个数,并按照从大到小的顺序输出。数据与数据之间使用空格隔开。对于整数请直接输出整数,对于可能出现的分数,请输出四舍五入保留 1 位小数的结果。 12 | 13 | ## 数据规模 14 | 15 | $$n\le{10}^5$$ 16 | 17 | ## 算法设计 18 | 19 | 由于输入就是有序的,我们无需保存下整个序列,只需记录下输入的第一个数、中间的两个数和最后一个数,即可统计出最大值、中位数和最小值。 20 | 21 | ## C++代码 22 | 23 | ```cpp 24 | #include 25 | using namespace std; 26 | using gg = long long; 27 | int main() { 28 | ios::sync_with_stdio(false); 29 | cin.tie(0); 30 | gg ni, ai; 31 | cin >> ni; 32 | gg M1, M2, Mid1, Mid2; 33 | for (gg i = 0; i < ni; ++i) { 34 | cin >> ai; 35 | if (i == 0) { 36 | M1 = ai; 37 | } else if (i == ni - 1) { 38 | M2 = ai; 39 | } else if (ni % 2 == 1 and i == ni / 2) { 40 | Mid1 = Mid2 = ai; 41 | } else if (i == ni / 2) { 42 | Mid1 = ai; 43 | } else if (i == ni / 2 - 1) { 44 | Mid2 = ai; 45 | } 46 | } 47 | cout << max(M1, M2) << " " << fixed 48 | << setprecision((Mid1 + Mid2) % 2 == 0 ? 0 : 1) << (Mid1 + Mid2) / 2.0 49 | << " " << min(M1, M2); 50 | return 0; 51 | } 52 | ``` 53 | -------------------------------------------------------------------------------- /CCF CSP/201903-2. 二十四点.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | gg ni; 8 | cin >> ni; 9 | string si; 10 | queue num; 11 | queue op; 12 | while (ni--) { 13 | cin >> si; 14 | num.push(si[0] - '0'); //把第一个操作数压入队列 15 | for (gg i = 1; i < si.size(); i += 2) { //遍历整个字符串 16 | if (si[i] == '+' or si[i] == '-') { //将加减法的操作数和符号入队 17 | op.push(si[i]); 18 | num.push(si[i + 1] - '0'); 19 | } else if (si[i] == 'x') { //是乘法,计算乘法结果 20 | num.back() *= (si[i + 1] - '0'); 21 | } else { //是除法,计算乘法结果 22 | num.back() /= (si[i + 1] - '0'); 23 | } 24 | } 25 | gg t = num.front(); //第一个加减法操作数 26 | num.pop(); 27 | while (!op.empty()) { //同时遍历两个队列,求出加减运算的结果 28 | char c = op.front(); 29 | op.pop(); 30 | t = (c == '+') ? t + num.front() : t - num.front(); 31 | num.pop(); 32 | } 33 | cout << (t == 24 ? "Yes" : "No") << "\n"; 34 | } 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /CCF CSP/201909-1. 小明种苹果.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | gg ni, mi, t = 0, k = 0, p = -1; 8 | cin >> ni >> mi; 9 | for (gg i = 1; i <= ni; ++i) { //遍历所有苹果树 10 | gg ai, b = 0, ci; 11 | cin >> ai; //疏果之前的苹果个数 12 | t += ai; 13 | for (gg j = 0; j < mi; ++j) { //遍历每一轮的疏果个数 14 | cin >> ci; 15 | b += ci; //累加疏果总数 16 | } 17 | t += b; 18 | if (abs(b) > p) { //当前苹果树的疏果总数比p大,更新p和k 19 | k = i; 20 | p = abs(b); 21 | } 22 | } 23 | cout << t << " " << k << " " << p; 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /CCF CSP/201909-2. 小明种苹果(续).cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | gg ni, mi, t = 0, d = 0, e = 0; 8 | cin >> ni; 9 | vector f(ni); //存储果树是否有苹果掉落 10 | for (gg i = 0; i < ni; ++i) { 11 | gg ai, bi; 12 | cin >> mi >> ai; 13 | while (--mi) { 14 | cin >> bi; 15 | if (bi <= 0) { //进行疏果操作 16 | ai += bi; 17 | } else { 18 | if (ai > bi) //有苹果掉落 19 | f[i] = true; 20 | ai = bi; 21 | } 22 | } 23 | t += ai; //存储最终的总苹果数 24 | } 25 | d = count(f.begin(), f.end(), true); //计算有多少棵果树有苹果掉落 26 | for (gg i = 0; i < ni; ++i) { //统计连续3棵苹果树有苹果掉落的组数 27 | if (f[i] and f[(i + 1) % ni] and f[(i + 2) % ni]) 28 | ++e; 29 | } 30 | cout << t << " " << d << " " << e; 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /CCF CSP/201912-1. 报数.md: -------------------------------------------------------------------------------- 1 | # 【CCF CSP-20191201】报数 2 | 3 | ## 题意概述 4 | 5 | 甲乙丙丁决定玩一个报数的游戏。游戏规则为四个人从 1 开始轮流进行报数,但如果需要报出的数是 7 的倍数或含有数字 7 则直接跳过。此外大家约定,在总共报出了 n 个数后(不计入被跳过的)游戏结束。统计游戏过程中每个人各自跳过了几次。 6 | 7 | ## 输入输出格式 8 | 9 | 输入仅一行,包含一个正整数 n,表示报出了多少个数后游戏结束。 10 | 11 | 输出共四行,每行一个整数,依次表示甲乙丙丁四人在游戏过程中跳过的次数。 12 | 13 | ## C++代码 14 | 15 | ```cpp 16 | #include 17 | using namespace std; 18 | using gg = long long; 19 | int main() { 20 | ios::sync_with_stdio(false); 21 | cin.tie(0); 22 | gg ni; 23 | cin >> ni; 24 | vector ans(4); 25 | for (gg i = 1; ni > 0; ++i) { 26 | if (i % 7 != 0 and to_string(i).find('7') == -1) { 27 | --ni; 28 | } else { 29 | ++ans[(i - 1) % 4]; 30 | } 31 | } 32 | for (gg i : ans) 33 | cout << i << "\n"; 34 | return 0; 35 | } 36 | ``` 37 | -------------------------------------------------------------------------------- /CCF CSP/201912-2. 回收站选址.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; //类型别名 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | //键为坐标,值对应该坐标上下左右四个邻居位置存在垃圾的个数和四个对角位 8 | //置中存在垃圾的个数 9 | map, array> m; 10 | gg n; 11 | array p; 12 | cin >> n; 13 | while (n--) { 14 | cin >> p[0] >> p[1]; 15 | //将当前坐标插入哈希表中,默认邻居位置和对角位置垃圾个数均为0 16 | m.insert({p, {0, 0}}); 17 | for (auto& i : m) { 18 | auto& p2 = i.first; 19 | if ((abs(p[0] - p2[0]) == 1 and p[1] == p2[1]) or 20 | (p[0] == p2[0] and 21 | abs(p[1] - p2[1]) == 1)) { //邻居位置存在垃圾 22 | ++m[p][0]; 23 | ++m[p2][0]; 24 | } else if (abs(p[0] - p2[0]) == 1 and abs(p[1] - p2[1]) == 1) { 25 | //对角位置存在垃圾 26 | ++m[p][1]; 27 | ++m[p2][1]; 28 | } 29 | } 30 | } 31 | array ans{}; //存储最终结果 32 | for (auto& i : m) 33 | if (i.second[0] == 4) //当前坐标可以作为选址 34 | ++ans[i.second[1]]; //递增其得分下的选址个数 35 | for (auto i : ans) 36 | cout << i << "\n"; 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /CCF CSP/202006-1. 线性分类器.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | gg ni, mi; 8 | cin >> ni >> mi; 9 | vector>> points(2); 10 | gg xi, yi, ai, bi, ci; 11 | string typei; 12 | while (ni--) { 13 | cin >> xi >> yi >> typei; 14 | points[typei[0] - 'A'].push_back({xi, yi}); 15 | } 16 | while (mi--) { 17 | cin >> ai >> bi >> ci; 18 | for (auto& p : points) { 19 | for (gg i = 1; i < p.size(); ++i) { 20 | if ((ai + bi * p[i][0] + ci * p[i][1] > 0) ^ (ai + bi * p[0][0] + ci * p[0][1] > 0)) { 21 | cout << "No\n"; 22 | goto loop; 23 | } 24 | } 25 | } 26 | cout << "Yes\n"; 27 | loop:; 28 | } 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /CCF CSP/202006-2. 稀疏向量.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | gg ni, ai, bi, xi, yi, ans = 0; 8 | cin >> ni >> ai >> bi; 9 | unordered_map um; 10 | while (ai--) { 11 | cin >> xi >> yi; 12 | um[xi] = yi; 13 | } 14 | while (bi--) { 15 | cin >> xi >> yi; 16 | ans += um[xi] * yi; 17 | } 18 | cout << ans; 19 | return 0; 20 | } -------------------------------------------------------------------------------- /CCF CSP/202006-2. 稀疏向量.md: -------------------------------------------------------------------------------- 1 | # 【CCF CSP-20200602】稀疏向量 2 | 3 | ## 题意概述 4 | 5 | 给出两个 n 维向量的稀疏向量表示,计算这两个向量的内积。所谓稀疏向量表示,就是指用`(index value)`的格式(索引由 1 开始)表示一个向量在 index 维度上的值为 value,例如向量$\vec{v}=\left(0,0,0,5,0,0,-3,0,0,1\right)$,就可以表示成$\vec{v}=\left[\left(4,5\right),\left(7,-3\right),\left(10,1\right)\right]$。 6 | 7 | ## 输入输出格式 8 | 9 | 输入的第一行包含用空格分隔的三个正整数 n、a 和 b,其中 n 表示向量 u 和 v 的维数,a 和 b 分别表示两个向量所含非零值的个数。接下来 a 行,每行按`index value`的格式输入向量 u 的稀疏表示。接下来 b 行,每行按`index value`的格式输入向量 v 的稀疏表示。注意 index 由 1 开始。 10 | 11 | 输出一个整数,表示向量 u 和向量 v 的内积。 12 | 13 | ## 数据规模 14 | 15 | $$n\le {10}^9,0 25 | using namespace std; 26 | using gg = long long; 27 | int main() { 28 | ios::sync_with_stdio(false); 29 | cin.tie(0); 30 | gg ni, ai, bi, xi, yi, ans = 0; 31 | cin >> ni >> ai >> bi; 32 | unordered_map um; 33 | while (ai--) { 34 | cin >> xi >> yi; 35 | um[xi] = yi; 36 | } 37 | while (bi--) { 38 | cin >> xi >> yi; 39 | ans += um[xi] * yi; 40 | } 41 | cout << ans; 42 | return 0; 43 | } 44 | ``` 45 | -------------------------------------------------------------------------------- /CCF CSP/202009-1. 称检测点查询.md: -------------------------------------------------------------------------------- 1 | # 【CCF CSP-20200901】称检测点查询 2 | 3 | ## 题意概述 4 | 5 | 某市设有 n 个核酸检测点,编号从 1 到 n,其中 i 号检测点的位置可以表示为一个平面整数坐标$(x_i,y_i$。为方便预约核酸检测,请根据市民所在位置$(X,Y)$,查询距其最近的三个检测点。多个检测点距离相同时,编号较小的视为更近。市民到第$i$号检测点的距离公式为$D_i=(X-x_i)^2+(Y-y_i)^2$。 6 | 7 | ## 输入输出格式 8 | 9 | 输入第一行包含用空格分隔的三个整数 n,X 和 Y,表示检测点总数和市民所在位置。第二行到第 n+1 行依次输入 n 个检测点的坐标。第$i+1$行($1<=i<=n$)包含用空格分隔的两个整数$x_i$和$y_i$,表示$i$号检测点所在位置。 10 | 11 | 输出共三行,按距离从近到远,依次输出距离该市民最近的三个检测点编号。 12 | 13 | ## 数据规模 14 | 15 | $$3<=n<=200$$ 16 | 17 | ## 算法设计 18 | 19 | 可以维护一个大小为 3 的红黑树(当然用堆也可以),每次比较当前检测点到市民的距离与红黑树中的最大距离,如果当前检测点到市民的距离更小,则从红黑树中删除最大距离,将当前检测点放入红黑树中。最后输出红黑树中所有检测点编号即可。 20 | 21 | ## C++代码 22 | 23 | ```cpp 24 | #include 25 | using namespace std; 26 | using gg = long long; 27 | int main() { 28 | ios::sync_with_stdio(false); 29 | cin.tie(0); 30 | gg ni, xi, yi, a, b; 31 | cin >> ni >> xi >> yi; 32 | set> s; 33 | for (gg i = 1; i <= ni; ++i) { 34 | cin >> a >> b; 35 | gg d = (a - xi) * (a - xi) + (b - yi) * (b - yi); 36 | if (s.size() < 3 or (*s.rbegin())[0] > d) { 37 | if (s.size() >= 3) { 38 | s.erase(prev(s.end())); 39 | } 40 | s.insert({d, i}); 41 | } 42 | } 43 | for (auto& i : s) { 44 | cout << i[1] << "\n"; 45 | } 46 | return 0; 47 | } 48 | ``` 49 | -------------------------------------------------------------------------------- /CCF CSP/202012-1. 期末预测之安全指数.md: -------------------------------------------------------------------------------- 1 | # 【CCF CSP-202012-1】期末预测之安全指数 2 | 3 | ## 题意概述 4 | 5 | 给出 n 项指标,每项指标包含$score_i$和$w_i$两个值,求$max(0,\sum_{i=1}^{n} score_i\cdot w_i)$的值。 6 | 7 | ## 输入输出格式 8 | 9 | 输入的第一行包含一个正整数 n。接下来 n 行,每行包含用空格分隔的两个整数,分别表示指标的重要程度和小菜同学该项的得分。 10 | 11 | 输出一个非负整数,表示小菜同学期末的安全指数。 12 | 13 | ## 数据规模 14 | 15 | $$2<=n<=10^5$$ 16 | 17 | ## C++代码 18 | 19 | ```cpp 20 | #include 21 | using namespace std; 22 | using gg = long long; 23 | int main() { 24 | ios::sync_with_stdio(false); 25 | cin.tie(0); 26 | gg ni, w, s; 27 | cin >> ni; 28 | gg ans = 0; 29 | while (ni--) { 30 | cin >> w >> s; 31 | ans += s * w; 32 | } 33 | cout << max(0ll, ans) << "\n"; 34 | return 0; 35 | } 36 | ``` 37 | -------------------------------------------------------------------------------- /CCF CSP/202104-1. 灰度直方图.md: -------------------------------------------------------------------------------- 1 | # 【CCF CSP-202104-1】灰度直方图 2 | 3 | ## 题意概述 4 | 5 | 一副$n\times m$的灰度图像的灰度直方图可以表示为一个长度为$L$的数组$h$,其中$h[x] (0<=x 21 | using namespace std; 22 | using gg = long long; 23 | int main() { 24 | ios::sync_with_stdio(false); 25 | cin.tie(0); 26 | gg ni, mi, li, xi; 27 | cin >> ni >> mi >> li; 28 | vector ans(li); 29 | for (gg i = 0; i < ni; ++i) { 30 | for (gg j = 0; j < mi; ++j) { 31 | cin >> xi; 32 | ans[xi]++; 33 | } 34 | } 35 | for (gg i : ans) { 36 | cout << i << " "; 37 | } 38 | return 0; 39 | } 40 | ``` 41 | -------------------------------------------------------------------------------- /PAT/Advanced Level/1001. A+B Format.md: -------------------------------------------------------------------------------- 1 | # 【PAT A-1001】A+B Format 2 | 3 | ## 题意概述 4 | 5 | 输入两个整数 a 和 b,输出 a+b。输出格式为:必须用逗号将数字划分成多个组,每组 3 个数字(除非该组数字个数不足 3 个)。 6 | 7 | ## 输入输出格式 8 | 9 | 输入第一行给出用空格符分隔的两个数字 a 和 b。 10 | 11 | 按给定格式输出 a+b。 12 | 13 | ## 数据规模 14 | 15 | $$-{10}^6\le a,b\le {10}^6$$ 16 | 17 | ## 算法设计 18 | 19 | 读取 a 和 b,计算出 a+b 后,如果 a+b 为负数,先输出一个负号。然后将 a+b 的绝对值转换成字符串,假设字符串长度为 n,如果 n 能被 3 整除,则输出的第一组数字个数应为 3;否则输出的第一组数字个数应为 n%3。之后每 3 个数字一组逐组输出即可。注意组间要用逗号分隔。 20 | 21 | ## C++代码 22 | 23 | ```cpp 24 | #include 25 | using namespace std; 26 | using gg = long long; 27 | int main() { 28 | ios::sync_with_stdio(false); 29 | cin.tie(0); 30 | gg ai, bi; 31 | cin >> ai >> bi; 32 | ai += bi; 33 | if (ai < 0) { //单独输出负号 34 | cout << "-"; 35 | } 36 | string s = to_string(abs(ai)); //转换成字符串 37 | gg n = s.size(); 38 | //先输出最前列的几位数 39 | cout << s.substr(0, n % 3 == 0 ? 3 : n % 3); 40 | //每3个字符输出一次(注意输出逗号) 41 | for (gg i = n % 3 == 0 ? 3 : n % 3; i < n; i += 3) { 42 | cout << "," << s.substr(i, 3); 43 | } 44 | return 0; 45 | } 46 | ``` 47 | -------------------------------------------------------------------------------- /PAT/Advanced Level/1002. A+B for Polynomials.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | map> um; //按键从高到低排序 8 | gg ki, ai; 9 | double bi; 10 | cin >> ki; 11 | while (ki--) { 12 | cin >> ai >> bi; 13 | um[ai] += bi; 14 | } 15 | cin >> ki; 16 | while (ki--) { 17 | cin >> ai >> bi; 18 | um[ai] += bi; 19 | if (um[ai] == 0) { //删除系数为零的项 20 | um.erase(ai); 21 | } 22 | } 23 | if (um.empty()) { //如果所有项系数均为0,只输出一个零即可 24 | cout << "0"; 25 | return 0; 26 | } 27 | cout << fixed << setprecision(1); //浮点数保留一位小数 28 | cout << um.size(); 29 | for (auto& i : um) { 30 | cout << " " << i.first << " " << i.second; 31 | } 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /PAT/Advanced Level/1005. Spell It Right.md: -------------------------------------------------------------------------------- 1 | # 【PAT A-1005】Spell It Right 2 | 3 | ## 题意概述 4 | 5 | 读入一个正整数 n,计算其各位数字之和,用英文写出和的每一位数字。 6 | 7 | ## 输入输出格式 8 | 9 | 输入一个正整数 n。 10 | 11 | 在一行内输出 n 的各位数字之和的每一位,英文单词间有 1 个空格,但一行中最后一个英文单词后没有空格。 12 | 13 | ## 数据规模 14 | 15 | $$n<{10}^{100}$$ 16 | 17 | ## 算法设计 18 | 19 | 由于输入的 n 最大可以达到${10}^{100}$,无法用整数类型存储,我们只能将它存储在一个 string 类型变量中。然后我们可以利用 accumulate 函数求整个字符串中所有数字之和,注意,由于 string 类型中存储的是数字字符,不是真正的数字,在求和的过程中需要在每个数字字符的基础上减去字符`0`所表示的 ASCII 码。然后我们可以用一个 string 类型的数组存储每个数字对应的英文字符串。将求出的和转换成 string 类型变量,然后遍历该变量中所有数字字符,输出对应的英文即可。 20 | 21 | ## C++代码 22 | 23 | ```cpp 24 | #include 25 | using namespace std; 26 | using gg = long long; 27 | int main() { 28 | ios::sync_with_stdio(false); 29 | cin.tie(0); 30 | string si; 31 | cin >> si; 32 | gg s = accumulate(si.begin(), si.end(), 0, 33 | [](gg a, char b) { return a + b - '0'; }); 34 | string ans = to_string(s); 35 | array t{"zero", "one", "two", "three", "four", 36 | "five", "six", "seven", "eight", "nine"}; 37 | for (int i = 0; i < ans.size(); ++i) { 38 | cout << (i == 0 ? "" : " ") << t[ans[i] - '0']; 39 | } 40 | return 0; 41 | } 42 | ``` 43 | -------------------------------------------------------------------------------- /PAT/Advanced Level/1006. Sign In and Sign Out.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | struct Person { 5 | string name, in, out; 6 | Person(string n = "", string i = "99:99:99", string o = "00:00:00") : 7 | name(n), in(i), out(o) {} 8 | }; 9 | int main() { 10 | ios::sync_with_stdio(false); 11 | cin.tie(0); 12 | Person in, out, temp; 13 | gg mi; 14 | cin >> mi; 15 | while (mi--) { 16 | cin >> temp.name >> temp.in >> temp.out; 17 | if (temp.in < in.in) { 18 | in = temp; 19 | } 20 | if (temp.out > out.out) { 21 | out = temp; 22 | } 23 | } 24 | cout << in.name << " " << out.name; 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /PAT/Advanced Level/1007. Maximum Subsequence Sum.md: -------------------------------------------------------------------------------- 1 | # pat 甲级 1007. Maximum Subsequence Sum 2 | 3 | ## 题意概述 4 | 5 | 给定一个由 K 个整数组成的序列,求最大连续子序列和。 6 | 7 | ## 输入输出格式 8 | 9 | 输入第一行包含一个正整数 K。第二行包含 K 个数字,以空格分隔。 10 | 11 | 在一行中输出最大和,以及最大子序列的第一个和最后一个数字。数字必须用一个空格分隔,但行尾不能有多余的空格。如果最大子序列不是唯一的,则输出索引 i 和 j 最小的子序列。如果所有 K 个数字均为负,则其最大和定义为 0,并输出整个序列的第一个和最后一个数字。 12 | 13 | ## 数据规模 14 | 15 | $$K<=10^4$$ 16 | 17 | ## 前置知识 18 | 19 | 本题是经典的线性动态规划问题,建议系统学习过动态规划之后再尝试解决本题。 20 | 21 | ## C++代码 22 | 23 | ```cpp 24 | #include 25 | using namespace std; 26 | using gg = long long; 27 | int main() { 28 | ios::sync_with_stdio(false); 29 | cin.tie(0); 30 | gg ni; 31 | cin >> ni; 32 | vector v(ni); 33 | for (gg& i : v) { 34 | cin >> i; 35 | } 36 | vector start(ni), dp(v.begin(), v.end()); 37 | iota(start.begin(), start.end(), 0); 38 | for (gg i = 1; i < ni; ++i) { 39 | if (dp[i] <= dp[i - 1] + v[i]) { 40 | dp[i] = dp[i - 1] + v[i]; 41 | start[i] = start[i - 1]; 42 | } 43 | } 44 | gg ans = max_element(dp.begin(), dp.end()) - dp.begin(); 45 | if (dp[ans] < 0) { 46 | cout << "0 " << v[0] << " " << v.back(); 47 | } else { 48 | cout << dp[ans] << " " << v[start[ans]] << " " << v[ans]; 49 | } 50 | return 0; 51 | } 52 | ``` 53 | -------------------------------------------------------------------------------- /PAT/Advanced Level/1008. Elevator.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | gg ni, ai; 8 | gg cur = 0, ans = 0; 9 | cin >> ni; 10 | while (ni--) { 11 | cin >> ai; 12 | if (ai > cur) { 13 | ans += (ai - cur) * 6; 14 | } else if (ai < cur) { 15 | ans += (cur - ai) * 4; 16 | } 17 | cur = ai; 18 | ans += 5; 19 | } 20 | cout << ans; 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /PAT/Advanced Level/1011. World Cup Betting.md: -------------------------------------------------------------------------------- 1 | # 【PAT A-1011】World Cup Betting 2 | 3 | ## 题意概述 4 | 5 | 给出三场比赛胜(W)、平(T)、负(L)的赔率,计算最大的收益。收益计算公式为:$P=((\prod _{i=1} ^3 max({W_i,T_i,L_i})\times 65\%-1)\times 2$。 6 | 7 | ## 输入输出格式 8 | 9 | 输入三行,每行按 W、T、L 的次序给出一场比赛的胜平负赔率。 10 | 11 | 输出一行,先输出 3 场比赛中每场比赛中最大赔率对应 W、T、L 中哪个赔率,再输出最后的最大收益,保留两位小数。 12 | 13 | ## C++代码 14 | 15 | ```cpp 16 | #include 17 | using namespace std; 18 | using gg = long long; 19 | int main() { 20 | ios::sync_with_stdio(false); 21 | cin.tie(0); 22 | double ans = 1; 23 | string t = "WTL"; 24 | for (gg i = 0; i < 3; ++i) { 25 | double m = 0, ai; 26 | gg index = 0; 27 | for (gg j = 0; j < 3; ++j) { 28 | cin >> ai; 29 | if (ai > m) { 30 | m = ai; 31 | index = j; 32 | } 33 | } 34 | cout << t[index] << " "; //输出每场比赛最大的那个数对应的WTL字符 35 | ans *= m; //累乘 36 | } 37 | cout << fixed << setprecision(2) << (ans * 0.65 - 1) * 2; //输出收益 38 | return 0; 39 | } 40 | ``` 41 | -------------------------------------------------------------------------------- /PAT/Advanced Level/1015. Reversible Primes.md: -------------------------------------------------------------------------------- 1 | # 【PAT A-1015】Reversible Primes 2 | 3 | ## 题意概述 4 | 5 | 判断数字 N 以及 N 在进制 D 下的`翻转数`是否均为素数。例如 73 在进制 10 下的`翻转数`为 37。 6 | 7 | ## 输入输出格式 8 | 9 | 输入的每一行给出两个正整数 N 和 D,最后一行以一个负数结束。 10 | 11 | 针对输入的每一行,如果数字 N 以及 N 在进制 D 下的`翻转数`均为素数,输出`Yes`,否则输出`No`。 12 | 13 | ## 数据规模 14 | 15 | $$0 25 | using namespace std; 26 | using gg = long long; 27 | bool isPrime(gg n) { 28 | if (n < 2) 29 | return false; 30 | for (gg i = 2; i <= (gg)sqrt(n); ++i) 31 | if (n % i == 0) 32 | return false; 33 | return true; 34 | } 35 | int main() { 36 | ios::sync_with_stdio(false); 37 | cin.tie(0); 38 | gg ni, di; 39 | while (cin >> ni and ni >= 0) { 40 | cin >> di; 41 | gg k = 0, m = ni; 42 | while (m != 0) { 43 | k = k * di + m % di; 44 | m /= di; 45 | } 46 | cout << (isPrime(ni) and isPrime(k) ? "Yes\n" : "No\n"); 47 | } 48 | return 0; 49 | } 50 | ``` 51 | -------------------------------------------------------------------------------- /PAT/Advanced Level/1017. Queueing at Bank.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | using agg2 = array; 5 | int main() { 6 | ios::sync_with_stdio(false); 7 | cin.tie(0); 8 | gg ni, ki; 9 | cin >> ni >> ki; 10 | gg startTime = 8 * 60 * 60, endTime = 17 * 60 * 60; 11 | priority_queue, greater> windows; 12 | priority_queue, greater> customers; 13 | for (gg i = 0; i < ki; ++i) { 14 | windows.push(startTime); 15 | } 16 | while (ni--) { 17 | gg h, m, s, p; 18 | char c; 19 | cin >> h >> c >> m >> c >> s >> p; 20 | gg arriveTime = h * 60 * 60 + m * 60 + s; 21 | if (arriveTime > endTime) { 22 | continue; 23 | } 24 | customers.push({arriveTime, p * 60}); 25 | } 26 | gg time = 0, num = customers.size(); 27 | while (not customers.empty()) { 28 | auto c = customers.top(); 29 | customers.pop(); 30 | gg t = windows.top(); 31 | windows.pop(); 32 | if (t > c[0]) { 33 | time += t - c[0]; 34 | } 35 | windows.push(max(c[0], t) + c[1]); 36 | } 37 | cout << fixed << setprecision(1) << time / 60.0 / num; 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /PAT/Advanced Level/1019. General Palindromic Number.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | vector decToR(gg n, gg R) { 5 | vector ans; 6 | do { 7 | ans.push_back(n % R); 8 | n /= R; 9 | } while (n != 0); 10 | reverse(ans.begin(), ans.end()); 11 | return ans; 12 | } 13 | int main() { 14 | ios::sync_with_stdio(false); 15 | cin.tie(0); 16 | gg ni, bi; 17 | cin >> ni >> bi; 18 | auto v = decToR(ni, bi); 19 | cout << (equal(v.begin(), v.end(), v.rbegin()) ? "Yes" : "No") << "\n"; 20 | for (int i = 0; i < v.size(); ++i) { 21 | cout << (i == 0 ? "" : " ") << v[i]; 22 | } 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /PAT/Advanced Level/1023. Have Fun with Numbers.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | string Plus(const string& a, const string& b) { 5 | string ans; 6 | gg carry = 0; //进位 7 | for (gg i = a.size() - 1, j = b.size() - 1; i >= 0 or j >= 0 or carry != 0; --i, --j) { 8 | gg p1 = i >= 0 ? a[i] - '0' : 0, p2 = j >= 0 ? b[j] - '0' : 0; 9 | gg k = p1 + p2 + carry; 10 | ans.push_back(k % 10 + '0'); 11 | carry = k / 10; 12 | } 13 | reverse(ans.begin(), ans.end()); //要进行翻转 14 | return ans; 15 | } 16 | int main() { 17 | ios::sync_with_stdio(false); 18 | cin.tie(0); 19 | string a; 20 | cin >> a; 21 | string b = Plus(a, a); 22 | if (a.size() == b.size() and is_permutation(a.begin(), a.end(), b.begin())) { 23 | cout << "Yes\n"; 24 | } else { 25 | cout << "No\n"; 26 | } 27 | cout << b; 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /PAT/Advanced Level/1027. Colors in Mars.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | string t = "0123456789ABC"; 8 | cout << "#"; 9 | for (gg i = 0; i < 3; ++i) { 10 | gg ai; 11 | cin >> ai; 12 | cout << t[ai / 13] << t[ai % 13]; 13 | } 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /PAT/Advanced Level/1028. List Sorting.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | struct Student { 5 | string id, name; 6 | gg grade; 7 | }; 8 | int main() { 9 | ios::sync_with_stdio(false); 10 | cin.tie(0); 11 | gg ni, ci; 12 | cin >> ni >> ci; 13 | vector v(ni); 14 | for (gg i = 0; i < ni; ++i) { 15 | cin >> v[i].id >> v[i].name >> v[i].grade; 16 | } 17 | vector> f = { 18 | [](const Student& s1, const Student& s2) { return s1.id < s2.id; }, 19 | [](const Student& s1, const Student& s2) { 20 | return tie(s1.name, s1.id) < tie(s2.name, s2.id); 21 | }, 22 | [](const Student& s1, const Student& s2) { 23 | return tie(s1.grade, s1.id) < tie(s2.grade, s2.id); 24 | }}; 25 | sort(v.begin(), v.end(), f[ci - 1]); 26 | for (auto& i : v) { 27 | cout << i.id << " " << i.name << " " << i.grade << "\n"; 28 | } 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /PAT/Advanced Level/1029. Median.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | gg ni; 8 | cin >> ni; 9 | vector s1(ni); 10 | for (gg& i : s1) { 11 | cin >> i; 12 | } 13 | cin >> ni; 14 | vector s2(ni); 15 | for (gg& i : s2) { 16 | cin >> i; 17 | } 18 | gg k = (s1.size() + s2.size() + 1) / 2, ans; 19 | for (gg i = 0, j = 0; k > 0; --k) { 20 | gg a = i < s1.size() ? s1[i] : INT_MAX, 21 | b = j < s2.size() ? s2[j] : INT_MAX; 22 | if (a < b) { 23 | ans = s1[i++]; 24 | } else { 25 | ans = s2[j++]; 26 | } 27 | } 28 | cout << ans; 29 | return 0; 30 | } -------------------------------------------------------------------------------- /PAT/Advanced Level/1031. Hello World for U.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | string input = ""; 8 | cin >> input; 9 | gg n1 = (input.size() + 2) / 3; 10 | gg n2 = input.size() + 2 - 2 * n1; 11 | //前n1-1行,需要输出首尾两个字符,且每行字符数为n2 12 | for (int i = 0; i < n1 - 1; ++i) { 13 | cout << input[i]; 14 | for (int j = 0; j < n2 - 2; ++j) 15 | cout << " "; 16 | cout << input[input.size() - i - 1] << "\n"; 17 | } 18 | //最后一行将没有输出的n2个字符一次性输出 19 | cout << input.substr(n1 - 1, n2); 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /PAT/Advanced Level/1032. Sharing.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | vector> input(gg(1e6)); 8 | gg start1, start2, ni; 9 | cin >> start1 >> start2 >> ni; 10 | for (gg i = 0; i < ni; ++i) { 11 | gg address, nextA; 12 | string data; 13 | cin >> address >> data >> nextA; 14 | input[address] = {data, nextA}; 15 | } 16 | unordered_set us; 17 | while (start1 != -1) { 18 | us.insert(start1); 19 | start1 = input[start1].second; 20 | } 21 | while (start2 != -1) { 22 | if (us.count(start2)) { 23 | cout << setfill('0') << setw(5) << start2; 24 | return 0; 25 | } 26 | start2 = input[start2].second; 27 | } 28 | cout << "-1"; 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /PAT/Advanced Level/1037. Magic Coupon.md: -------------------------------------------------------------------------------- 1 | # 【PAT A-1037】Magic Coupon 2 | 3 | ## 题意概述 4 | 5 | 给定两个序列,从这两个序列中每次分别拿出一个数字进行相乘,问最终得到的所有乘积之和最大是多少。序列中每个数字最多只能用一次,当然也可以不用。 6 | 7 | ## 输入输出格式 8 | 9 | 输入第一行先给出第一个序列的长度$N_c$,然后是$N_c$个整数。第二行先给出第二个序列的长度$N_p$,然后是$N_p$个整数。 10 | 11 | 输出最终得到的所有乘积之和的最大值。 12 | 13 | ## 数据规模 14 | 15 | $$1\le N_c,N_p\le{10}^5$$ 16 | 17 | ## 算法设计 18 | 19 | 解决这道题需要使用贪心算法,贪心策略是:对两个序列进行排序,正数和负数分开考虑,对于正数,肯定是大的整数乘大的正数得到的乘积更大;对于负数,肯定是小的负数乘小的负数得到的乘积更大。 20 | 21 | ## 注意点 22 | 23 | 进行累加的循环中,不能以乘积大于 0 或者乘积小于 0 作为判断条件,因为在两个序列正负数个数相同时,这样的求得的结果会发生错误(想一想为什么?)。 24 | 25 | ## C++代码 26 | 27 | ```cpp 28 | #include 29 | using namespace std; 30 | using gg = long long; 31 | int main() { 32 | ios::sync_with_stdio(false); 33 | cin.tie(0); 34 | gg ni, mi; 35 | cin >> ni; 36 | vector v1(ni); 37 | for (gg& i : v1) { 38 | cin >> i; 39 | } 40 | cin >> mi; 41 | vector v2(mi); 42 | for (gg& i : v2) { 43 | cin >> i; 44 | } 45 | sort(v1.begin(), v1.end()); 46 | sort(v2.begin(), v2.end()); 47 | gg ans = 0; 48 | for (gg i = 0; i < min(ni, mi) and v1[i] < 0 and v2[i] < 0; ++i) { 49 | ans += v1[i] * v2[i]; 50 | } 51 | for (gg i = ni - 1, j = mi - 1; 52 | i >= 0 and j >= 0 and v1[i] > 0 and v2[j] > 0; --i, --j) { 53 | ans += v1[i] * v2[j]; 54 | } 55 | cout << ans; 56 | return 0; 57 | } 58 | ``` 59 | -------------------------------------------------------------------------------- /PAT/Advanced Level/1038. Recover the Smallest Number.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | gg ni; 8 | cin >> ni; 9 | vector v(ni); 10 | for (auto& i : v) { //读取n个数字 11 | cin >> i; 12 | } 13 | //按拼接后形成字典序最小的字符串的比较方式进行排序 14 | sort(v.begin(), v.end(), 15 | [](const string& s1, const string& s2) { return s1 + s2 < s2 + s1; }); 16 | string s = accumulate(v.begin(), v.end(), string()); //将所有数字拼接在一起 17 | //找到第一个不为零的字符 18 | auto i = find_if(s.begin(), s.end(), [](char c) { return c != '0'; }); 19 | //输出不带前导零的数字 20 | i == s.end() ? (cout << "0") : (cout << s.substr(i - s.begin())); 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /PAT/Advanced Level/1039. Course List for Student.md: -------------------------------------------------------------------------------- 1 | # 【PAT A-1039】Course List for Student 2 | 3 | ## 输入输出格式 4 | 5 | 输入第一行给出两个正整数 N 和 K,分别表示要查询的学生个数和课程数。课程从 1~K 编号。接下来 K 组输入,每组第一行给出两个正整数 i 和$N_i$,分别表示课程编号以及选了该课的学生个数。第二行给出$N_i$个学生的 ID。输入的最后一行给出 N 个要查询的学生 ID,要求查询这 N 个学生选的所有课程编号。 6 | 7 | 对应查询的每个学生输出一行,先输出这个学生的 ID,然后输出这个学生选择的课程数量,最后按升序输出这个学生选择的所有课程编号。 8 | 9 | ## 数据规模 10 | 11 | $$N\le {10}^4,K\le 2500$$ 12 | 13 | ## 算法设计 14 | 15 | 需要建立一种映射关系:学生 ID 到该学生选择的全部课程,这种映射可以用`unordered_map>`表示,键表示学生 ID,值用一个 set 表示,可以按升序存储所有课程编号。在读取学生信息的时候,将学生及其选课信息存入其中,查询时按要求输出即可。 16 | 17 | ## C++代码 18 | 19 | ```cpp 20 | #include 21 | using namespace std; 22 | using gg = long long; 23 | int main() { 24 | ios::sync_with_stdio(false); 25 | cin.tie(0); 26 | gg ni, ki, index, mi; 27 | cin >> ni >> ki; 28 | string id; 29 | unordered_map> ans; 30 | for (gg i = 0; i < ki; ++i) { 31 | cin >> index >> mi; 32 | for (gg j = 0; j < mi; ++j) { 33 | cin >> id; 34 | ans[id].insert(index); 35 | } 36 | } 37 | for (gg i = 0; i < ni; ++i) { 38 | cin >> id; 39 | auto& c = ans[id]; 40 | cout << id << " " << c.size(); 41 | for (auto j : c) { 42 | cout << " " << j; 43 | } 44 | cout << "\n"; 45 | } 46 | return 0; 47 | } 48 | ``` 49 | -------------------------------------------------------------------------------- /PAT/Advanced Level/1041. Be Unique.md: -------------------------------------------------------------------------------- 1 | # 【PAT A-1041】Be Unique 2 | 3 | ## 输入输出格式 4 | 5 | 输入只有一行,先给出一个正整数 N,接下来输入 N 个数。 6 | 7 | 输出在这 N 个数中,第一个只出现 1 次的数字。如果没有,输出`None`。 8 | 9 | ## 数据规模 10 | 11 | $$0`存储这 N 个数字中每个数字及其出现次数。再次遍历这 N 个数字,将第一个只出现 1 次的数字输出即可。 16 | 17 | ## C++代码 18 | 19 | ```cpp 20 | #include 21 | using namespace std; 22 | using gg = long long; 23 | int main() { 24 | ios::sync_with_stdio(false); 25 | cin.tie(0); 26 | unordered_map um; 27 | gg ni; 28 | cin >> ni; 29 | vector ai(ni); 30 | for (gg i = 0; i < ni; ++i) { 31 | cin >> ai[i]; 32 | ++um[ai[i]]; 33 | } 34 | for (gg i : ai) { 35 | if (um[i] == 1) { 36 | cout << i; 37 | return 0; 38 | } 39 | } 40 | cout << "None"; 41 | return 0; 42 | } 43 | ``` 44 | -------------------------------------------------------------------------------- /PAT/Advanced Level/1042. Shuffling Machine.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | vector ans(54), order(54); 8 | gg times; 9 | cin >> times; 10 | for (int i = 0; i < 54; ++i) { 11 | cin >> order[i]; 12 | } 13 | iota(ans.begin(), ans.end(), 0); //用0-53这54个整数初始化ans 14 | while (times--) { //混洗times次 15 | vector temp(54); //存储临时结果 16 | for (gg i = 0; i < 54; ++i) { 17 | temp[order[i] - 1] = ans[i]; 18 | } 19 | ans = temp; //存入ans中 20 | } 21 | string s = "SHCDJ"; 22 | for (int i = 0; i < 54; ++i) { //输出最终结果 23 | cout << (i > 0 ? " " : "") << s[ans[i] / 13] << ans[i] % 13 + 1; 24 | } 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /PAT/Advanced Level/1046. Shortest Distance.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | gg ni, mi, sum = 0; 8 | cin >> ni; 9 | vector v(ni + 1); //注意v[0]=0 10 | for (gg i = 1; i <= ni; ++i) { 11 | cin >> v[i]; 12 | } 13 | partial_sum(v.begin(), v.end(), v.begin()); //求前缀和 14 | cin >> mi; 15 | while (mi--) { 16 | gg ai, bi; 17 | cin >> ai >> bi; 18 | gg t = v[max(ai, bi) - 1] - v[min(ai, bi) - 1]; 19 | cout << min(t, v.back() - t) << "\n"; 20 | } 21 | return 0; 22 | } -------------------------------------------------------------------------------- /PAT/Advanced Level/1047. Student List for Course.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | gg ni, ki; 8 | cin >> ni >> ki; 9 | vector> course(ki + 1); 10 | vector names; 11 | for (gg i = 0; i < ni; ++i) { 12 | string si; 13 | gg ci, ai; 14 | cin >> si >> ci; 15 | names.push_back(si); 16 | while (ci--) { 17 | cin >> ai; 18 | course[ai].push_back(i); 19 | } 20 | } 21 | for (gg i = 1; i <= ki; ++i) { 22 | cout << i << " " << course[i].size() << "\n"; 23 | sort(course[i].begin(), course[i].end(), 24 | [&names](gg a, gg b) { return names[a] < names[b]; }); 25 | for (auto& s : course[i]) { 26 | cout << names[s] << "\n"; 27 | } 28 | } 29 | return 0; 30 | } -------------------------------------------------------------------------------- /PAT/Advanced Level/1050. String Subtraction.md: -------------------------------------------------------------------------------- 1 | # 【PAT A-1050】String Subtraction 2 | 3 | ## 题意概述 4 | 5 | 给出两个字符串$S_1$和$S_2$,我们定义$S=S_1-S_2$,其中 S 为将$S_2$中所有字符从$S_1$中删除后的剩余字符。要求输出 S。 6 | 7 | ## 输入输出格式 8 | 9 | 输入两行字符串,分别为$S_1$和$S_2$。 10 | 11 | 输出$S_1-S_2$。 12 | 13 | ## 数据规模 14 | 15 | $S_1$和$S_2$的长度不会超过${10}^4$。 16 | 17 | ## 算法设计 18 | 19 | 将$S_2$的所有字符放入`unordered_set`做记录,遍历$S_1$,将未出现在 unordered_set 中的字符进行输出即可。 20 | 21 | ## C++代码 22 | 23 | ```cpp 24 | #include 25 | using namespace std; 26 | using gg = long long; 27 | int main() { 28 | ios::sync_with_stdio(false); 29 | cin.tie(0); 30 | string s1, s2; 31 | getline(cin, s1); 32 | getline(cin, s2); 33 | unordered_set us(s2.begin(), s2.end()); 34 | for (char c : s1) { 35 | if (not us.count(c)) { 36 | cout << c; 37 | } 38 | } 39 | return 0; 40 | } 41 | ``` 42 | -------------------------------------------------------------------------------- /PAT/Advanced Level/1051. Pop Sequence.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | gg mi, ni, ki; 8 | cin >> mi >> ni >> ki; 9 | vector seq(ni); 10 | while (ki--) { 11 | for (gg i = 0; i < ni; ++i) { 12 | cin >> seq[i]; 13 | } 14 | gg cur = 1; 15 | stack st; 16 | for (gg i : seq) { 17 | while (cur <= ni and st.size() < mi and 18 | (st.empty() or st.top() < i)) { 19 | st.push(cur++); 20 | } 21 | if (st.empty() or st.top() != i) { 22 | cout << "NO\n"; 23 | goto loop; 24 | } 25 | st.pop(); 26 | } 27 | cout << "YES\n"; 28 | loop:; 29 | } 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /PAT/Advanced Level/1054. The Dominant Color.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | gg mi, ni, ai; 8 | cin >> mi >> ni; 9 | unordered_map um; 10 | for (gg i = 0; i < mi * ni; ++i) { 11 | cin >> ai; 12 | ++um[ai]; 13 | } 14 | for (auto& i : um) { 15 | if (i.second * 2 > mi * ni) { 16 | cout << i.first; 17 | } 18 | } 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /PAT/Advanced Level/1059. Prime Factors.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | map factor; //质因子按升序排序,这里要使用map 5 | vector prime; 6 | void getPrime(gg n = gg(1e5)) { 7 | vector f(n + 5); 8 | for (gg i = 2; i <= n; ++i) 9 | if (not f[i]) { 10 | prime.push_back(i); 11 | for (gg j = i + i; j <= n; j += i) 12 | f[j] = true; 13 | } 14 | } 15 | void getFactor(gg n) { 16 | getPrime(); 17 | for (gg i : prime) { 18 | while (n % i == 0) { 19 | ++factor[i]; 20 | n /= i; 21 | } 22 | if (n == 1) 23 | break; 24 | } 25 | } 26 | int main() { 27 | ios::sync_with_stdio(false); 28 | cin.tie(0); 29 | gg ni; 30 | cin >> ni; 31 | if (ni == 1) { // N==1时要进行特判断 32 | cout << "1=1"; 33 | return 0; 34 | } 35 | getFactor(ni); 36 | cout << ni << "="; 37 | for (auto i = factor.begin(); i != factor.end(); ++i) { 38 | cout << (i == factor.begin() ? "" : "*") << i->first; 39 | if (i->second > 1) { 40 | cout << "^" << i->second; 41 | } 42 | } 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /PAT/Advanced Level/1060. Are They Equal.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | //返回n位有效数字和指数 5 | pair f(const string& s, gg n) { 6 | string ans; 7 | gg i = find_if(s.begin(), s.end(), 8 | [](char c) { return isdigit(c) and c != '0'; }) - 9 | s.begin(); //查找第一位非0数字的位置 10 | if (i == s.size()) { //输入的数字都是0,说明这个数字的值就是0 11 | return {string(n, '0'), 0}; 12 | } 13 | for (gg j = i; j < s.size(); ++j) { //将最多n位有效数字放入ans中 14 | if (ans.size() < n and isdigit(s[j])) { 15 | ans.push_back(s[j]); 16 | } 17 | } 18 | ans += string(n - ans.size(), '0'); //有效数字不足n位,末位补0 19 | gg num = s.find('.'); //小数点的位置 20 | if (num == -1) { 21 | num = s.size(); 22 | } 23 | //如果num-i是负数,指数是num-i+1,否则为num-i 24 | return {ans, num - i > 0 ? num - i : num - i + 1}; 25 | } 26 | int main() { 27 | ios::sync_with_stdio(false); 28 | cin.tie(0); 29 | string s1, s2; 30 | gg ni; 31 | cin >> ni >> s1 >> s2; 32 | auto ans1 = f(s1, ni), ans2 = f(s2, ni); 33 | if (ans1 == ans2) { 34 | cout << "YES 0." << ans1.first << "*10^" << ans1.second << "\n"; 35 | } else { 36 | cout << "NO 0." << ans1.first << "*10^" << ans1.second << " 0." 37 | << ans2.first << "*10^" << ans2.second << "\n"; 38 | } 39 | return 0; 40 | } -------------------------------------------------------------------------------- /PAT/Advanced Level/1061. Dating.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | cout << setfill('0'); //输出用字符0填充 8 | // ABCDEFG七个字符到星期的映射 9 | unordered_map week = { 10 | {'A', "MON"}, {'B', "TUE"}, {'C', "WED"}, {'D', "THU"}, 11 | {'E', "FRI"}, {'F', "SAT"}, {'G', "SUN"}}; 12 | // 0~9、A~N到小时的映射 13 | unordered_map hour; 14 | for (gg i = 0; i < 24; ++i) 15 | hour.insert({i < 10 ? i + '0' : i - 10 + 'A', i}); 16 | string s1, s2; 17 | cin >> s1 >> s2; 18 | for (gg i = 0, c = 0; i < min(s1.size(), s2.size()); ++i) { 19 | if (s1[i] == s2[i] and c == 0 and week.count(s1[i])) { 20 | cout << week[s1[i]] << " "; 21 | ++c; 22 | } else if (s1[i] == s2[i] and c == 1 and hour.count(s1[i])) { 23 | cout << setw(2) << hour[s1[i]] << ':'; 24 | ++c; 25 | } 26 | } 27 | cin >> s1 >> s2; 28 | for (gg i = 0, c = 0; i < min(s1.size(), s2.size()); ++i) { 29 | if (s1[i] == s2[i] and isalpha(s1[i])) { 30 | cout << setw(2) << i; 31 | break; 32 | } 33 | } 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /PAT/Advanced Level/1062. Talent and Virtue.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | struct Student { 5 | gg id, de, cai, total, level; 6 | Student(gg i, gg d, gg c, gg le) : id(i), de(d), cai(c), level(le) { 7 | total = de + cai; 8 | } 9 | }; 10 | int main() { 11 | ios::sync_with_stdio(false); 12 | cin.tie(0); 13 | vector students; 14 | gg ni, li, hi, id, de, cai, level; 15 | cin >> ni >> li >> hi; 16 | cout << setfill('0'); 17 | while (ni--) { 18 | cin >> id >> de >> cai; 19 | if (de < li or cai < li) 20 | continue; 21 | if (de >= hi and cai >= hi) { 22 | level = 1; 23 | } else if (de >= hi and cai < hi) { 24 | level = 2; 25 | } else if (de < hi and cai < hi and de >= cai) { 26 | level = 3; 27 | } else { 28 | level = 4; 29 | } 30 | students.push_back(Student(id, de, cai, level)); 31 | } 32 | sort(students.begin(), students.end(), 33 | [](const Student& s1, const Student& s2) { 34 | return tie(s1.level, s2.total, s2.de, s1.id) < 35 | tie(s2.level, s1.total, s1.de, s2.id); 36 | }); 37 | cout << students.size() << '\n'; 38 | for (auto& s : students) { 39 | cout << setw(8) << s.id << ' ' << s.de << ' ' << s.cai << '\n'; 40 | } 41 | return 0; 42 | } 43 | -------------------------------------------------------------------------------- /PAT/Advanced Level/1064. Complete Binary Search Tree.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | vector tree(1005), in(1005); 5 | gg ni; 6 | void inOrder(gg root, gg& p) { 7 | if (root > ni) { 8 | return; 9 | } 10 | inOrder(root * 2, p); 11 | tree[root] = in[p++]; 12 | inOrder(root * 2 + 1, p); 13 | } 14 | int main() { 15 | ios::sync_with_stdio(false); 16 | cin.tie(0); 17 | cin >> ni; 18 | for (gg i = 0; i < ni; ++i) { 19 | cin >> in[i]; 20 | } 21 | sort(in.begin(), in.begin() + ni); 22 | gg p = 0; //标记当前要处理的数字在中根序列中的下标 23 | inOrder(1, p); 24 | for (gg i = 1; i <= ni; ++i) { 25 | cout << (i == 1 ? "" : " ") << tree[i]; 26 | } 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /PAT/Advanced Level/1065. A+B and C.md: -------------------------------------------------------------------------------- 1 | # 【PAT A-1065】 A+B and C (64bit) 2 | 3 | ## 题意概述 4 | 5 | 给出 3 个整数 A,B,C,问 A+B>C 是否成立。 6 | 7 | ## 输入输出格式 8 | 9 | 输入的第一行给出一个正整数 T,表示测试用例的数量。然后是 T 个测试用例,每个用例包含一行,其中包含三个整数 A,B 和 C,并用单个空格分隔。 10 | 11 | 对于每个测试用例,如果 A+B>C,输出一行`Case #X: true`;否则,输出一行`Case #X: false`,其中 X 是测试用例编号(从 1 开始)。 12 | 13 | ## 数据规模 14 | 15 | $$T<=10, -2^{63}<=A,B,C<=2^{63}$$ 16 | 17 | ## 算法设计 18 | 19 | 这种题目没什么太大意义。由于直接使用 long long 类型存储 A,B,C,在计算 A+B 有可能会造成数据溢出。我们考虑使用浮点数存储 A,B,C,但是由于 double 最多只能保存 15-16 位有效数字,用来存储 A,B,C 可能会有精度损失,我们可以使用精度更高的 long double 类型。 20 | 21 | ## C++代码 22 | 23 | ```cpp 24 | #include 25 | using namespace std; 26 | using gg = long long; 27 | int main() { 28 | ios::sync_with_stdio(false); 29 | cin.tie(0); 30 | gg t; 31 | cin >> t; 32 | for (gg i = 1; i <= t; i++) { 33 | long double a, b, c; 34 | cin >> a >> b >> c; 35 | cout << "Case #" << i << ": " << boolalpha << (a + b > c) << "\n"; 36 | } 37 | return 0; 38 | } 39 | ``` 40 | -------------------------------------------------------------------------------- /PAT/Advanced Level/1069. The Black Hole of Numbers.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | cout << setfill('0'); 8 | gg ni; 9 | cin >> ni; 10 | do { 11 | string s = to_string(ni); 12 | while (s.size() < 4) 13 | s.push_back('0'); 14 | sort(s.begin(), s.end()); 15 | gg a = stoll(s); 16 | sort(s.begin(), s.end(), greater()); 17 | gg b = stoll(s); 18 | ni = b - a; 19 | cout << setw(4) << b << " - " << setw(4) << a << " = " << setw(4) << ni 20 | << '\n'; 21 | } while (ni != 0 and ni != 6174); 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /PAT/Advanced Level/1070. Mooncake.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | gg ni, di; 8 | cin >> ni >> di; 9 | using ad2 = array; //存储月饼的库存量和总售价 10 | vector cakes(ni); 11 | for (gg i = 0; i < ni; ++i) 12 | cin >> cakes[i][0]; 13 | for (gg i = 0; i < ni; ++i) 14 | cin >> cakes[i][1]; 15 | //按单价从大到小排序 16 | sort(cakes.begin(), cakes.end(), [](const ad2& c1, const ad2& c2) { 17 | return c1[1] * 1.0 / c1[0] > c2[1] * 1.0 / c2[0]; 18 | }); 19 | double ans = 0.0; //存储最终收益 20 | for (auto& c : cakes) { 21 | if (di >= c[0]) { 22 | ans += c[1]; 23 | di -= c[0]; 24 | } else { 25 | ans += c[1] * 1.0 / c[0] * di; 26 | di = 0; 27 | } 28 | } 29 | cout << fixed << setprecision(2) << ans; 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /PAT/Advanced Level/1073. Scientific Notation.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | regex r("([+-])([1-9]).([0-9]+)E([+-])([0-9]+)"); 8 | string si; 9 | cin >> si; 10 | smatch result; 11 | regex_match(si, result, r); 12 | if (result.str(1) == "-") { //输入是负数要输出负号 13 | cout << result[1]; 14 | } 15 | gg n = stoll(result.str(5)); //获取指数的值 16 | if (result.str(4) == "-") { //小数点要左移n位,要在小数点后补n-1个0 17 | cout << "0." << string(n - 1, '0') << result[2] << result[3]; 18 | } else if (n < result.length(3)) { 19 | //小数点右移的位数不超过3号子串长度,将3号子串用小数点分隔开进行输出 20 | cout << result[2] << result.str(3).substr(0, n) << "." 21 | << result.str(3).substr(n); 22 | } else if (n == result.length(3)) { 23 | //小数点右移的位数等于3号子字符串长度,小数点无需输出 24 | cout << result[2] << result[3]; 25 | } else { 26 | //小数点右移的位数超过3号子串长度,在3号子串后补0 27 | cout << result[2] << result[3] << string(n - result.length(3), '0'); 28 | } 29 | return 0; 30 | } -------------------------------------------------------------------------------- /PAT/Advanced Level/1074. Reversing Linked List.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | vector> input(gg(1e6), {-1, -1}); 8 | gg start, ni, ki; 9 | cin >> start >> ni >> ki; 10 | for (gg i = 0; i < ni; ++i) { 11 | gg address, data, nextA; 12 | cin >> address >> data >> nextA; 13 | input[address] = {data, nextA}; 14 | } 15 | vector lst; 16 | while (start != -1) { 17 | lst.push_back(start); 18 | start = input[start][1]; 19 | } 20 | for (gg i = ki; i <= lst.size(); i += ki) { 21 | reverse(lst.begin() + i - ki, lst.begin() + i); 22 | } 23 | cout << setfill('0'); 24 | for (gg i = 0; i < lst.size() - 1; ++i) { 25 | cout << setw(5) << lst[i] << " " << input[lst[i]][0] << " " << setw(5) 26 | << lst[i + 1] << "\n"; 27 | } 28 | cout << setw(5) << lst.back() << " " << input[lst.back()][0] << " -1\n"; 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /PAT/Advanced Level/1077. Kuchiguse.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | gg ni, m = INT_MAX; 8 | cin >> ni; 9 | cin.get(); 10 | vector v(ni); 11 | string ans; 12 | for (auto& i : v) { 13 | getline(cin, i); 14 | reverse(i.begin(), i.end()); 15 | m = min(m, (gg)i.size()); 16 | } 17 | for (gg i = 0; i < m; ++i) { 18 | for (auto& j : v) { 19 | if (j[i] != v[0][i]) { 20 | goto loop; 21 | } 22 | } 23 | ans.push_back(v[0][i]); 24 | } 25 | loop: 26 | reverse(ans.begin(), ans.end()); 27 | cout << (ans.empty() ? "nai" : ans); 28 | return 0; 29 | } -------------------------------------------------------------------------------- /PAT/Advanced Level/1083. List Grades.md: -------------------------------------------------------------------------------- 1 | # 【PAT A-1083】List Grades 2 | 3 | ## 题意概述 4 | 5 | 给出 N 个学生的名称,ID 和成绩。输出成绩在给定区间内的学生信息。题目保证给出的学生成绩都是唯一的。 6 | 7 | ## 输入输出格式 8 | 9 | 输入第一行包含 1 个正整数:N,表示学生总数。之后 N 行,每行按`姓名 ID 成绩`的格式给出 N 个学生的信息。最后一行给出两个正整数 grade1 和 grade2。 10 | 11 | 按成绩降序的标准,输出在[grade1,grade2]区间内的所有学生的姓名和 ID。如果没有学生成绩在这个区间内,输出`NONE`。 12 | 13 | ## 算法设计 14 | 15 | 先定义一个类 Student,其中应该包括以下几种数据成员:姓名 name、id、成绩 grade。按成绩从高到低对所有学生排序。遍历所有的学生,输出在指定区间内学生的姓名和 ID 即可。 16 | 17 | ## C++代码 18 | 19 | ```cpp 20 | #include 21 | using namespace std; 22 | using gg = long long; 23 | struct Student { 24 | string name, id; 25 | gg grade; 26 | }; 27 | int main() { 28 | ios::sync_with_stdio(false); 29 | cin.tie(0); 30 | gg ni, g1, g2; 31 | cin >> ni; 32 | vector stu(ni); 33 | for (auto& i : stu) { 34 | cin >> i.name >> i.id >> i.grade; 35 | } 36 | sort(stu.begin(), stu.end(), [](const Student& s1, const Student& s2) { 37 | return s1.grade > s2.grade; 38 | }); 39 | cin >> g1 >> g2; 40 | bool f = false; 41 | for (auto& s : stu) { 42 | if (s.grade >= g1 and s.grade <= g2) { 43 | cout << s.name << " " << s.id << "\n"; 44 | f = true; 45 | } 46 | } 47 | if (not f) 48 | cout << "NONE"; 49 | return 0; 50 | } 51 | ``` 52 | -------------------------------------------------------------------------------- /PAT/Advanced Level/1084. Broken Keyboard.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int main() { 4 | ios::sync_with_stdio(false); 5 | cin.tie(0); 6 | string s1, s2; 7 | cin >> s1 >> s2; 8 | vector h(128); //哈希表 9 | for (char c : s2) 10 | h[toupper(c)] = true; 11 | for (char c : s1) { 12 | if (not h[toupper(c)]) { 13 | cout << (char)toupper(c); 14 | h[toupper(c)] = true; //保证坏掉的键只输出一次 15 | } 16 | } 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /PAT/Advanced Level/1085. Perfect Sequence.cpp: -------------------------------------------------------------------------------- 1 | //二分查找 2 | #include 3 | using namespace std; 4 | using gg = long long; 5 | int main() { 6 | ios::sync_with_stdio(false); 7 | cin.tie(0); 8 | gg ni, pi, ans = 0; 9 | cin >> ni >> pi; 10 | vector v(ni); 11 | for (gg i = 0; i < ni; ++i) { 12 | cin >> v[i]; 13 | } 14 | sort(v.begin(), v.end()); 15 | for (gg i = 0; i < ni; ++i) { 16 | ans = max(ans, 17 | upper_bound(v.begin(), v.end(), v[i] * pi) - v.begin() - i); 18 | } 19 | cout << ans; 20 | return 0; 21 | } 22 | // two pointers 23 | #include 24 | using namespace std; 25 | using gg = long long; 26 | int main() { 27 | ios::sync_with_stdio(false); 28 | cin.tie(0); 29 | gg ni, pi, ans = 0; 30 | cin >> ni >> pi; 31 | vector v(ni); 32 | for (gg i = 0; i < ni; ++i) { 33 | cin >> v[i]; 34 | } 35 | sort(v.begin(), v.end()); 36 | for (gg i = 0, j = 0; j < v.size(); ++i) { 37 | while (j < v.size() and v[j] <= v[i] * pi) { 38 | ++j; 39 | } 40 | ans = max(ans, j - i); 41 | } 42 | cout << ans; 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /PAT/Advanced Level/1086. Tree Traversals Again.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | void getPostFromPreIn(vector& pre, vector& in, gg r, gg left, gg right) { 5 | if (left > right) //序列为空,直接返回 6 | return; 7 | gg i = find(in.begin(), in.end(), pre[r]) - in.begin(); 8 | getPostFromPreIn(pre, in, r + 1, left, i - 1); //递归遍历左子树 9 | getPostFromPreIn(pre, in, r + 1 + i - left, i + 1, right); //递归遍历右子树 10 | cout << pre[r] << (r == 0 ? "" : " "); // r==0时为整棵树的根结点,后面不能有空格 11 | } 12 | int main() { 13 | ios::sync_with_stdio(false); 14 | cin.tie(0); 15 | gg ni, ai; 16 | cin >> ni; 17 | string si; 18 | stack st; 19 | vector pre, in; 20 | for (gg i = 0; i < 2 * ni; ++i) { 21 | cin >> si; 22 | if (si == "Push") { 23 | cin >> ai; 24 | st.push(ai); 25 | pre.push_back(ai); 26 | } else { 27 | in.push_back(st.top()); 28 | st.pop(); 29 | } 30 | } 31 | getPostFromPreIn(pre, in, 0, 0, in.size() - 1); 32 | return 0; 33 | } -------------------------------------------------------------------------------- /PAT/Advanced Level/1092. To Buy or Not to Buy.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | string s1, s2; 8 | getline(cin, s1); 9 | getline(cin, s2); 10 | array h{}; 11 | for (char c : s1) 12 | ++h[c]; 13 | for (char c : s2) 14 | --h[c]; 15 | gg k1 = 0, k2 = 0; // k1记录多余的珠子数,k2记录少的珠子数 16 | for (int i : h) { 17 | i > 0 ? k1 += i : k2 -= i; 18 | } 19 | k2 > 0 ? cout << "No " << k2 : cout << "Yes " << k1; 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /PAT/Advanced Level/1096. Consecutive Factors.md: -------------------------------------------------------------------------------- 1 | # 【PAT A-1096】Consecutive Factors 2 | ## 题意概述 3 | 在正整数N的所有因子中,可能存在几个连续的数字。例如,630可以分解为3×5×6×7,其中5、6和7是三个连续的数字。现在给定任何正数N,您应该找到最大数量的连续因子,并列出连续因子的最小序列。 4 | ## 输入输出格式 5 | 输入在一行给出正整数N。 6 | 7 | 对于每个测试用例,请在第一行中打印最大连续因子数。然后在第二行中,以格式`factor [1] * factor [2] * ... * factor [k]`来打印连续因子的最小序列,其中因子以升序排列,注意,因子中不应包含1。 8 | ## 数据规模 9 | $$0 15 | using namespace std; 16 | using gg = long long; 17 | int main() { 18 | ios::sync_with_stdio(false); 19 | cin.tie(0); 20 | gg ni; 21 | cin >> ni; 22 | gg num = 1, first = ni; 23 | for (gg i = 2; i <= (gg)sqrt(ni); ++i) { 24 | if (ni % i == 0) { 25 | gg n = ni, curnum = 0; 26 | for (gg j = i; n % j == 0; ++j) { 27 | n /= j; 28 | ++curnum; 29 | } 30 | if (curnum > num or (curnum == num and first > i)) { 31 | num = curnum; 32 | first = i; 33 | } 34 | } 35 | } 36 | cout << num << "\n"; 37 | for (gg i = 0; i < num; ++i) { 38 | cout << (i == 0 ? "" : "*") << first + i; 39 | } 40 | return 0; 41 | } 42 | ``` -------------------------------------------------------------------------------- /PAT/Advanced Level/1099. Build A Binary Search Tree.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | const gg MAX = 105; 5 | struct Node { 6 | gg val, left = -1, right = -1; 7 | }; 8 | vector tree(MAX); 9 | vector in(MAX); 10 | gg ni; 11 | void inOrder(gg root, gg& p) { 12 | if (root == -1) { 13 | return; 14 | } 15 | inOrder(tree[root].left, p); 16 | tree[root].val = in[p++]; 17 | inOrder(tree[root].right, p); 18 | } 19 | void levelOrder(gg root) { 20 | queue q; 21 | q.push(root); 22 | while (not q.empty()) { 23 | auto t = q.front(); 24 | q.pop(); 25 | cout << (t == 0 ? "" : " ") << tree[t].val; 26 | if (tree[t].left != -1) 27 | q.push(tree[t].left); 28 | if (tree[t].right != -1) 29 | q.push(tree[t].right); 30 | } 31 | } 32 | int main() { 33 | ios::sync_with_stdio(false); 34 | cin.tie(0); 35 | cin >> ni; 36 | for (gg i = 0; i < ni; ++i) { 37 | cin >> tree[i].left >> tree[i].right; 38 | } 39 | for (gg i = 0; i < ni; ++i) { 40 | cin >> in[i]; 41 | } 42 | sort(in.begin(), in.begin() + ni); 43 | gg p = 0; //标记当前要处理的数字在中根序列中的下标 44 | inOrder(0, p); 45 | levelOrder(0); 46 | return 0; 47 | } 48 | -------------------------------------------------------------------------------- /PAT/Advanced Level/1102. Invert a Binary Tree.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | const gg MAX = 15; 5 | gg ni; 6 | vector> tree(MAX, {-1, -1}); 7 | void inOrder(gg root, gg& n) { 8 | if (root == -1) 9 | return; 10 | inOrder(tree[root][0], n); 11 | cout << root << (++n == ni ? "\n" : " "); 12 | inOrder(tree[root][1], n); 13 | } 14 | void levelOrder(gg root) { 15 | queue q; 16 | q.push(root); 17 | gg n = 0; 18 | while (not q.empty()) { 19 | auto t = q.front(); 20 | q.pop(); 21 | cout << t << (++n == ni ? "\n" : " "); 22 | if (tree[t][0] != -1) 23 | q.push(tree[t][0]); 24 | if (tree[t][1] != -1) 25 | q.push(tree[t][1]); 26 | } 27 | } 28 | int main() { 29 | ios::sync_with_stdio(false); 30 | cin.tie(0); 31 | cin >> ni; 32 | string s1, s2; 33 | vector f(ni); 34 | for (gg i = 0; i < ni; ++i) { 35 | cin >> s1 >> s2; 36 | if (s1 != "-") { 37 | tree[i][1] = stoll(s1); 38 | f[stoll(s1)] = true; 39 | } 40 | if (s2 != "-") { 41 | tree[i][0] = stoll(s2); 42 | f[stoll(s2)] = true; 43 | } 44 | } 45 | gg root = find(f.begin(), f.end(), false) - f.begin(); 46 | levelOrder(root); 47 | gg n = 0; 48 | inOrder(root, n); 49 | return 0; 50 | } 51 | -------------------------------------------------------------------------------- /PAT/Advanced Level/1105. Spiral Matrix.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | gg m, n, ni; 8 | cin >> ni; 9 | vector ai(ni); 10 | for (gg& i : ai) { 11 | cin >> i; 12 | } 13 | sort(ai.begin(), ai.end(), greater()); 14 | for (n = gg(sqrt(ni)); n > 0; --n) { //枚举n 15 | if (ni % n == 0) { 16 | m = ni / n; 17 | break; 18 | } 19 | } 20 | vector> ans(m, vector(n)); 21 | vector> direc{{0, 1}, {1, 0}, {0, -1}, {-1, 0}}; //方向 22 | gg d = 0, x = 0, y = 0; 23 | for (gg i = 0; i < ni; ++i) { 24 | ans[x][y] = ai[i]; //填充 25 | gg nx = x + direc[d][0], ny = y + direc[d][1]; 26 | if (nx >= 0 and nx < m and ny >= 0 and ny < n and ans[nx][ny] == 0) { 27 | x = nx, y = ny; 28 | } else { 29 | d = (d + 1) % 4; 30 | x += direc[d][0], y += direc[d][1]; 31 | } 32 | } 33 | for (auto& i : ans) { 34 | for (gg j = 0; j < i.size(); ++j) { 35 | cout << (j == 0 ? "" : " ") << i[j]; 36 | } 37 | cout << "\n"; 38 | } 39 | return 0; 40 | } -------------------------------------------------------------------------------- /PAT/Advanced Level/1107. Social Clusters.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | const gg MAX = 1e3 + 5; 5 | vector ufs(MAX), num(MAX); 6 | void init() { iota(ufs.begin(), ufs.end(), 0); } 7 | gg findRoot(gg x) { return ufs[x] == x ? x : ufs[x] = findRoot(ufs[x]); } 8 | void unionSets(gg a, gg b) { ufs[findRoot(a)] = findRoot(b); } 9 | int main() { 10 | ios::sync_with_stdio(false); 11 | cin.tie(0); 12 | gg ni, ki, ai; 13 | char c; 14 | cin >> ni; 15 | unordered_map hobby; 16 | init(); 17 | for (gg i = 1; i <= ni; ++i) { 18 | cin >> ki >> c; 19 | while (ki--) { 20 | cin >> ai; 21 | if (hobby.count(ai)) { 22 | unionSets(hobby[ai], i); 23 | } else { 24 | hobby[ai] = i; 25 | } 26 | } 27 | } 28 | for (gg i = 1; i <= ni; ++i) { 29 | num[findRoot(i)]++; 30 | } 31 | sort(num.begin(), num.begin() + ni + 2, greater()); 32 | gg n = find(num.begin(), num.begin() + ni + 2, 0) - num.begin(); 33 | cout << n << "\n"; 34 | for (gg i = 0; i < n; ++i) { 35 | cout << (i == 0 ? "" : " ") << num[i]; 36 | } 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /PAT/Advanced Level/1108. Finding Average.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | gg ni, num = 0; 8 | cin >> ni; 9 | string si; 10 | double sum = 0; 11 | regex r("[+-]?\\d+(\\.\\d{0,2})?"); 12 | while (ni--) { 13 | cin >> si; 14 | if (not regex_match(si, r) or stod(si) > 1000 or stod(si) < -1000) { 15 | cout << "ERROR: " << si << " is not a legal number\n"; 16 | } else { 17 | ++num; 18 | sum += stod(si); 19 | } 20 | } 21 | cout << fixed << setprecision(2); 22 | if (num == 0) { 23 | cout << "The average of 0 numbers is Undefined"; 24 | } else if (num == 1) { 25 | cout << "The average of 1 number is " << sum; 26 | } else { 27 | cout << "The average of " << num << " numbers is " << sum / num; 28 | } 29 | return 0; 30 | } -------------------------------------------------------------------------------- /PAT/Advanced Level/1112. Stucked Keyboard.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | gg ki; 8 | string si; 9 | cin >> ki >> si; 10 | array h{}; 11 | for (gg i = 0; i < si.size();) { 12 | if (h[si[i]] != -1) { //无需检测已确定不是坏键的字符 13 | gg j = si.find_first_not_of(si[i], i + 1); 14 | if (j == -1) { 15 | j = si.size(); 16 | } 17 | h[si[i]] = (j - i) % ki != 0 ? -1 : 1; //检测重复次数是否为K的倍数 18 | i = j; 19 | } else { 20 | ++i; 21 | } 22 | } 23 | string ans; 24 | for (gg i = 0; i < si.size();) { 25 | ans.push_back(si[i]); 26 | if (h[si[i]] == -1) { 27 | ++i; 28 | continue; 29 | } 30 | if (h[si[i]] == 1) { //是坏键且未输出过 31 | cout << si[i]; 32 | h[si[i]] = 2; 33 | } 34 | i += ki; 35 | } 36 | cout << "\n" << ans; 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /PAT/Advanced Level/1113. Integer Set Partition.md: -------------------------------------------------------------------------------- 1 | # 【PAT A-1113】Integer Set Partition 2 | 3 | ## 题意概述 4 | 5 | 给定一组 N 个正整数,您应该将它们划分为两个不相交的集合$A_1$和$A_2$。假设$A_1$和$A_2$分别有$n_1$和$n_2$个数字,和分别为$S_1$和$S_2$。如何划分这两个集合,以便保证在$\left|n_1-n_2\right|$最小化的基础上,让$\left|S_1-S_2\right|$最大化? 6 | 7 | ## 输入输出格式 8 | 9 | 输入第一行中先给出一个正整数 N。第二行给出 N 个正整数。 10 | 11 | 在一行中输出$|n_1-n_2|$和$\left|S_1-S_2\right|$。 12 | 13 | ## 算法设计 14 | 15 | 先把给定的序列进行排序,则前$\lfloor n/2 \rfloor$个元素为集合$A_1$,其余元素为集合$A_2$,输出$\left|n_1-n_2\right|$和$\left|S_1-S_2\right|$即可。 16 | 17 | ## C++代码 18 | 19 | ```cpp 20 | #include 21 | using namespace std; 22 | using gg = long long; 23 | int main() { 24 | ios::sync_with_stdio(false); 25 | cin.tie(0); 26 | gg ni; 27 | cin >> ni; 28 | vector v(ni); 29 | for (gg& i : v) { 30 | cin >> i; 31 | } 32 | sort(v.begin(), v.end()); 33 | cout << (ni % 2) << " " 34 | << abs(accumulate(v.begin(), v.begin() + ni / 2, 0) - 35 | accumulate(v.begin() + ni / 2, v.end(), 0)); 36 | return 0; 37 | } 38 | ``` 39 | -------------------------------------------------------------------------------- /PAT/Advanced Level/1115. Counting Nodes in a BST.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | vector level; 5 | struct BTNode { 6 | gg val; 7 | BTNode *left, *right; 8 | BTNode(gg v, BTNode* l = nullptr, BTNode* r = nullptr) : 9 | val(v), left(l), right(r) {} 10 | }; 11 | void insertElement(BTNode*& root, gg x) { 12 | if (not root) { //根结点为空,新建一个结点 13 | root = new BTNode(x); 14 | } else if (x <= root->val) { //向左子树中插入 15 | insertElement(root->left, x); 16 | } else { //向右子树中插入 17 | insertElement(root->right, x); 18 | } 19 | } 20 | void preOrder(BTNode* root, gg depth) { 21 | if (not root) 22 | return; 23 | if (level.size() <= depth) 24 | level.push_back(0); 25 | ++level[depth]; 26 | preOrder(root->left, depth + 1); 27 | preOrder(root->right, depth + 1); 28 | } 29 | int main() { 30 | ios::sync_with_stdio(false); 31 | cin.tie(0); 32 | BTNode* root = nullptr; 33 | gg ni, ai; 34 | cin >> ni; 35 | while (ni--) { 36 | cin >> ai; 37 | insertElement(root, ai); 38 | } 39 | preOrder(root, 0); 40 | gg k1 = level.back(), k2 = level.size() > 1 ? level[level.size() - 2] : 0; 41 | cout << k1 << " + " << k2 << " = " << (k1 + k2); 42 | return 0; 43 | } -------------------------------------------------------------------------------- /PAT/Advanced Level/1116. Come on! Let's C.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | bool isPrime(gg n) { 5 | for (gg i = 2; i <= (gg)sqrt(n); ++i) 6 | if (n % i == 0) 7 | return false; 8 | return true; 9 | } 10 | int main() { 11 | ios::sync_with_stdio(false); 12 | cin.tie(0); 13 | gg ni, ki; 14 | string si; 15 | cin >> ni; 16 | unordered_map um; 17 | for (gg i = 1; i <= ni; ++i) { 18 | cin >> si; 19 | um[si] = i == 1 ? "Mystery Award" : isPrime(i) ? "Minion" : "Chocolate"; 20 | } 21 | cin >> ki; 22 | while (ki--) { 23 | cin >> si; 24 | cout << si << ": " << (um.count(si) ? um[si] : "Are you kidding?") 25 | << "\n"; 26 | if (um.count(si)) { 27 | um[si] = "Checked"; 28 | } 29 | } 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /PAT/Advanced Level/1118. Birds in Forest.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | const gg MAX = 1e4 + 5; 5 | vector ufs(MAX), num(MAX); 6 | void init() { iota(ufs.begin(), ufs.end(), 0); } 7 | gg findRoot(gg x) { return ufs[x] == x ? x : ufs[x] = findRoot(ufs[x]); } 8 | void unionSets(gg a, gg b) { ufs[findRoot(a)] = findRoot(b); } 9 | int main() { 10 | ios::sync_with_stdio(false); 11 | cin.tie(0); 12 | gg ni, ki, ai, bi, treeNum = 0, birdNum = 0; 13 | cin >> ni; 14 | init(); 15 | while (ni--) { 16 | cin >> ki >> ai; 17 | birdNum = max(birdNum, ai); 18 | while (--ki) { 19 | cin >> bi; 20 | unionSets(ai, bi); 21 | birdNum = max(birdNum, bi); 22 | } 23 | } 24 | for (gg i = 1; i <= birdNum; ++i) { 25 | if (i == ufs[i]) { 26 | ++treeNum; 27 | } 28 | } 29 | cout << treeNum << " " << birdNum << "\n"; 30 | cin >> ki; 31 | while (ki--) { 32 | cin >> ai >> bi; 33 | cout << (findRoot(ai) == findRoot(bi) ? "Yes" : "No") << "\n"; 34 | } 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /PAT/Advanced Level/1120. Friend Numbers.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | gg ni; 8 | set s; 9 | cin >> ni; 10 | while (ni--) { 11 | gg sum = 0, ai; 12 | cin >> ai; 13 | do { 14 | sum += ai % 10; 15 | ai /= 10; 16 | } while (ai != 0); 17 | s.insert(sum); 18 | } 19 | cout << s.size() << '\n'; 20 | for (auto i = s.begin(); i != s.end(); ++i) { 21 | cout << (i == s.begin() ? "" : " ") << *i; 22 | } 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /PAT/Advanced Level/1121. Damn Single.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | unordered_map um; //记录配偶ID 8 | gg ni, ai, bi; 9 | cin >> ni; 10 | while (ni--) { 11 | cin >> ai >> bi; 12 | um[ai] = bi; 13 | um[bi] = ai; 14 | } 15 | cin >> ni; 16 | set s; //记录是否出现在派对上并排序 17 | while (ni--) { 18 | cin >> ai; 19 | if (not um.count(ai) or not s.count(um[ai])) { 20 | s.insert(ai); 21 | } else { 22 | s.erase(um[ai]); 23 | } 24 | } 25 | cout << s.size() << '\n' << setfill('0'); 26 | for (auto i = s.begin(); i != s.end(); ++i) { 27 | cout << (i == s.begin() ? "" : " ") << setw(5) << *i; 28 | } 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /PAT/Advanced Level/1122. Hamiltonian Cycle.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | gg ni, mi, ki; 8 | cin >> ni >> mi; 9 | vector> graph(ni + 1, vector(ni + 1)); 10 | while (mi--) { 11 | gg ai, bi; 12 | cin >> ai >> bi; 13 | graph[ai][bi] = graph[bi][ai] = true; 14 | } 15 | cin >> mi; 16 | while (mi--) { 17 | bool ans = true; //标记是否是哈密顿环 18 | cin >> ki; 19 | vector v(ki); 20 | unordered_set us; //记录环中出现的顶点编号 21 | for (gg& i : v) { 22 | cin >> i; 23 | us.insert(i); 24 | } 25 | if (ki != ni + 1 or v[0] != v.back() or us.size() != ni) { 26 | ans = false; 27 | } 28 | //判断环中每两个相邻结点之间是否有边 29 | for (gg i = 0; i < ki - 1; ++i) { 30 | if (not graph[v[i]][v[i + 1]]) { 31 | ans = false; 32 | } 33 | } 34 | cout << (ans ? "YES" : "NO") << "\n"; 35 | } 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /PAT/Advanced Level/1124. Raffle for Weibo Followers.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | gg mi, ni, si; 8 | cin >> mi >> ni >> si; 9 | vector v(mi + 1); 10 | for (int i = 1; i < v.size(); ++i) 11 | cin >> v[i]; 12 | unordered_set us; //标志一个人已中过奖 13 | for (int i = si; i < v.size(); i += ni) { 14 | while (i < v.size() and us.count(v[i])) //中过奖则顺取下一位 15 | ++i; 16 | if (i < v.size()) { 17 | cout << v[i] << '\n'; 18 | us.insert(v[i]); 19 | } 20 | } 21 | if (us.empty()) //没有人中过奖 22 | cout << "Keep going..."; 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /PAT/Advanced Level/1125. Chain the Ropes.md: -------------------------------------------------------------------------------- 1 | # 【PAT A-1125、PAT B-1070】Chain the Ropes、结绳 2 | 3 | ## 题意概述 4 | 5 | 给定一段一段的绳子,你需要把它们串成一条绳。每次串连的时候,是把两段绳子对折,再套接在一起。这样得到的绳子又被当成是另一段绳子,可以再次对折去跟另一段绳子串连。每次串连后,原来两段绳子的长度就会减半。给定 N 段绳子的长度,你需要找出它们能串成的绳子的最大长度。 6 | 7 | ## 输入输出格式 8 | 9 | 输入第 1 行给出正整数 N。第 2 行给出 N 个正整数,即原始绳段的长度,数字间以空格分隔。所有整数都不超过${10}^4$。 10 | 11 | 输出能串成的绳子的最大长度。 12 | 13 | ## 数据规模 14 | 15 | $$2\le N\le{10}^4$$ 16 | 17 | ## 算法设计 18 | 19 | 由于每次串连的时候都需要将两根绳子对折,所以越是先串连的绳子对折次数越多,因此为了保证最后的长度最长,串连的绳子中长度越长的就应该越晚串连。于是我们只需要按长度将给定的绳子从小到大排序,按题目描述逐个绳子进行串连,得到的长度必然是最长的。这里我们使用的贪心策略就是:先串连长度短的绳子,再串连长度长的绳子。 20 | 21 | ## 注意点 22 | 23 | 1. 当串联第一根绳子时不用对折。 24 | 2. 为了保证结果的精度,最好用 double 储存输入的绳子长度,最后对结果进行向下取整,这样在对折取半时就不会丧失精度。 25 | 26 | ## C++代码 27 | 28 | ```cpp 29 | #include 30 | using namespace std; 31 | using gg = long long; 32 | int main() { 33 | ios::sync_with_stdio(false); 34 | cin.tie(0); 35 | gg n; 36 | cin >> n; 37 | vector v(n); 38 | for (int i = 0; i < n; ++i) 39 | cin >> v[i]; 40 | sort(v.begin(), v.end()); 41 | cout << floor(accumulate(v.begin() + 1, v.end(), v[0], 42 | [](double a, double b) { return (a + b) / 2; })); 43 | return 0; 44 | } 45 | ``` 46 | -------------------------------------------------------------------------------- /PAT/Advanced Level/1126. Eulerian Path.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | const gg MAX = 505; 5 | vector> graph(505); 6 | vector visit(505); 7 | void dfs(gg v) { 8 | visit[v] = true; 9 | for (gg i : graph[v]) { 10 | if (not visit[i]) { 11 | dfs(i); 12 | } 13 | } 14 | } 15 | int main() { 16 | ios::sync_with_stdio(false); 17 | cin.tie(0); 18 | gg ni, mi; 19 | cin >> ni >> mi; 20 | while (mi--) { 21 | gg ai, bi; 22 | cin >> ai >> bi; 23 | graph[ai].push_back(bi); 24 | graph[bi].push_back(ai); 25 | } 26 | dfs(1); 27 | gg vis = count(visit.begin() + 1, visit.begin() + ni + 1, false), 28 | num = count_if(graph.begin() + 1, graph.begin() + ni + 1, 29 | [](vector&a) { return a.size() % 2 == 1; }); 30 | for (gg i = 1; i <= ni; ++i) { 31 | cout << graph[i].size() << (i == ni ? "\n" : " "); 32 | } 33 | cout << (vis != 0 or (num != 0 and num != 2) ? 34 | "Non-Eulerian" : 35 | num == 0 ? "Eulerian" : "Semi-Eulerian"); 36 | return 0; 37 | } -------------------------------------------------------------------------------- /PAT/Advanced Level/1128. N Queens Puzzle.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | gg ni, ki; 8 | cin >> ki; 9 | while (ki--) { 10 | cin >> ni; 11 | vector v(ni); 12 | for (gg& i : v) { 13 | cin >> i; 14 | } 15 | for (gg i = 0; i < v.size(); ++i) { 16 | for (gg j = i + 1; j < v.size(); ++j) { 17 | if (v[j] == v[i] or abs(j - i) == abs(v[j] - v[i])) { 18 | cout << "NO\n"; 19 | goto loop; 20 | } 21 | } 22 | } 23 | cout << "YES\n"; 24 | loop:; 25 | } 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /PAT/Advanced Level/1130. Infix Expression.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | struct BTNode { 5 | string val; 6 | gg left, right; 7 | }; 8 | vector tree(25); 9 | void inOrder(gg root, gg r) { 10 | if (root == -1) { 11 | return; 12 | } 13 | if (tree[root].left == -1 and tree[root].right == -1) { 14 | cout << tree[root].val; 15 | return; 16 | } 17 | if (root != r) { //最外层的表达式是没有括号的 18 | cout << "("; 19 | } 20 | inOrder(tree[root].left, r); 21 | cout << tree[root].val; 22 | inOrder(tree[root].right, r); 23 | if (root != r) { //最外层的表达式是没有括号的 24 | cout << ")"; 25 | } 26 | } 27 | int main() { 28 | ios::sync_with_stdio(false); 29 | cin.tie(0); 30 | gg ni; 31 | cin >> ni; 32 | vector f(ni + 1); 33 | for (gg i = 1; i <= ni; ++i) { 34 | cin >> tree[i].val >> tree[i].left >> tree[i].right; 35 | if (tree[i].left != -1) { 36 | f[tree[i].left] = true; 37 | } 38 | if (tree[i].right != -1) { 39 | f[tree[i].right] = true; 40 | } 41 | } 42 | gg root = find(f.begin() + 1, f.end(), false) - f.begin(); 43 | inOrder(root, root); 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /PAT/Advanced Level/1132. Cut Integer.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | gg ni, zi; 8 | cin >> ni; 9 | while (ni--) { 10 | cin >> zi; 11 | string s = to_string(zi); 12 | gg a = stoll(s.substr(0, s.size() / 2)), 13 | b = stoll(s.substr(s.size() / 2)); 14 | cout << (a * b != 0 and zi % (a * b) == 0 ? "Yes" : "No") << "\n"; 15 | } 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /PAT/Advanced Level/1133. Splitting A Linked List.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | vector> input(gg(1e6), {-1, -1}); 8 | gg start, ni, ki; 9 | cin >> start >> ni >> ki; 10 | for (gg i = 0; i < ni; ++i) { 11 | gg address, data, nextA; 12 | cin >> address >> data >> nextA; 13 | input[address] = {data, nextA}; 14 | } 15 | vector> lst(3); 16 | while (start != -1) { 17 | gg flag = input[start][0] < 0 ? 0 : input[start][0] > ki ? 2 : 1; 18 | lst[flag].push_back(start); 19 | start = input[start][1]; 20 | } 21 | lst[0].insert(lst[0].end(), lst[1].begin(), lst[1].end()); 22 | lst[0].insert(lst[0].end(), lst[2].begin(), lst[2].end()); 23 | cout << setfill('0'); 24 | for (gg i = 0; i < lst[0].size() - 1; ++i) { 25 | cout << setw(5) << lst[0][i] << " " << input[lst[0][i]][0] << " " 26 | << setw(5) << lst[0][i + 1] << "\n"; 27 | } 28 | cout << setw(5) << lst[0].back() << " " << input[lst[0].back()][0] 29 | << " -1\n"; 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /PAT/Advanced Level/1134. Vertex Cover.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | gg ni, mi, ki, ti, ai; 8 | cin >> ni >> mi; 9 | vector> edges(mi); 10 | for (auto& e : edges) { 11 | cin >> e[0] >> e[1]; 12 | } 13 | cin >> ki; 14 | while (ki--) { 15 | cin >> ti; 16 | unordered_set us; 17 | while (ti--) { 18 | cin >> ai; 19 | us.insert(ai); 20 | } 21 | for (auto& e : edges) { 22 | if (not us.count(e[0]) and not us.count(e[1])) { 23 | cout << "No\n"; 24 | goto loop; 25 | } 26 | } 27 | cout << "Yes\n"; 28 | loop:; 29 | } 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /PAT/Advanced Level/1136. A Delayed Palindrome.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | string Plus(const string& a, const string& b) { 5 | string ans; 6 | gg carry = 0; //进位 7 | for (gg i = a.size() - 1, j = b.size() - 1; i >= 0 or j >= 0 or carry != 0; --i, --j) { 8 | gg p1 = i >= 0 ? a[i] - '0' : 0, p2 = j >= 0 ? b[j] - '0' : 0; 9 | gg k = p1 + p2 + carry; 10 | ans.push_back(k % 10 + '0'); 11 | carry = k / 10; 12 | } 13 | reverse(ans.begin(), ans.end()); //要进行翻转 14 | return ans; 15 | } 16 | int main() { 17 | ios::sync_with_stdio(false); 18 | cin.tie(0); 19 | string a, b; 20 | cin >> a; 21 | for (gg i = 0; i < 10; ++i) { 22 | if (equal(a.begin(), a.end(), a.rbegin())) { //是回文数 23 | cout << a << " is a palindromic number.\n"; 24 | return 0; 25 | } 26 | b = a; 27 | reverse(b.begin(), b.end()); 28 | string c = Plus(a, b); 29 | cout << a << " + " << b << " = " << c << "\n"; 30 | a = c; 31 | } 32 | cout << "Not found in 10 iterations.\n"; 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /PAT/Advanced Level/1140. Look-and-say Sequence.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | string si; 8 | gg ni; 9 | cin >> si >> ni; 10 | while (--ni) { 11 | string t; 12 | for (gg i = 0, j; i < si.size(); i = j) { 13 | j = si.find_first_not_of(si[i], i + 1); 14 | if (j == -1) 15 | j = si.size(); 16 | t += string(1, si[i]) + to_string(j - i); 17 | } 18 | si = t; 19 | } 20 | cout << si; 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /PAT/Advanced Level/1143. Lowest Common Ancestor.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | gg mi, ni, u, v; 8 | cin >> mi >> ni; 9 | vector pre(ni); 10 | for (gg i = 0; i < ni; ++i) 11 | cin >> pre[i]; 12 | unordered_set us(pre.begin(), pre.end()); 13 | while (mi--) { 14 | cin >> u >> v; 15 | bool f1 = us.count(u), f2 = us.count(v); 16 | if (not f1 and not f2) { 17 | cout << "ERROR: " << u << " and " << v << " are not found.\n"; 18 | } else if (not f1 or not f2) { 19 | cout << "ERROR: " << (not f1 ? u : v) << " is not found.\n"; 20 | } else { 21 | gg ans = *find_if(pre.begin(), pre.end(), 22 | [u, v](gg a) { return (a - u) * (a - v) <= 0; }); 23 | if (ans == u or ans == v) { 24 | cout << (ans == u ? u : v) << " is an ancestor of " 25 | << (ans == u ? v : u) << ".\n"; 26 | } else { 27 | cout << "LCA of " << u << " and " << v << " is " << ans << ".\n"; 28 | } 29 | } 30 | } 31 | return 0; 32 | } -------------------------------------------------------------------------------- /PAT/Advanced Level/1144. The Missing Number.md: -------------------------------------------------------------------------------- 1 | # 【PAT A-1144】The Missing Number 2 | 3 | ## 题意概述 4 | 5 | 给定 N 个整数,要求找到不在这些整数中的最小正整数。 6 | 7 | ## 输入输出格式 8 | 9 | 输入第一行给出正整数 N,接下来一行,给出 N 个正整数。 10 | 11 | 输出不在这些整数中的最小正整数。 12 | 13 | ## 数据规模 14 | 15 | $$N\le {10}^5$$ 16 | 17 | ## 算法设计 18 | 19 | 将这 N 个正整数存入一个 unordered_set 中,然后从 1 开始枚举,第一个不在 unordered_set 中的正整数即为所求。 20 | 21 | ## C++代码 22 | 23 | ```cpp 24 | #include 25 | using namespace std; 26 | using gg = long long; 27 | int main() { 28 | ios::sync_with_stdio(false); 29 | cin.tie(0); 30 | gg ni, ai; 31 | cin >> ni; 32 | unordered_set us; 33 | for (gg i = 0; i < ni; ++i) { 34 | cin >> ai; 35 | us.insert(ai); 36 | } 37 | for (gg i = 1;; ++i) { 38 | if (not us.count(i)) { 39 | cout << i; 40 | break; 41 | } 42 | } 43 | return 0; 44 | } 45 | ``` 46 | -------------------------------------------------------------------------------- /PAT/Advanced Level/1146. Topological Order.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | const gg MAX = 1005; 5 | gg ni, mi, ki; 6 | vector> graph(MAX); 7 | vector top(MAX), degree(MAX); 8 | bool isTopSort() { 9 | vector temp(degree.begin(), degree.begin() + ni + 1); //拷贝入度 10 | for (gg i = 0; i < ni; ++i) { 11 | if (temp[top[i]] != 0) { //入度不为零,返回false 12 | return false; 13 | } 14 | for (gg j : graph[top[i]]) { //遍历该结点的邻接顶点 15 | --temp[j]; 16 | } 17 | } 18 | return true; 19 | } 20 | int main() { 21 | ios::sync_with_stdio(false); 22 | cin.tie(0); 23 | cin >> ni >> mi; 24 | while (mi--) { 25 | gg ai, bi; 26 | cin >> ai >> bi; 27 | graph[ai].push_back(bi); 28 | ++degree[bi]; 29 | } 30 | cin >> ki; 31 | vector ans; 32 | for (gg i = 0; i < ki; ++i) { 33 | for (gg j = 0; j < ni; ++j) { 34 | cin >> top[j]; 35 | } 36 | if (not isTopSort()) { 37 | ans.push_back(i); 38 | } 39 | } 40 | for (gg i = 0; i < ans.size(); ++i) { 41 | cout << ans[i] << (i == ans.size() - 1 ? "\n" : " "); 42 | } 43 | return 0; 44 | } -------------------------------------------------------------------------------- /PAT/Advanced Level/1147. Heaps.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | gg mi, ni; 5 | void postOrder(vector& v, gg root, gg& num) { 6 | if (root >= v.size()) { 7 | return; 8 | } 9 | postOrder(v, root * 2 + 1, num); 10 | postOrder(v, root * 2 + 2, num); 11 | cout << v[root] << (num++ < ni - 1 ? " " : "\n"); 12 | } 13 | int main() { 14 | ios::sync_with_stdio(false); 15 | cin.tie(0); 16 | cin >> mi >> ni; 17 | vector v(ni); 18 | while (mi--) { 19 | for (gg& i : v) { 20 | cin >> i; 21 | } 22 | if (is_heap(v.begin(), v.end())) { //能构成大根堆 23 | cout << "Max Heap\n"; 24 | } else if (is_heap(v.begin(), v.end(), greater())) { //能构成小根堆 25 | cout << "Min Heap\n"; 26 | } else { //不能构成堆 27 | cout << "Not Heap\n"; 28 | } 29 | gg num = 0; //记录输出到第几个数字了 30 | postOrder(v, 0, num); 31 | } 32 | return 0; 33 | } -------------------------------------------------------------------------------- /PAT/Advanced Level/1148. Werewolf - Simple Version.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | gg ni; 8 | cin >> ni; 9 | vector input(ni + 1); 10 | for (gg i = 1; i <= ni; ++i) { 11 | cin >> input[i]; 12 | } 13 | for (gg i = 1; i <= ni; ++i) { // i号玩家是狼人 14 | for (gg j = i + 1; j <= ni; ++j) { // j号玩家是狼人 15 | gg lier = 0, wolflier = 0; 16 | for (gg k = 1; k <= ni; ++k) { 17 | if (input[k] > 0 xor (abs(input[k]) != i and 18 | abs(input[k]) != j)) { // k号玩家在撒谎 19 | ++lier; 20 | if (k == i or k == j) { //狼人在撒谎 21 | ++wolflier; 22 | } 23 | } 24 | } 25 | if (lier == 2 and wolflier == 1) { //找到了一组解 26 | cout << i << " " << j; 27 | return 0; 28 | } 29 | } 30 | } 31 | cout << "No Solution"; 32 | return 0; 33 | } -------------------------------------------------------------------------------- /PAT/Advanced Level/1149. Dangerous Goods Packaging.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | gg ni, mi, ki, ai, bi; 8 | cin >> ni >> mi; 9 | //存储不相容的物品对 10 | unordered_map> um; 11 | while (ni--) { 12 | cin >> ai >> bi; 13 | um[ai].insert(bi); 14 | um[bi].insert(ai); 15 | } 16 | while (mi--) { 17 | cin >> ki; 18 | unordered_set us; 19 | while (ki--) { 20 | cin >> ai; 21 | us.insert(ai); 22 | } 23 | for (auto i : us) { //遍历货物清单 24 | if (um.count(i)) { //有不相容的物品 25 | for (auto j : um[i]) { //遍历不相容的物品 26 | if (us.count(j)) { //不相容的物品在该箱中 27 | cout << "No\n"; 28 | goto loop; 29 | } 30 | } 31 | } 32 | } 33 | cout << "Yes\n"; 34 | loop:; 35 | } 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /PAT/Advanced Level/1152. Google Recruitment.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | bool isPrime(gg n) { 5 | if (n < 2) // n小于2,一定不是素数 6 | return false; 7 | for (gg i = 2; i <= (gg)sqrt(n); ++i) //遍历2~根号n所有的数 8 | if (n % i == 0) // n能被i整除,说明n不是素数 9 | return false; 10 | return true; // n不能被2~n任何数整除,则n是素数 11 | } 12 | int main() { 13 | ios::sync_with_stdio(false); 14 | cin.tie(0); 15 | gg li, ki; 16 | string s; 17 | cin >> li >> ki >> s; 18 | for (int i = 0; i < s.size() - ki + 1; ++i) { 19 | string n = s.substr(i, ki); 20 | if (isPrime(stoll(n))) { 21 | cout << n; 22 | return 0; 23 | } 24 | } 25 | cout << "404"; 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /PAT/Advanced Level/1154. Vertex Coloring.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | gg ni, mi, ki; 8 | cin >> ni >> mi; 9 | vector> edges(mi); 10 | for (auto& e : edges) { 11 | cin >> e[0] >> e[1]; 12 | } 13 | cin >> ki; 14 | vector colors(ni); 15 | while (ki--) { 16 | unordered_set us; 17 | for (gg i = 0; i < ni; ++i) { 18 | cin >> colors[i]; 19 | us.insert(colors[i]); 20 | } 21 | for (auto& e : edges) { 22 | if (colors[e[0]] == colors[e[1]]) { 23 | cout << "No\n"; 24 | goto loop; 25 | } 26 | } 27 | cout << us.size() << "-coloring\n"; 28 | loop:; 29 | } 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /PAT/Advanced Level/1155. Heap Paths.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | vector path; //存储路径 5 | void dfs(vector& v, gg root) { 6 | if (root >= v.size()) { 7 | return; 8 | } 9 | if (root * 2 + 1 >= v.size()) { //是叶子结点 10 | for (gg i : path) { 11 | cout << i << " "; 12 | } 13 | cout << v[root] << "\n"; 14 | return; 15 | } 16 | path.push_back(v[root]); 17 | dfs(v, root * 2 + 2); //递归遍历右子树 18 | dfs(v, root * 2 + 1); //递归遍历左子树 19 | path.pop_back(); 20 | } 21 | int main() { 22 | ios::sync_with_stdio(false); 23 | cin.tie(0); 24 | gg ni; 25 | cin >> ni; 26 | vector v(ni); 27 | for (gg& i : v) { 28 | cin >> i; 29 | } 30 | dfs(v, 0); 31 | if (is_heap(v.begin(), v.end())) { //能构成大根堆 32 | cout << "Max Heap\n"; 33 | } else if (is_heap(v.begin(), v.end(), greater())) { //能构成小根堆 34 | cout << "Min Heap\n"; 35 | } else { //不能构成堆 36 | cout << "Not Heap\n"; 37 | } 38 | return 0; 39 | } -------------------------------------------------------------------------------- /PAT/Basic Level/1001. 害死人不偿命的(3n+1)猜想.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | gg ni, ans = 0; 8 | cin >> ni; 9 | for (; ni != 1; ++ans) { 10 | if (ni % 2 == 1) { 11 | ni = 3 * ni + 1; 12 | } 13 | ni /= 2; 14 | } 15 | cout << ans; 16 | return 0; 17 | } -------------------------------------------------------------------------------- /PAT/Basic Level/1002. 写出这个数.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int main() { 4 | ios::sync_with_stdio(false); 5 | cin.tie(0); 6 | string s; 7 | cin >> s; 8 | int sum = accumulate(s.begin(), s.end(), 0, 9 | [](int a, char c) { return a + c - '0'; }); 10 | s = to_string(sum); 11 | array p{"ling", "yi", "er", "san", "si", 12 | "wu", "liu", "qi", "ba", "jiu"}; 13 | for (int i = 0; i < s.size(); ++i) { 14 | cout << (i > 0 ? " " : "") << p[s[i] - '0']; 15 | } 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /PAT/Basic Level/1003. 我要通过!.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | gg ni; 8 | cin >> ni; 9 | while (ni--) { 10 | string si; 11 | cin >> si; 12 | unordered_map um; 13 | for (char c : si) { 14 | ++um[c]; 15 | } 16 | gg p = si.find('P'), t = si.find('T'); 17 | if (um.size() == 3 and um['P'] == 1 and um['T'] == 1 and 18 | um.count('A') > 0 and p < t - 1 and 19 | p * (t - p - 1) == si.size() - t - 1) { 20 | cout << "YES\n"; 21 | } else { 22 | cout << "NO\n"; 23 | } 24 | } 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /PAT/Basic Level/1004. 成绩排名.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | struct Student { 5 | string name, number; 6 | gg score; 7 | Student(gg s = 0) : score(s) {} 8 | }; 9 | int main() { 10 | ios::sync_with_stdio(false); 11 | cin.tie(0); 12 | gg ni; 13 | cin >> ni; 14 | Student Max(-1), Min(101), temp; // Max初始成绩为-1,Min初试成绩为101 15 | for (gg i = 0; i < ni; ++i) { 16 | cin >> temp.name >> temp.number >> temp.score; 17 | if (Max.score < temp.score) 18 | Max = temp; 19 | if (Min.score > temp.score) 20 | Min = temp; 21 | } 22 | cout << Max.name << " " << Max.number << "\n" 23 | << Min.name << " " << Min.number; 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /PAT/Basic Level/1005. 继续(3n+1)猜想.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; //类型别名 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | gg ni, ai; 8 | unordered_set us; //存储被覆盖的数 9 | cin >> ni; 10 | vector v; 11 | while (ni--) { 12 | cin >> ai; 13 | v.push_back(ai); 14 | while (ai != 1) { 15 | if (ai % 2 == 1) 16 | ai = ai * 3 + 1; 17 | ai /= 2; 18 | us.insert(ai); 19 | } 20 | } 21 | sort(v.begin(), v.end(), greater()); //从大到小排序 22 | bool first = true; //标志是否是第一个输出的数字,控制输出空格 23 | for (auto i : v) { 24 | if (not us.count(i)) { // i是关键数 25 | cout << (first ? "" : " ") << i; 26 | first = false; 27 | } 28 | } 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /PAT/Basic Level/1006. 换个格式输出整数.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int main() { 4 | ios::sync_with_stdio(false); 5 | cin.tie(0); 6 | string ni; 7 | cin >> ni; 8 | int s = ni.size(); // s为字符串长度 9 | for (int i = 0; i < s; ++i) { 10 | // j不仅负责计数,还负责遍历从'1'到n[i]之间的字符 11 | for (char j = '1'; j <= ni[i]; ++j) { 12 | // i为j-3说明是百位,i为j-2说明是十位,否则是个位 13 | cout << (i == s - 3 ? 'B' : i == s - 2 ? 'S' : j); 14 | } 15 | } 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /PAT/Basic Level/1007. 素数对猜想.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | vector prime; 5 | void getPrime(gg n = gg(1e5)) { 6 | vector f(n + 5); 7 | for (gg i = 2; i <= n; ++i) 8 | if (not f[i]) { 9 | prime.push_back(i); 10 | for (gg j = i + i; j <= n; j += i) 11 | f[j] = true; 12 | } 13 | } 14 | int main() { 15 | ios::sync_with_stdio(false); 16 | cin.tie(0); 17 | gg ni, ans = 0; 18 | cin >> ni; 19 | getPrime(ni); 20 | for (gg i = 1; i < prime.size(); ++i) { 21 | if (prime[i] - prime[i - 1] == 2) { 22 | ++ans; 23 | } 24 | } 25 | cout << ans; 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /PAT/Basic Level/1008. 数组元素循环右移问题.md: -------------------------------------------------------------------------------- 1 | # 【PAT B-1008】数组元素循环右移问题 2 | 3 | ## 题意概述 4 | 5 | 一个数组 A 中存有 N 个整数,在不允许使用另外数组的前提下,将每个整数循环向右移 M 个位置,即将 A 中的数据由$A_0A_1\cdots A_{N-1}$变换为$A_{N-M}\cdots A_{N-1}A_0A_1\cdots A_{N-M-1}$(最后 M 个数循环移至最前面的 M 个位置)。如果需要考虑程序移动数据的次数尽量少,要如何设计移动的方法? 6 | 7 | ## 输入输出格式 8 | 9 | 输入第 1 行给出两个整数 N 和 M;第 2 行输入 N 个整数,之间用空格分隔。 10 | 11 | 在一行中输出循环右移 M 位以后的整数序列,之间用空格分隔,序列结尾不能有多余空格。 12 | 13 | ## 数据规模 14 | 15 | $$1<=N<=100,M>=0$$ 16 | 17 | ## 算法设计 18 | 19 | 3 次翻转即可。 20 | 21 | ## C++代码 22 | 23 | ```cpp 24 | #include 25 | using namespace std; 26 | using gg = long long; 27 | int main() { 28 | ios::sync_with_stdio(false); 29 | cin.tie(0); 30 | gg ni, mi; 31 | cin >> ni >> mi; 32 | vector v(ni); 33 | for (gg& i : v) { 34 | cin >> i; 35 | } 36 | mi = ni - mi % ni; 37 | reverse(v.begin(), v.begin() + mi); 38 | reverse(v.begin() + mi, v.end()); 39 | reverse(v.begin(), v.end()); 40 | for (gg i = 0; i < v.size(); ++i) { 41 | cout << v[i] << (i == v.size() - 1 ? "\n" : " "); 42 | } 43 | return 0; 44 | } 45 | ``` 46 | -------------------------------------------------------------------------------- /PAT/Basic Level/1009. 说反话.cpp: -------------------------------------------------------------------------------- 1 | //第一种方法:使用栈 2 | #include 3 | using namespace std; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | string s; 8 | stack st; 9 | while (cin >> s) { 10 | st.push(s); 11 | } 12 | while (not st.empty()) { 13 | cout << st.top(); 14 | st.pop(); 15 | cout << (st.empty() ? "" : " "); 16 | } 17 | return 0; 18 | } 19 | //第二种方法:使用vector+反向迭代器 20 | #include 21 | using namespace std; 22 | int main() { 23 | ios::sync_with_stdio(false); 24 | cin.tie(0); 25 | string s; 26 | vector v; 27 | while (cin >> s) { 28 | v.push_back(s); 29 | } 30 | for (auto i = v.rbegin(); i != v.rend(); ++i) { 31 | cout << (i == v.rbegin() ? "" : " ") << *i; 32 | } 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /PAT/Basic Level/1010. 一元多项式求导.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | gg ci, ei; 8 | bool space = false; 9 | while (cin >> ci >> ei) { 10 | ci *= ei; 11 | --ei; 12 | if (ci != 0) { 13 | cout << (space ? " " : "") << ci << " " << ei; 14 | space = true; 15 | } 16 | } 17 | if (not space) 18 | cout << "0 0"; 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /PAT/Basic Level/1011. A+B和C.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | gg ti, ai, bi, ci; 8 | cin >> ti; 9 | for (gg i = 1; i <= ti; ++i) { 10 | cin >> ai >> bi >> ci; 11 | cout << "Case #" << i << ": " << (ai + bi > ci ? "true" : "false") 12 | << "\n"; 13 | } 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /PAT/Basic Level/1012. 数字分类.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | gg ni, ti, help = 1; 8 | cin >> ni; 9 | gg ans[5]{}, num[5]{}; // ans记录A[1]~A[5],num记录数字出现次数 10 | while (ni--) { 11 | cin >> ti; 12 | if (ti % 10 == 0) { // A[1] 13 | ans[0] += ti; 14 | ++num[0]; 15 | } else if (ti % 5 == 1) { // A[2] 16 | ans[1] += help * ti; 17 | help *= -1; 18 | ++num[1]; 19 | } else if (ti % 5 == 2) { // A[3] 20 | ++ans[2]; 21 | ++num[2]; 22 | } else if (ti % 5 == 3) { // A[4] 23 | ans[3] += ti; 24 | ++num[3]; 25 | } else if (ti % 5 == 4 and ti > ans[4]) { // A[5] 26 | ans[4] = ti; 27 | ++num[4]; 28 | } 29 | } 30 | for (int i = 0; i < 5; ++i) { 31 | cout << (i == 0 ? "" : " "); 32 | if (num[i] == 0) { 33 | cout << 'N'; 34 | } else { 35 | cout << fixed << setprecision(i == 3 ? 1 : 0) 36 | << (i == 3 ? ans[i] * 1.0 / num[i] : ans[i] * 1.0); 37 | } 38 | } 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /PAT/Basic Level/1013. 数素数.md: -------------------------------------------------------------------------------- 1 | # 【PAT B-1013】数素数 2 | 3 | ## 题意概述 4 | 5 | 令$P_i$ 表示第 i 个素数,给出两个数 M 和 N,求$P_M$到$P_N$的所有素数。 6 | 7 | ## 输入输出格式 8 | 9 | 输入在一行中给出 M 和 N,其间以空格分隔。 10 | 11 | 输出从$P_M$到$P_N$的所有素数,每 10 个数字占 1 行,其间以空格分隔,但行末不得有多余空格。 12 | 13 | ## 数据规模 14 | 15 | $$M\le N\le{10}^4$$ 16 | 17 | ## 算法设计 18 | 19 | 定义两个循环变量 i 和 j,i 负责从 2 开始枚举所有的正整数,j 负责记录已经枚举过多少素数,当 i 为素数时,判断 j 是否在$\left[M,N\right]$之间,如果在,就输出 i。当$j\geq N$时即可跳出循环。 20 | 循环的时间复杂度为$O\left(n\right)$,暴力判断一个数是否为素数的时间复杂度为$O\left(\sqrt n\right)$,那么整个算法的时间复杂度为$O\left(n^{1.5}\right)$。但这里的 n 最大不是${10}^4$,而是要取决于第${10}^4$个素数的值。第${10}^4$个质数其实是 104729,达到了${10}^5$级别。但暴力的算法仍然可以很轻松地通过本题的评测,说明本题的测试数据并不强。 21 | 22 | ## C++代码 23 | 24 | ```cpp 25 | #include 26 | using namespace std; 27 | using gg = long long; 28 | bool isPrime(gg n) { 29 | if (n < 2) // n小于2,一定不是素数 30 | return false; 31 | for (gg i = 2; i <= (gg)sqrt(n); ++i) //遍历2~根号n所有的数 32 | if (n % i == 0) // n能被i整除,说明n不是素数 33 | return false; 34 | return true; // n不能被2~n任何数整除,则n是素数 35 | } 36 | int main() { 37 | ios::sync_with_stdio(false); 38 | cin.tie(0); 39 | gg mi, ni; 40 | cin >> mi >> ni; 41 | for (gg i = 2, j = 0; j <= ni; ++i) { 42 | if (isPrime(i)) { 43 | ++j; 44 | if (j >= mi and j <= ni) { 45 | cout << i << ((j - mi + 1) % 10 == 0 or j == ni ? '\n' : ' '); 46 | } 47 | } 48 | } 49 | return 0; 50 | } 51 | ``` 52 | -------------------------------------------------------------------------------- /PAT/Basic Level/1014. 福尔摩斯的约会.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | cout << setfill('0'); //输出用字符0填充 8 | // ABCDEFG七个字符到星期的映射 9 | unordered_map week = { 10 | {'A', "MON"}, {'B', "TUE"}, {'C', "WED"}, {'D', "THU"}, 11 | {'E', "FRI"}, {'F', "SAT"}, {'G', "SUN"}}; 12 | // 0~9、A~N到小时的映射 13 | unordered_map hour; 14 | for (gg i = 0; i < 24; ++i) 15 | hour.insert({i < 10 ? i + '0' : i - 10 + 'A', i}); 16 | string s1, s2; 17 | cin >> s1 >> s2; 18 | for (gg i = 0, c = 0; i < min(s1.size(), s2.size()); ++i) { 19 | if (s1[i] == s2[i] and c == 0 and week.count(s1[i])) { 20 | cout << week[s1[i]] << " "; 21 | ++c; 22 | } else if (s1[i] == s2[i] and c == 1 and hour.count(s1[i])) { 23 | cout << setw(2) << hour[s1[i]] << ':'; 24 | ++c; 25 | } 26 | } 27 | cin >> s1 >> s2; 28 | for (gg i = 0, c = 0; i < min(s1.size(), s2.size()); ++i) { 29 | if (s1[i] == s2[i] and isalpha(s1[i])) { 30 | cout << setw(2) << i; 31 | break; 32 | } 33 | } 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /PAT/Basic Level/1015. 德才论.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | struct Student { 5 | gg id, de, cai, total, level; 6 | Student(gg i, gg d, gg c, gg le) : id(i), de(d), cai(c), level(le) { 7 | total = de + cai; 8 | } 9 | }; 10 | int main() { 11 | ios::sync_with_stdio(false); 12 | cin.tie(0); 13 | vector students; 14 | gg ni, li, hi, id, de, cai, level; 15 | cin >> ni >> li >> hi; 16 | cout << setfill('0'); 17 | while (ni--) { 18 | cin >> id >> de >> cai; 19 | if (de < li or cai < li) 20 | continue; 21 | if (de >= hi and cai >= hi) { 22 | level = 1; 23 | } else if (de >= hi and cai < hi) { 24 | level = 2; 25 | } else if (de < hi and cai < hi and de >= cai) { 26 | level = 3; 27 | } else { 28 | level = 4; 29 | } 30 | students.push_back(Student(id, de, cai, level)); 31 | } 32 | sort(students.begin(), students.end(), 33 | [](const Student& s1, const Student& s2) { 34 | return tie(s1.level, s2.total, s2.de, s1.id) < 35 | tie(s2.level, s1.total, s1.de, s2.id); 36 | }); 37 | cout << students.size() << '\n'; 38 | for (auto& s : students) { 39 | cout << setw(8) << s.id << ' ' << s.de << ' ' << s.cai << '\n'; 40 | } 41 | return 0; 42 | } 43 | -------------------------------------------------------------------------------- /PAT/Basic Level/1016. 部分A+B.md: -------------------------------------------------------------------------------- 1 | # 【PAT B-1016】部分 A+B 2 | 3 | ## 题意概述 4 | 5 | 正整数 A 的$D_A$部分定义为由 A 中的所有$D_A$组成的新整数$P_A$。例如:给定 A=3862767,$D_A=6$,则 A 的“6 部分”$P_A=66$,因为 A 中有 2 个 6。给定 A、$D_A$、B、$D_B$,计算$P_A+P_B$。 6 | 7 | ## 输入输出格式 8 | 9 | 输入第一行给出 A、$D_A$、B、$D_B$。 10 | 11 | 在一行中输出$P_A+P_B$。 12 | 13 | ## 数据规模 14 | 15 | $$0 25 | using namespace std; 26 | using gg = long long; 27 | int main() { 28 | ios::sync_with_stdio(false); 29 | cin.tie(0); 30 | string A, B; 31 | gg Da, Db, a = 0, b = 0; 32 | cin >> A >> Da >> B >> Db; 33 | for (auto c : A) { 34 | if (c - '0' == Da) { 35 | a = a * 10 + Da; 36 | } 37 | } 38 | for (auto c : B) { 39 | if (c - '0' == Db) { 40 | b = b * 10 + Db; 41 | } 42 | } 43 | cout << a + b; 44 | return 0; 45 | } 46 | ``` 47 | -------------------------------------------------------------------------------- /PAT/Basic Level/1017. A除以B.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | //默认a为非负整数,b为正整数 5 | pair DivMod(const string& a, gg b) { 6 | string ans; //商 7 | gg mod = 0; //余数 8 | for (char c : a) { 9 | mod = c - '0' + mod * 10; 10 | ans.push_back(mod / b + '0'); 11 | mod %= b; 12 | } 13 | ans.erase(0, ans.find_first_not_of('0')); 14 | return {ans.empty() ? "0" : ans, mod}; 15 | } 16 | int main() { 17 | ios::sync_with_stdio(false); 18 | cin.tie(0); 19 | string a; 20 | gg b; 21 | cin >> a >> b; 22 | auto ans = DivMod(a, b); 23 | cout << ans.first << " " << ans.second; 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /PAT/Basic Level/1019. 数字黑洞.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | cout << setfill('0'); 8 | gg ni; 9 | cin >> ni; 10 | do { 11 | string s = to_string(ni); 12 | while (s.size() < 4) 13 | s.push_back('0'); 14 | sort(s.begin(), s.end()); 15 | gg a = stoll(s); 16 | sort(s.begin(), s.end(), greater()); 17 | gg b = stoll(s); 18 | ni = b - a; 19 | cout << setw(4) << b << " - " << setw(4) << a << " = " << setw(4) << ni 20 | << '\n'; 21 | } while (ni != 0 and ni != 6174); 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /PAT/Basic Level/1020. 月饼.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | gg ni, di; 8 | cin >> ni >> di; 9 | using ad2 = array; //存储月饼的库存量和总售价 10 | vector cakes(ni); 11 | for (gg i = 0; i < ni; ++i) 12 | cin >> cakes[i][0]; 13 | for (gg i = 0; i < ni; ++i) 14 | cin >> cakes[i][1]; 15 | //按单价从大到小排序 16 | sort(cakes.begin(), cakes.end(), [](const ad2& c1, const ad2& c2) { 17 | return c1[1] * 1.0 / c1[0] > c2[1] * 1.0 / c2[0]; 18 | }); 19 | double ans = 0.0; //存储最终收益 20 | for (auto& c : cakes) { 21 | if (di >= c[0]) { 22 | ans += c[1]; 23 | di -= c[0]; 24 | } else { 25 | ans += c[1] * 1.0 / c[0] * di; 26 | di = 0; 27 | } 28 | } 29 | cout << fixed << setprecision(2) << ans; 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /PAT/Basic Level/1021. 个位数统计.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | array h{}; 8 | string s; 9 | cin >> s; 10 | for (char c : s) { 11 | ++h[c - '0']; 12 | } 13 | for (int i = 0; i < h.size(); ++i) { 14 | if (h[i] > 0) { 15 | cout << i << ':' << h[i] << '\n'; 16 | } 17 | } 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /PAT/Basic Level/1022. D进制的A+B.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | vector decToR(gg n, gg R) { 5 | vector ans; //存储R进制数 6 | do { 7 | ans.push_back(n % R); //取余 8 | n /= R; //除基 9 | } while (n != 0); // n==0时跳出循环 10 | reverse(ans.begin(), ans.end()); //翻转整个数组 11 | return ans; 12 | } 13 | int main() { 14 | ios::sync_with_stdio(false); 15 | cin.tie(0); 16 | gg ai, bi, di; 17 | cin >> ai >> bi >> di; 18 | ai += bi; 19 | for (auto i : decToR(ai, di)) 20 | cout << i; 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /PAT/Basic Level/1023. 组个最小数.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | array h{}; 8 | for (gg i = 0; i < 10; ++i) 9 | cin >> h[i]; 10 | auto k = find_if(h.begin() + 1, h.end(), [](int a) { return a > 0; }) - 11 | h.begin(); 12 | cout << k; 13 | --h[k]; 14 | for (gg i = 0; i < 10; ++i) { 15 | while (h[i]--) { 16 | cout << i; 17 | } 18 | } 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /PAT/Basic Level/1024. 科学计数法.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | regex r("([+-])([1-9]).([0-9]+)E([+-])([0-9]+)"); 8 | string si; 9 | cin >> si; 10 | smatch result; 11 | regex_match(si, result, r); 12 | if (result.str(1) == "-") { //输入是负数要输出负号 13 | cout << result[1]; 14 | } 15 | gg n = stoll(result.str(5)); //获取指数的值 16 | if (result.str(4) == "-") { //小数点要左移n位,要在小数点后补n-1个0 17 | cout << "0." << string(n - 1, '0') << result[2] << result[3]; 18 | } else if (n < result.length(3)) { 19 | //小数点右移的位数不超过3号子串长度,将3号子串用小数点分隔开进行输出 20 | cout << result[2] << result.str(3).substr(0, n) << "." 21 | << result.str(3).substr(n); 22 | } else if (n == result.length(3)) { 23 | //小数点右移的位数等于3号子字符串长度,小数点无需输出 24 | cout << result[2] << result[3]; 25 | } else { 26 | //小数点右移的位数超过3号子串长度,在3号子串后补0 27 | cout << result[2] << result[3] << string(n - result.length(3), '0'); 28 | } 29 | return 0; 30 | } -------------------------------------------------------------------------------- /PAT/Basic Level/1025. 反转链表.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | vector> input(gg(1e6), {-1, -1}); 8 | gg start, ni, ki; 9 | cin >> start >> ni >> ki; 10 | for (gg i = 0; i < ni; ++i) { 11 | gg address, data, nextA; 12 | cin >> address >> data >> nextA; 13 | input[address] = {data, nextA}; 14 | } 15 | vector lst; 16 | while (start != -1) { 17 | lst.push_back(start); 18 | start = input[start][1]; 19 | } 20 | for (gg i = ki; i <= lst.size(); i += ki) { 21 | reverse(lst.begin() + i - ki, lst.begin() + i); 22 | } 23 | cout << setfill('0'); 24 | for (gg i = 0; i < lst.size() - 1; ++i) { 25 | cout << setw(5) << lst[i] << " " << input[lst[i]][0] << " " << setw(5) 26 | << lst[i + 1] << "\n"; 27 | } 28 | cout << setw(5) << lst.back() << " " << input[lst.back()][0] << " -1\n"; 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /PAT/Basic Level/1026. 程序运行时间.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | gg ai, bi; 8 | cin >> ai >> bi; 9 | ai = round((bi - ai) / 100.0); 10 | cout << setfill('0') << setw(2) << ai / 3600 << ":" << setw(2) 11 | << ai / 60 % 60 << ":" << setw(2) << ai % 60; 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /PAT/Basic Level/1028. 人口普查.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | struct Person { 5 | string name; 6 | gg y, m, d; 7 | Person(gg yy, gg mm, gg dd, string n = "") : y(yy), m(mm), d(dd), name(n) {} 8 | bool operator<(const Person& p) const { 9 | return tie(y, m, d) < tie(p.y, p.m, p.d); 10 | } 11 | }; 12 | int main() { 13 | ios::sync_with_stdio(false); 14 | cin.tie(0); 15 | gg ni, num = 0; 16 | cin >> ni; 17 | Person old(2014, 9, 6), young(1814, 9, 6), b1 = old, b2 = young, t(0, 0, 0); 18 | while (ni--) { 19 | char c; 20 | cin >> t.name >> t.y >> c >> t.m >> c >> t.d; 21 | if (b1 < t or t < b2) //注意这里不能使用>,因为我们没有重载>运算符 22 | continue; 23 | old = min(old, t); 24 | young = max(young, t); 25 | ++num; 26 | } 27 | if (num == 0) //有效生日为0,进行特判 28 | cout << "0"; 29 | else 30 | cout << num << ' ' << old.name << ' ' << young.name; 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /PAT/Basic Level/1029. 旧键盘.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int main() { 4 | ios::sync_with_stdio(false); 5 | cin.tie(0); 6 | string s1, s2; 7 | cin >> s1 >> s2; 8 | vector h(128); //哈希表 9 | for (char c : s2) 10 | h[toupper(c)] = true; 11 | for (char c : s1) { 12 | if (not h[toupper(c)]) { 13 | cout << (char)toupper(c); 14 | h[toupper(c)] = true; //保证坏掉的键只输出一次 15 | } 16 | } 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /PAT/Basic Level/1030. 完美数列.cpp: -------------------------------------------------------------------------------- 1 | //二分查找 2 | #include 3 | using namespace std; 4 | using gg = long long; 5 | int main() { 6 | ios::sync_with_stdio(false); 7 | cin.tie(0); 8 | gg ni, pi, ans = 0; 9 | cin >> ni >> pi; 10 | vector v(ni); 11 | for (gg i = 0; i < ni; ++i) { 12 | cin >> v[i]; 13 | } 14 | sort(v.begin(), v.end()); 15 | for (gg i = 0; i < ni; ++i) { 16 | ans = max(ans, 17 | upper_bound(v.begin(), v.end(), v[i] * pi) - v.begin() - i); 18 | } 19 | cout << ans; 20 | return 0; 21 | } 22 | // two pointers 23 | #include 24 | using namespace std; 25 | using gg = long long; 26 | int main() { 27 | ios::sync_with_stdio(false); 28 | cin.tie(0); 29 | gg ni, pi, ans = 0; 30 | cin >> ni >> pi; 31 | vector v(ni); 32 | for (gg i = 0; i < ni; ++i) { 33 | cin >> v[i]; 34 | } 35 | sort(v.begin(), v.end()); 36 | for (gg i = 0, j = 0; j < v.size(); ++i) { 37 | while (j < v.size() and v[j] <= v[i] * pi) { 38 | ++j; 39 | } 40 | ans = max(ans, j - i); 41 | } 42 | cout << ans; 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /PAT/Basic Level/1031. 查验身份证.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | gg ni; 8 | cin >> ni; 9 | string si; 10 | gg weight[] = {7, 9, 10, 5, 8, 4, 2, 1, 6, 11 | 3, 7, 9, 10, 5, 8, 4, 2}; //前17位权重 12 | string m = "10X98765432"; //模11取余后的字符 13 | bool pass = true; 14 | while (ni--) { 15 | cin >> si; 16 | bool f = true; //记录当前身份证是否有问题 17 | gg sum = 0; 18 | for (int i = 0; i < 17 and f; ++i) { 19 | if (not isdigit(si[i])) { 20 | f = false; 21 | } else { 22 | sum += (si[i] - '0') * weight[i]; 23 | } 24 | } 25 | if (m[sum % 11] != si.back() or not f) { 26 | cout << si << '\n'; 27 | pass = false; 28 | } 29 | } 30 | if (pass) 31 | cout << "All passed"; 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /PAT/Basic Level/1032. 挖掘机技术哪家强.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | array h{}; 8 | gg n; 9 | cin >> n; 10 | while (n--) { 11 | gg a, b; 12 | cin >> a >> b; 13 | h[a] += b; 14 | } 15 | auto i = max_element(h.begin(), h.end()); 16 | cout << (i - h.begin()) << ' ' << *i; 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /PAT/Basic Level/1033. 旧键盘打字.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int main() { 4 | ios::sync_with_stdio(false); 5 | cin.tie(0); 6 | string s1, s2; 7 | getline(cin, s1); 8 | getline(cin, s2); 9 | vector h(128); 10 | for (char c : s1) 11 | h[tolower(c)] = true; 12 | for (char c : s2) { 13 | if (h[tolower(c)] or (isupper(c) and h['+'])) 14 | continue; 15 | cout << c; 16 | } 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /PAT/Basic Level/1036. 跟奥巴马一起编程.md: -------------------------------------------------------------------------------- 1 | # 【PAT B-1036】跟奥巴马一起编程 2 | 3 | ## 题意概述 4 | 5 | 本题要求你在屏幕上画一个正方形。 6 | 7 | ## 输入输出格式 8 | 9 | 输入在一行中给出正方形边长 N 和组成正方形边的某种字符 C,间隔一个空格。 10 | 11 | 输出由给定字符 C 画出的正方形。但是注意到行间距比列间距大,所以为了让结果看上去更像正方形,我们输出的行数实际上是列数的 50%(四舍五入取整)。 12 | 13 | ## 数据规模 14 | 15 | $$3\le N\le20$$ 16 | 17 | ## 算法设计 18 | 19 | 很容易知道这个图形在第 1 行和最后一行共输出 N 个 C 字符,而其他行只在第一列和最后一列输出字符 C。关键在于确定列数,如果行数为 N,列数为行数的一半且四舍五入取整,那么列数$col=\lfloor(N+1)/2\rfloor$。 20 | 21 | ## C++代码 22 | 23 | ```cpp 24 | #include 25 | using namespace std; 26 | using gg = long long; 27 | int main() { 28 | gg ni; 29 | char ci; 30 | cin >> ni >> ci; 31 | for (gg i = 0; i < ni; ++i) 32 | cout << ci; 33 | cout << '\n'; 34 | gg row = (ni + 1) / 2; 35 | for (gg i = 0; i < row - 2; ++i) { 36 | cout << ci; 37 | for (gg j = 0; j < ni - 2; ++j) 38 | cout << ' '; 39 | cout << ci << '\n'; 40 | } 41 | for (gg i = 0; i < ni; ++i) 42 | cout << ci; 43 | return 0; 44 | } 45 | ``` 46 | -------------------------------------------------------------------------------- /PAT/Basic Level/1037. 在霍格沃茨找零钱.cpp: -------------------------------------------------------------------------------- 1 | // 将输入数据统一转换到最小单位,进行指定运算后,再将得到的结果转换到所要输出的格式 2 | #include 3 | using namespace std; 4 | using gg = long long; 5 | int main() { 6 | ios::sync_with_stdio(false); 7 | cin.tie(0); 8 | gg g1, s1, k1, g2, s2, k2; 9 | char c; //读取小数点 10 | cin >> g1 >> c >> s1 >> c >> k1 >> g2 >> c >> s2 >> c >> k2; 11 | //将输入数据统一转换到最小单位 12 | gg t1 = (g1 * 17 + s1) * 29 + k1, t2 = (g2 * 17 + s2) * 29 + k2; 13 | t2 -= t1; 14 | cout << t2 / 29 / 17 << '.' << abs(t2) / 29 % 17 << '.' << abs(t2) % 29; 15 | return 0; 16 | } 17 | // 从最小单位开始进行指定运算,向上级单位产生进位或借位,得出最终结果。 18 | #include 19 | using namespace std; 20 | using gg = long long; 21 | struct T { 22 | gg g, s, k; 23 | bool operator<(const T& t) const { 24 | return tie(g, s, k) < tie(t.g, t.s, t.k); 25 | } 26 | }; 27 | int main() { 28 | ios::sync_with_stdio(false); 29 | cin.tie(0); 30 | T t1, t2; 31 | char c; //读取小数点 32 | cin >> t1.g >> c >> t1.s >> c >> t1.k >> t2.g >> c >> t2.s >> c >> t2.k; 33 | if (t2 < t1) { 34 | cout << '-'; 35 | swap(t1, t2); 36 | } 37 | if (t2.k < t1.k) { //向高位借位 38 | t2.k = t2.k + 29; 39 | --t2.s; 40 | } 41 | if (t2.s < t1.s) { //向高位借位 42 | t2.s = t2.s + 17; 43 | --t2.g; 44 | } 45 | cout << t2.g - t1.g << '.' << t2.s - t1.s << '.' << t2.k - t1.k; 46 | return 0; 47 | } 48 | -------------------------------------------------------------------------------- /PAT/Basic Level/1038. 统计同成绩学生.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | array h{}; 8 | gg n, a; 9 | cin >> n; 10 | while (n--) { 11 | cin >> a; 12 | ++h[a]; 13 | } 14 | cin >> n; 15 | for (int i = 0; i < n; ++i) { 16 | cin >> a; 17 | cout << (i == 0 ? "" : " ") << h[a]; 18 | } 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /PAT/Basic Level/1039. 到底买不买.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | string s1, s2; 8 | getline(cin, s1); 9 | getline(cin, s2); 10 | array h{}; 11 | for (char c : s1) 12 | ++h[c]; 13 | for (char c : s2) 14 | --h[c]; 15 | gg k1 = 0, k2 = 0; // k1记录多余的珠子数,k2记录少的珠子数 16 | for (int i : h) { 17 | i > 0 ? k1 += i : k2 -= i; 18 | } 19 | k2 > 0 ? cout << "No " << k2 : cout << "Yes " << k1; 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /PAT/Basic Level/1040. 有几个PAT.md: -------------------------------------------------------------------------------- 1 | 请参考[PAT A-1093. Count PAT's](../Advanced%20Level/1093.%20Count%20PAT's.md) -------------------------------------------------------------------------------- /PAT/Basic Level/1041. 考试座位号.md: -------------------------------------------------------------------------------- 1 | # 【PAT B-1041】考试座位号 2 | 3 | ## 题意概述 4 | 5 | 每个 PAT 考生在参加考试时都会被分配两个座位号,一个是试机座位,一个是考试座位。你需要根据试机座位查询考生的准考证号和考试座位号码。 6 | 7 | ## 输入输出格式 8 | 9 | 输入第一行给出一个正整数 N,随后 N 行,每行依次给出一个考生的信息:准考证号、试机座位号、考试座位号。其中准考证号由 16 位数字组成,座位从 1 到 N 编号。输入保证每个人的准考证号都不同,并且任何时候都不会把两个人分配到同一个座位上。 10 | 11 | 考生信息之后,给出一个正整数 M(≤N),随后一行中给出 M 个待查询的试机座位号码,以空格分隔。 12 | 13 | ## 数据规模 14 | 15 | $$0 29 | using namespace std; 30 | using gg = long long; 31 | int main() { 32 | ios::sync_with_stdio(false); 33 | cin.tie(0); 34 | array, 1005> h{}; 35 | gg ni, ai, bi, ci; 36 | cin >> ni; 37 | while (ni--) { 38 | cin >> ai >> bi >> ci; 39 | h[bi] = {ai, ci}; 40 | } 41 | cin >> ni; 42 | cout << setfill('0'); 43 | while (ni--) { 44 | cin >> ai; 45 | cout << setw(16) << h[ai][0] << ' ' << h[ai][1] << '\n'; 46 | } 47 | return 0; 48 | } 49 | ``` 50 | -------------------------------------------------------------------------------- /PAT/Basic Level/1042. 字符统计.md: -------------------------------------------------------------------------------- 1 | # 【PAT B-1042】字符统计 2 | 3 | ## 题意概述 4 | 5 | 找出一段给定文字中出现最频繁的那个英文字母。 6 | 7 | ## 输入输出格式 8 | 9 | 在一行中给出一个字符串。字符串由 ASCII 码表中任意可见字符及空格组成,至少包含 1 个英文字母。 10 | 11 | 在一行中输出出现频率最高的那个英文字母及其出现次数,其间以空格分隔。如果有并列,则输出按字母序最小的那个字母。统计时不区分大小写,输出小写字母。 12 | 13 | ## 数据规模 14 | 15 | 字符串长度不超过 1000。 16 | 17 | ## 算法设计 18 | 19 | 由于 ASCII 码只有 128 位,可以定义一个维度为 128 的数组来记录字符出现的频率。然后遍历该数组找出频率最高的字符即可。 20 | 21 | ## 注意点 22 | 23 | 1. 要求查找的是出现频率最高的英文字母,非英文字母应该忽略。 24 | 2. 以小写字母形式输出,不区分大小写。 25 | 3. 如果有频率相同的小写字母,输出字母序最小的那一个。 26 | 27 | ## C++代码 28 | 29 | ```cpp 30 | #include 31 | using namespace std; 32 | using gg = long long; 33 | int main() { 34 | ios::sync_with_stdio(false); 35 | cin.tie(0); 36 | array h{}; 37 | string s; 38 | getline(cin, s); 39 | for (char c : s) { 40 | if (isalpha(c)) { 41 | ++h[tolower(c)]; 42 | } 43 | } 44 | auto i = max_element(h.begin(), h.end()); 45 | cout << (char)(i - h.begin()) << ' ' << *i; 46 | return 0; 47 | } 48 | ``` 49 | -------------------------------------------------------------------------------- /PAT/Basic Level/1043. 输出PATest.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | string si, out = "PATest"; 8 | unordered_map um; //记录字符及其出现次数 9 | cin >> si; 10 | for (char c : si) { //统计字符出现的次数 11 | if (out.find(c) != -1) { // out中包含字符c 12 | ++um[c]; 13 | } 14 | } 15 | while (not um.empty()) { 16 | for (char c : out) { 17 | if (um.count(c)) { // um关键字中有该字符 18 | cout << c; 19 | //每输出一个字符就在um中将该字符个数减1 20 | //如果字符个数为0,就将该元素从um中删除 21 | if (--um[c] == 0) { 22 | um.erase(c); 23 | } 24 | } 25 | } 26 | } 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /PAT/Basic Level/1045. 快速排序.md: -------------------------------------------------------------------------------- 1 | 请参考[PAT A-1101. Quick Sort](../Advanced%20Level/1101.%20Quick%20Sort.md) -------------------------------------------------------------------------------- /PAT/Basic Level/1046. 划拳.md: -------------------------------------------------------------------------------- 1 | # 【PAT B-1046】划拳 2 | 3 | ## 题意概述 4 | 5 | 酒桌上两人划拳的方法为:每人口中喊出一个数字,同时用手比划出一个数字。如果谁比划出的数字正好等于两人喊出的数字之和,谁就赢了,输家罚一杯酒。两人同赢或两人同输则继续下一轮,直到唯一的赢家出现。 6 | 7 | 下面给出甲、乙两人的划拳记录,请你统计他们最后分别喝了多少杯酒。 8 | 9 | ## 输入输出格式 10 | 11 | 输入第一行先给出一个正整数,随后 N 行,每行给出一轮划拳的记录,格式为:`甲喊 甲划 乙喊 乙划`。其中喊是喊出的数字,划是划出的数字。 12 | 13 | 在一行中先后输出甲、乙两人喝酒的杯数,其间以一个空格分隔。 14 | 15 | ## 数据规模 16 | 17 | $0 23 | using namespace std; 24 | using gg = long long; 25 | int main() { 26 | ios::sync_with_stdio(false); 27 | cin.tie(0); 28 | gg ni, ans1 = 0, ans2 = 0; 29 | cin >> ni; 30 | while (ni--) { 31 | gg a1, a2, b1, b2; 32 | cin >> a1 >> a2 >> b1 >> b2; 33 | if (a2 == a1 + b1 and b2 != a1 + b1) { 34 | ++ans2; 35 | } else if (a2 != a1 + b1 and b2 == a1 + b1) { 36 | ++ans1; 37 | } 38 | } 39 | cout << ans1 << ' ' << ans2; 40 | return 0; 41 | } 42 | ``` 43 | -------------------------------------------------------------------------------- /PAT/Basic Level/1047. 编程团体赛.md: -------------------------------------------------------------------------------- 1 | # 【PAT B-1047】编程团体赛 2 | 3 | ## 题意概述 4 | 5 | 编程团体赛的规则为:每个参赛队由若干队员组成;所有队员独立比赛;参赛队的成绩为所有队员的成绩和;成绩最高的队获胜。 6 | 现给定所有队员的比赛成绩,请你编写程序找出冠军队。 7 | 8 | ## 输入输出格式 9 | 10 | 输入第一行给出一个正整数 N,即所有参赛队员总数。随后 N 行,每行给出一位队员的成绩,格式为`队伍编号-队员编号 成绩`,其中队伍编号为 1 到 1000 的正整数,队员编号为 1 到 10 的正整数,成绩为 0 到 100 的整数。 11 | 12 | 在一行中输出冠军队的编号和总成绩,其间以一个空格分隔。注意:题目保证冠军队是唯一的。 13 | 14 | ## 数据规模 15 | 16 | $$N\le{10}^4$$ 17 | 18 | ## 算法设计 19 | 20 | 由于队伍编号是为 1 到 1000 的正整数,我们可以开一个长为 1005 的数组 h 作哈希表,下标是队伍编号,元素的值为队伍成绩。然后输出 h 中的最大值即可。 21 | 22 | ## C++代码 23 | 24 | ```cpp 25 | #include 26 | using namespace std; 27 | using gg = long long; 28 | int main() { 29 | ios::sync_with_stdio(false); 30 | cin.tie(0); 31 | gg ni, ki, si; 32 | cin >> ni; 33 | array h{}; 34 | while (ni--) { 35 | char ci; 36 | cin >> ki >> ci >> si >> si; 37 | h[ki] += si; 38 | } 39 | auto i = max_element(h.begin(), h.end()); 40 | cout << (i - h.begin()) << ' ' << *i; 41 | return 0; 42 | } 43 | ``` 44 | -------------------------------------------------------------------------------- /PAT/Basic Level/1048. 数字加密.md: -------------------------------------------------------------------------------- 1 | # 【PAT B-1048】数字加密 2 | 3 | ## 题意概述 4 | 5 | 本题要求实现一种数字加密方法。首先固定一个加密用正整数 A,对任一正整数 B,将其每 1 位数字与 A 的对应位置上的数字进行以下运算:对奇数位,对应位的数字相加后对 13 取余——这里用 J 代表 10、Q 代表 11、K 代表 12;对偶数位,用 B 的数字减去 A 的数字,若结果为负数,则再加 10。这里令个位为第 1 位。 6 | 7 | ## 输入输出格式 8 | 9 | 输入在一行中依次给出 A 和 B,其间以空格分隔。 10 | 11 | 在一行中输出加密后的结果。 12 | 13 | ## 数据规模 14 | 15 | A 和 B 均为不超过 100 位的正整数。 16 | 17 | ## 算法设计 18 | 19 | 首先要理解,第 1 位是字符串的末位,从右向左位数逐渐递增。用字符串读入两个整数 A 和 B,并通过字符串 C 来记录最后输出结果。如果直接遍历就需要定义两个索引分别从 A 字符串和 B 字符串的末位开始向前遍历,为了编码方便,不妨先将 A,B 字符串进行翻转。这样就可以只定义一个索引从开始位遍历即可。遍历过程中按要求操作,并将结果记录在 C 字符串中,最后将 C 字符串输出即可。 20 | 21 | ## 注意点 22 | 23 | 1. 字符串下标从 0 开始,而题目中个位从 1 开始编号,所以对于奇数位偶数位的处理要反过来。 24 | 2. 字符串 A 和字符串 B 的长度不定,可能 A 比 B 长,可能 B 比 A 长,可能 A、B 一样长,这点要特别注意。 25 | 26 | ## C++代码 27 | 28 | ```cpp 29 | #include 30 | using namespace std; 31 | using gg = long long; 32 | int main() { 33 | ios::sync_with_stdio(false); 34 | cin.tie(0); 35 | string ai, bi, c, h = "0123456789JQK"; 36 | cin >> ai >> bi; 37 | reverse(ai.begin(), ai.end()); 38 | reverse(bi.begin(), bi.end()); 39 | for (int i = 0; i < ai.size() or i < bi.size(); ++i) { 40 | int k1 = i < ai.size() ? ai[i] - '0' : 0, 41 | k2 = i < bi.size() ? bi[i] - '0' : 0; 42 | c.push_back(i % 2 == 0 ? h[(k1 + k2) % 13] : (10 + k2 - k1) % 10 + '0'); 43 | } 44 | reverse(c.begin(), c.end()); 45 | cout << c; 46 | return 0; 47 | } 48 | ``` 49 | -------------------------------------------------------------------------------- /PAT/Basic Level/1049. 数列的片段和.md: -------------------------------------------------------------------------------- 1 | 请参考[PAT A-1104. 数列的片段和](../Advanced%20Level/1104.%20Sum%20of%20Number%20Segments.md) 2 | -------------------------------------------------------------------------------- /PAT/Basic Level/1050. 螺旋矩阵.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | gg m, n, ni; 8 | cin >> ni; 9 | vector ai(ni); 10 | for (gg& i : ai) { 11 | cin >> i; 12 | } 13 | sort(ai.begin(), ai.end(), greater()); 14 | for (n = gg(sqrt(ni)); n > 0; --n) { //枚举n 15 | if (ni % n == 0) { 16 | m = ni / n; 17 | break; 18 | } 19 | } 20 | vector> ans(m, vector(n)); 21 | vector> direc{{0, 1}, {1, 0}, {0, -1}, {-1, 0}}; //方向 22 | gg d = 0, x = 0, y = 0; 23 | for (gg i = 0; i < ni; ++i) { 24 | ans[x][y] = ai[i]; //填充 25 | gg nx = x + direc[d][0], ny = y + direc[d][1]; 26 | if (nx >= 0 and nx < m and ny >= 0 and ny < n and ans[nx][ny] == 0) { 27 | x = nx, y = ny; 28 | } else { 29 | d = (d + 1) % 4; 30 | x += direc[d][0], y += direc[d][1]; 31 | } 32 | } 33 | for (auto& i : ans) { 34 | for (gg j = 0; j < i.size(); ++j) { 35 | cout << (j == 0 ? "" : " ") << i[j]; 36 | } 37 | cout << "\n"; 38 | } 39 | return 0; 40 | } -------------------------------------------------------------------------------- /PAT/Basic Level/1051. 复数乘法.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int main() { 4 | ios::sync_with_stdio(false); 5 | cin.tie(0); 6 | double r1, r2, p1, p2; 7 | cin >> r1 >> p1 >> r2 >> p2; 8 | double a = r1 * cos(p1) * r2 * cos(p2) - r1 * sin(p1) * r2 * sin(p2); 9 | double b = r1 * sin(p1) * r2 * cos(p2) + r1 * cos(p1) * r2 * sin(p2); 10 | a = a < 0 and a > -0.005 ? 0 : a; 11 | b = b < 0 and b > -0.005 ? 0 : b; 12 | cout << fixed << setprecision(2) << a << showpos << b << 'i'; 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /PAT/Basic Level/1052. 卖个萌.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | array, 3> e{}; //存储表情符号 8 | for (auto& v : e) { 9 | string line; 10 | getline(cin, line); //读取一行字符串 11 | // i负责查找'['的下标,j负责查找']'的下标 12 | for (auto i = line.find('['); i != -1;) { 13 | auto j = line.find(']', i); 14 | v.push_back(line.substr(i + 1, j - i - 1)); 15 | i = line.find('[', j); 16 | } 17 | } 18 | gg ki, ai; 19 | cin >> ki; 20 | while (ki--) { 21 | string out; //存储要输出的表情字符串 22 | bool f = true; //表示下标是否存在非法情况 23 | for (auto i = 0; i < 5; ++i) { 24 | cin >> ai; 25 | // v负责获取a是手眼口中哪个表情数组的下标 26 | const auto& v = i == 2 ? e[2] : (i == 0 or i == 4) ? e[0] : e[1]; 27 | if (ai - 1 >= v.size()) { //下标非法 28 | f = false; 29 | } else { 30 | out += v[ai - 1] + (i == 0 ? "(" : i == 3 ? ")" : ""); 31 | } 32 | } 33 | f ? cout << out << '\n' : cout << "Are you kidding me? @\\/@\n"; 34 | } 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /PAT/Basic Level/1053. 住房空置率.md: -------------------------------------------------------------------------------- 1 | # 【PAT B-1053】住房空置率 2 | 3 | ## 题意概述 4 | 5 | 在不打扰居民的前提下,统计住房空置率的一种方法是根据每户用电量的连续变化规律进行判断。判断方法如下: 6 | 7 | - 在观察期内,若存在超过一半的日子用电量低于某给定的阈值 e,则该住房为“可能空置”; 8 | - 若观察期超过某给定阈值 D 天,且满足上一个条件,则该住房为“空置”。 9 | 10 | 现给定某居民区的住户用电量数据,请你统计“可能空置”的比率和“空置”比率,即以上两种状态的住房占居民区住房总套数的百分比。 11 | 12 | ## 输入输出格式 13 | 14 | 输入第一行给出正整数 N,为居民区住房总套数;正实数 e,即低电量阈值;正整数 D,即观察期阈值。随后 N 行,每行按$K\ E_1\ E_2\ \cdots\ E_k$格式给出一套住房的用电量数据。其中 $K$ 为观察的天数,$K_i$ 为第 $i$ 天的用电量。 15 | 16 | 在一行中输出“可能空置”的比率和“空置”比率的百分比值,其间以一个空格分隔,保留小数点后 1 位。 17 | 18 | ## 数据规模 19 | 20 | $N \le 1000$ 21 | 22 | ## C++代码 23 | 24 | ```cpp 25 | #include 26 | using namespace std; 27 | using gg = long long; 28 | int main() { 29 | ios::sync_with_stdio(false); 30 | cin.tie(0); 31 | gg ni, di, ki, k1 = 0, k2 = 0; 32 | double ei, ai; 33 | cin >> ni >> ei >> di; 34 | for (gg i = 0; i < ni; ++i) { 35 | cin >> ki; 36 | gg num = 0; 37 | for (gg j = 0; j < ki; ++j) { 38 | cin >> ai; 39 | if (ai < ei) { 40 | ++num; 41 | } 42 | } 43 | if (num > ki / 2 and ki <= di) 44 | ++k1; 45 | else if (num > ki / 2 and ki > di) 46 | ++k2; 47 | } 48 | cout << fixed << setprecision(1); //保留一位小数 49 | cout << k1 * 100.0 / ni << "% " << k2 * 100.0 / ni << '%'; 50 | return 0; 51 | } 52 | ``` 53 | -------------------------------------------------------------------------------- /PAT/Basic Level/1054. 求平均值.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | gg ni, num = 0; 8 | cin >> ni; 9 | string si; 10 | double sum = 0; 11 | regex r("[+-]?\\d+(\\.\\d{0,2})?"); 12 | while (ni--) { 13 | cin >> si; 14 | if (not regex_match(si, r) or stod(si) > 1000 or stod(si) < -1000) { 15 | cout << "ERROR: " << si << " is not a legal number\n"; 16 | } else { 17 | ++num; 18 | sum += stod(si); 19 | } 20 | } 21 | cout << fixed << setprecision(2); 22 | if (num == 0) { 23 | cout << "The average of 0 numbers is Undefined"; 24 | } else if (num == 1) { 25 | cout << "The average of 1 number is " << sum; 26 | } else { 27 | cout << "The average of " << num << " numbers is " << sum / num; 28 | } 29 | return 0; 30 | } -------------------------------------------------------------------------------- /PAT/Basic Level/1055. 集体照.md: -------------------------------------------------------------------------------- 1 | 请参考[PAT A-1109. Group Photo](../Advanced%20Level/1109.%20Group%20Photo.md) -------------------------------------------------------------------------------- /PAT/Basic Level/1056. 组合数的和.md: -------------------------------------------------------------------------------- 1 | # 【PAT B-1056】组合数的和 2 | 3 | ## 题意概述 4 | 5 | 给定 N 个非 0 的个位数字,用其中任意 2 个数字都可以组合成 1 个 2 位的数字。要求所有可能组合出来的 2 位数字的和。例如给定 2、5、8,则可以组合出:25、28、52、58、82、85,它们的和为 330。 6 | 7 | ## 输入输出格式 8 | 9 | 输入在一行中先给出 N,随后给出 N 个不同的非 0 个位数字。数字间以空格分隔。 10 | 11 | 输出所有可能组合出来的 2 位数字的和。 12 | 13 | ## 数据规模 14 | 15 | $$1 25 | using namespace std; 26 | using gg = long long; 27 | int main() { 28 | ios::sync_with_stdio(false); 29 | cin.tie(0); 30 | gg ni; 31 | cin >> ni; 32 | gg ans = 0; 33 | vector ai(ni); 34 | for (gg& i : ai) { 35 | cin >> i; 36 | } 37 | for (gg i = 0; i < ni; ++i) { 38 | for (gg j = i + 1; j < ni; ++j) { 39 | ans += ai[i] * 10 + ai[j] + ai[j] * 10 + ai[i]; 40 | } 41 | } 42 | cout << ans; 43 | return 0; 44 | } 45 | ``` 46 | -------------------------------------------------------------------------------- /PAT/Basic Level/1057. 数零壹.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | string si; 8 | getline(cin, si); 9 | gg sum = accumulate(si.begin(), si.end(), 0, [](gg a, char c) { 10 | return a + (isalpha(c) ? tolower(c) - 'a' + 1 : 0); 11 | }); 12 | bitset<32> b(sum); 13 | cout << (sum == 0 ? 0 : (gg)log2(sum) + 1 - b.count()) << ' ' << b.count(); 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /PAT/Basic Level/1059. C语言竞赛.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | bool isPrime(gg n) { 5 | for (gg i = 2; i <= (gg)sqrt(n); ++i) 6 | if (n % i == 0) 7 | return false; 8 | return true; 9 | } 10 | int main() { 11 | ios::sync_with_stdio(false); 12 | cin.tie(0); 13 | gg ni, ki; 14 | string si; 15 | cin >> ni; 16 | unordered_map um; 17 | for (gg i = 1; i <= ni; ++i) { 18 | cin >> si; 19 | um[si] = i == 1 ? "Mystery Award" : isPrime(i) ? "Minion" : "Chocolate"; 20 | } 21 | cin >> ki; 22 | while (ki--) { 23 | cin >> si; 24 | cout << si << ": " << (um.count(si) ? um[si] : "Are you kidding?") 25 | << "\n"; 26 | if (um.count(si)) { 27 | um[si] = "Checked"; 28 | } 29 | } 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /PAT/Basic Level/1060. 爱丁顿数.md: -------------------------------------------------------------------------------- 1 | 请参考[PAT A-1117. Eddington Number](../Advanced%20Level/1117.%20Eddington%20Number.md) -------------------------------------------------------------------------------- /PAT/Basic Level/1061. 判断题.md: -------------------------------------------------------------------------------- 1 | # 【PAT B-1061】判断题 2 | 3 | ## 输入输出格式 4 | 5 | 输入在第一行给出两个正整数 N 和 M,分别是学生人数和判断题数量。第二行给出 M 个不超过 5 的正整数,是每道题的满分值。第三行给出每道题对应的正确答案,0 代表`非`,1 代表`是`。随后 N 行,每行给出一个学生的解答。数字间均以空格分隔。 6 | 7 | 按照输入的顺序输出每个学生的得分,每个分数占一行。 8 | 9 | ## 数据规模 10 | 11 | $$0< N,M \le 100$$ 12 | 13 | ## 算法设计 14 | 15 | 使用`vector>`类型将题目的满分值和正确答案存储起来。每读取一个学生的解答,将它和正确答案作对比,累加解答正确的题目的分值即可。 16 | 17 | ## C++代码 18 | 19 | ```cpp 20 | #include 21 | using namespace std; 22 | using gg = long long; 23 | int main() { 24 | ios::sync_with_stdio(false); 25 | cin.tie(0); 26 | gg ni, mi; 27 | cin >> ni >> mi; 28 | vector> problems(mi); 29 | for (auto i = 0; i < mi; ++i) 30 | cin >> problems[i][0]; 31 | for (auto i = 0; i < mi; ++i) 32 | cin >> problems[i][1]; 33 | while (ni--) { 34 | gg s = 0, ai; 35 | for (int i = 0; i < mi; ++i) { 36 | cin >> ai; 37 | if (ai == problems[i][1]) { 38 | s += problems[i][0]; 39 | } 40 | } 41 | cout << s << '\n'; 42 | } 43 | return 0; 44 | } 45 | ``` 46 | -------------------------------------------------------------------------------- /PAT/Basic Level/1062. 最简分数.md: -------------------------------------------------------------------------------- 1 | # 【PAT B-1062】最简分数 2 | 3 | ## 题意概述 4 | 5 | 一个分数一般写成两个整数相除的形式:N/M,其中 M 不为 0。最简分数是指分子和分母没有公约数的分数表示形式。现给定两个不相等的正分数$N_1/M_1$和$N_2/M_2$,要求你按从小到大的顺序列出它们之间分母为 K 的最简分数。 6 | 7 | ## 输入输出格式 8 | 9 | 输入在一行中按`N/M`的格式给出两个正分数,随后是一个正整数分母 K,其间以空格分隔。题目保证给出的所有整数都不超过 1000。 10 | 11 | 在一行中按`N/M`的格式列出两个给定分数之间分母为 K 的所有最简分数,按从小到大的顺序,其间以 1 个空格分隔。行首尾不得有多余空格。题目保证至少有 1 个输出。 12 | 13 | ## 算法设计 14 | 15 | 就样例来说,我们可以把 7/18 和 13/20 都通分成以 12 为分母的分数,即约为 4.67/12 和 7.8/12。那么在这两个分数之间的最简分数自然为 5/12 和 7/12。所以算法逻辑也就非常清晰了,将两个输入的分数均化成以给定整数为分母的分数,从小的分数的分子向大的分数的分子进行遍历,查找所有与给定整数互质(即最大公约数为 1)的分子,即为所求。 16 | 17 | ## 注意点 18 | 19 | 1. 输入的两个分数的谁大谁小不确定,需进行简单的判断。 20 | 2. 如果给出两个分数有以给定的 K 为分母的最简分数,则该分数不予输出。 21 | 22 | ## C++代码 23 | 24 | ```cpp 25 | #include 26 | using namespace std; 27 | using gg = long long; 28 | gg gcd(gg a, gg b) { return b == 0 ? a : gcd(b, a % b); } 29 | int main() { 30 | ios::sync_with_stdio(false); 31 | cin.tie(0); 32 | gg ki, a1, b1, a2, b2; 33 | char c; 34 | cin >> a1 >> c >> b1 >> a2 >> c >> b2 >> ki; 35 | double n1 = (a1 * 1.0 * ki / b1), n2 = (a2 * 1.0 * ki / b2); 36 | if (n1 > n2) 37 | swap(n1, n2); 38 | bool space = false; 39 | for (gg i = floor(n1 + 1); i <= ceil(n2 - 1); ++i) { 40 | if (gcd(i, ki) == 1) { 41 | cout << (space ? " " : "") << i << '/' << ki; 42 | space = true; 43 | } 44 | } 45 | return 0; 46 | } 47 | ``` 48 | -------------------------------------------------------------------------------- /PAT/Basic Level/1063. 计算谱半径.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | gg ni; 8 | cin >> ni; 9 | double ans = 0; 10 | while (ni--) { 11 | gg ai, bi; 12 | cin >> ai >> bi; 13 | ans = max(ans, hypot(ai, bi)); 14 | } 15 | cout << fixed << setprecision(2) << ans; 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /PAT/Basic Level/1064. 朋友数.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | gg ni; 8 | set s; 9 | cin >> ni; 10 | while (ni--) { 11 | gg sum = 0, ai; 12 | cin >> ai; 13 | do { 14 | sum += ai % 10; 15 | ai /= 10; 16 | } while (ai != 0); 17 | s.insert(sum); 18 | } 19 | cout << s.size() << '\n'; 20 | for (auto i = s.begin(); i != s.end(); ++i) { 21 | cout << (i == s.begin() ? "" : " ") << *i; 22 | } 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /PAT/Basic Level/1065. 单身狗.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | unordered_map um; //记录配偶ID 8 | gg ni, ai, bi; 9 | cin >> ni; 10 | while (ni--) { 11 | cin >> ai >> bi; 12 | um[ai] = bi; 13 | um[bi] = ai; 14 | } 15 | cin >> ni; 16 | set s; //记录是否出现在派对上并排序 17 | while (ni--) { 18 | cin >> ai; 19 | if (not um.count(ai) or not s.count(um[ai])) { 20 | s.insert(ai); 21 | } else { 22 | s.erase(um[ai]); 23 | } 24 | } 25 | cout << s.size() << '\n' << setfill('0'); 26 | for (auto i = s.begin(); i != s.end(); ++i) { 27 | cout << (i == s.begin() ? "" : " ") << setw(5) << *i; 28 | } 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /PAT/Basic Level/1066. 图像过滤.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | cout << setfill('0'); 8 | gg ni, mi, ai, bi, ri, ki; 9 | cin >> mi >> ni >> ai >> bi >> ri; 10 | for (auto i = 0; i < mi; ++i) { 11 | for (auto j = 0; j < ni; ++j) { 12 | cin >> ki; 13 | ki = ki >= ai and ki <= bi ? ri : ki; 14 | cout << setw(3) << ki << (j == ni - 1 ? '\n' : ' '); 15 | } 16 | } 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /PAT/Basic Level/1067. 试密码.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | string ci, in; 8 | gg ni; 9 | cin >> ci >> ni; //读取密码和输入次数 10 | cin.get(); //吸收换行符 11 | while (getline(cin, in) and in != "#") { 12 | if (in == ci) { //密码正确 13 | cout << "Welcome in\n"; 14 | break; 15 | } 16 | cout << "Wrong password: " << in << '\n'; 17 | if (--ni == 0) { //输入次数达到上限 18 | cout << "Account locked\n"; 19 | break; 20 | } 21 | } 22 | return 0; 23 | } -------------------------------------------------------------------------------- /PAT/Basic Level/1069. 微博转发抽奖.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | gg mi, ni, si; 8 | cin >> mi >> ni >> si; 9 | vector v(mi + 1); 10 | for (int i = 1; i < v.size(); ++i) 11 | cin >> v[i]; 12 | unordered_set us; //标志一个人已中过奖 13 | for (int i = si; i < v.size(); i += ni) { 14 | while (i < v.size() and us.count(v[i])) //中过奖则顺取下一位 15 | ++i; 16 | if (i < v.size()) { 17 | cout << v[i] << '\n'; 18 | us.insert(v[i]); 19 | } 20 | } 21 | if (us.empty()) //没有人中过奖 22 | cout << "Keep going..."; 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /PAT/Basic Level/1070. 结绳.md: -------------------------------------------------------------------------------- 1 | 请参考[PAT A-1125. Chain the Ropes.cpp](../Advanced%20Level/1125.%20Chain%20the%20Ropes.md) -------------------------------------------------------------------------------- /PAT/Basic Level/1071. 小赌怡情.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | gg ti, ki, n1, b, t, n2; 8 | cin >> ti >> ki; 9 | while (ki--) { 10 | cin >> n1 >> b >> t >> n2; 11 | if (t > ti) { 12 | cout << "Not enough tokens. Total = " << ti 13 | << ".\n"; 14 | } else { 15 | if ((b == 0 and n1 > n2) or (b == 1 and n1 < n2)) { 16 | ti += t; 17 | cout << "Win " << t << "! Total = " << ti 18 | << ".\n"; 19 | } else { 20 | ti -= t; 21 | cout << "Lose " << t << ". Total = " << ti 22 | << ".\n"; 23 | if (ti == 0) { 24 | cout << "Game Over.\n"; 25 | break; 26 | } 27 | } 28 | } 29 | } 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /PAT/Basic Level/1072. 开学寄语.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | gg ni, mi, ki, ai; 8 | cin >> ni >> mi; 9 | vector v(mi); 10 | for (gg i = 0; i < mi; ++i) { 11 | cin >> v[i]; 12 | } 13 | array ans{}; //存储学生人数和收缴的物品个数 14 | string name; 15 | while (ni--) { 16 | cin >> name >> ki; 17 | bool output = false; 18 | while (ki--) { 19 | cin >> ai; 20 | //判断物品ai是否应该被收缴 21 | if (any_of(v.begin(), v.end(), [ai](int a) { return a == ai; })) { 22 | if (not output) { 23 | cout << name << ':'; 24 | output = true; 25 | ++ans[0]; 26 | } 27 | //注意不足4位数字要在高位补0 28 | cout << ' ' << setfill('0') << setw(4) << ai; 29 | ++ans[1]; 30 | } 31 | } 32 | if (output) 33 | cout << '\n'; 34 | } 35 | cout << ans[0] << ' ' << ans[1]; 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /PAT/Basic Level/1075. 链表元素分类.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | vector> input(gg(1e6), {-1, -1}); 8 | gg start, ni, ki; 9 | cin >> start >> ni >> ki; 10 | for (gg i = 0; i < ni; ++i) { 11 | gg address, data, nextA; 12 | cin >> address >> data >> nextA; 13 | input[address] = {data, nextA}; 14 | } 15 | vector> lst(3); 16 | while (start != -1) { 17 | gg flag = input[start][0] < 0 ? 0 : input[start][0] > ki ? 2 : 1; 18 | lst[flag].push_back(start); 19 | start = input[start][1]; 20 | } 21 | lst[0].insert(lst[0].end(), lst[1].begin(), lst[1].end()); 22 | lst[0].insert(lst[0].end(), lst[2].begin(), lst[2].end()); 23 | cout << setfill('0'); 24 | for (gg i = 0; i < lst[0].size() - 1; ++i) { 25 | cout << setw(5) << lst[0][i] << " " << input[lst[0][i]][0] << " " 26 | << setw(5) << lst[0][i + 1] << "\n"; 27 | } 28 | cout << setw(5) << lst[0].back() << " " << input[lst[0].back()][0] 29 | << " -1\n"; 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /PAT/Basic Level/1076. Wifi密码.md: -------------------------------------------------------------------------------- 1 | # 【PAT B-1076】Wifi 密码 2 | 3 | ## 题意概述 4 | 5 | Wifi 密码是选择题答案的组合。当正确选项是 A、B、C、D 时,分别输出 1、2、3、4。 6 | 7 | ## 输入输出格式 8 | 9 | 输入第一行给出一个正整数 N,随后 N 行,每行按照“编号-答案”的格式给出一道题的 4 个选项,T 表示正确选项,F 表示错误选项。选项间用空格分隔。 10 | 11 | 在一行中输出 wifi 密码。 12 | 13 | ## 数据规模 14 | 15 | $$N \le 100$$ 16 | 17 | ## C++代码 18 | 19 | ```cpp 20 | #include 21 | using namespace std; 22 | using gg = long long; 23 | int main() { 24 | ios::sync_with_stdio(false); 25 | cin.tie(0); 26 | gg ni; 27 | cin >> ni; 28 | string si; 29 | while (cin >> si) { 30 | if (si.back() == 'T') { 31 | cout << (si[0] - 'A' + 1); 32 | } 33 | } 34 | return 0; 35 | } 36 | ``` 37 | -------------------------------------------------------------------------------- /PAT/Basic Level/1077. 互评成绩计算.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | gg ni, mi; 8 | cin >> ni >> mi; 9 | for (gg i = 0; i < ni; ++i) { 10 | gg g1, a; 11 | vector g2; 12 | cin >> g1; 13 | for (gg j = 0; j < ni - 1; ++j) { 14 | cin >> a; 15 | if (a >= 0 and a <= mi) { //只统计[0,mi]之内的分数 16 | g2.push_back(a); 17 | } 18 | } 19 | //找到最高和最低的成绩 20 | auto m = minmax_element(g2.begin(), g2.end()); 21 | //统计去除最高和最低的成绩后的分数总和 22 | gg g2a = accumulate(g2.begin(), g2.end(), 0) - *m.first - *m.second; 23 | //计算最终成绩 24 | cout << round((g1 + g2a * 1.0 / (g2.size() - 2)) / 2.0) << '\n'; 25 | } 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /PAT/Basic Level/1078. 字符串压缩与解压.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | string compress(const string& s) { //压缩 5 | string r; 6 | for (gg i = 0, j = 0; i < s.size(); i = j) { 7 | //找到下标i之后第一个与s[i]不同的字符的下标 8 | j = s.find_first_not_of(s[i], i); 9 | if (j == -1) 10 | j = s.size(); 11 | //压缩当前字符 12 | r += (j - i == 1 ? "" : to_string(j - i)) + 13 | string(1, s[i]); 14 | } 15 | return r; 16 | } 17 | string decompress(const string& s) { //解压 18 | string r; 19 | for (gg i = 0, j = 0; i < s.size(); i = j + 1) { 20 | //找到下标i之后第一个非数字字符的下标 21 | j = s.find_first_not_of("0123456789", i); 22 | //解析字符s[j]的个数 23 | gg k = j - i == 0 ? 1 : stoll(s.substr(i, j - i)); 24 | //解压s[j]字符 25 | r += string(k, s[j]); 26 | } 27 | return r; 28 | } 29 | int main() { 30 | ios::sync_with_stdio(false); 31 | cin.tie(0); 32 | string fi, si; 33 | getline(cin, fi); 34 | getline(cin, si); 35 | cout << (fi == "C" ? compress(si) : decompress(si)); 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /PAT/Basic Level/1079. 延迟的回文数.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | string Plus(const string& a, const string& b) { 5 | string ans; 6 | gg carry = 0; //进位 7 | for (gg i = a.size() - 1, j = b.size() - 1; i >= 0 or j >= 0 or carry != 0; --i, --j) { 8 | gg p1 = i >= 0 ? a[i] - '0' : 0, p2 = j >= 0 ? b[j] - '0' : 0; 9 | gg k = p1 + p2 + carry; 10 | ans.push_back(k % 10 + '0'); 11 | carry = k / 10; 12 | } 13 | reverse(ans.begin(), ans.end()); //要进行翻转 14 | return ans; 15 | } 16 | int main() { 17 | ios::sync_with_stdio(false); 18 | cin.tie(0); 19 | string a, b; 20 | cin >> a; 21 | for (gg i = 0; i < 10; ++i) { 22 | if (equal(a.begin(), a.end(), a.rbegin())) { //是回文数 23 | cout << a << " is a palindromic number.\n"; 24 | return 0; 25 | } 26 | b = a; 27 | reverse(b.begin(), b.end()); 28 | string c = Plus(a, b); 29 | cout << a << " + " << b << " = " << c << "\n"; 30 | a = c; 31 | } 32 | cout << "Not found in 10 iterations.\n"; 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /PAT/Basic Level/1082. 射击比赛.md: -------------------------------------------------------------------------------- 1 | # 【PAT B-1082】射击比赛 2 | 3 | ## 题意概述 4 | 5 | 本题目给出的射击比赛的规则非常简单,谁打的弹洞距离靶心最近,谁就是冠军;谁差得最远,谁就是菜鸟。本题给出一系列弹洞的平面坐标(x,y),请你编写程序找出冠军和菜鸟。我们假设靶心在原点(0,0)。 6 | 7 | ## 输入输出格式 8 | 9 | 输入在第一行中给出一个正整数 N。随后 N 行,每行按格式`ID x y`给出。题目保证每个运动员的编号不重复,且每人只打 1 枪。 10 | 11 | 输出冠军和菜鸟的ID。 12 | 13 | ## 数据规模 14 | 15 | $$N\le{10}^4$$ 16 | 17 | ## 算法设计 18 | 19 | 由于每个运动员只有 3 个信息:ID、x、y,我们可以用一个`array`类型存储它。将所有运动员的信息存储到一个 vector 中,然后可以使用 minmax_element 函数获取冠军和菜鸟。 20 | 21 | ## C++代码 22 | 23 | ```cpp 24 | #include 25 | using namespace std; 26 | using gg = long long; 27 | int main() { 28 | ios::sync_with_stdio(false); 29 | cin.tie(0); 30 | gg ni; 31 | cin >> ni; 32 | using Player = array; 33 | vector v(ni); 34 | for (gg i = 0; i < ni; ++i) { 35 | cin >> v[i][0] >> v[i][1] >> v[i][2]; 36 | } 37 | auto ans = minmax_element( 38 | v.begin(), v.end(), [](const Player& p1, const Player& p2) { 39 | return hypot(p1[1], p1[2]) < hypot(p2[1], p2[2]); 40 | }); 41 | cout << setfill('0') << setw(4) << (*ans.first)[0] << ' ' << setw(4) 42 | << (*ans.second)[0]; 43 | return 0; 44 | } 45 | ``` 46 | -------------------------------------------------------------------------------- /PAT/Basic Level/1083. 是否存在相等的差.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | gg ni, a; 8 | cin >> ni; 9 | map> m; //按键从大到小排序 10 | for (int i = 1; i <= ni; ++i) { 11 | cin >> a; 12 | ++m[abs(a - i)]; 13 | } 14 | for (auto& i : m) { 15 | if (i.second > 1) 16 | cout << i.first << ' ' << i.second << '\n'; 17 | } 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /PAT/Basic Level/1084. 外观数列.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | string si; 8 | gg ni; 9 | cin >> si >> ni; 10 | while (--ni) { 11 | string t; 12 | for (gg i = 0, j; i < si.size(); i = j) { 13 | j = si.find_first_not_of(si[i], i + 1); 14 | if (j == -1) 15 | j = si.size(); 16 | t += string(1, si[i]) + to_string(j - i); 17 | } 18 | si = t; 19 | } 20 | cout << si; 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /PAT/Basic Level/1086. 就不告诉你.md: -------------------------------------------------------------------------------- 1 | # 【PAT B-1086】就不告诉你 2 | 3 | ## 输入输出格式 4 | 5 | 输入在第一行给出两个不超过 1000 的正整数 A 和 B,其间以空格分隔。 6 | 7 | 在一行中倒着输出 A 和 B 的乘积。 8 | 9 | ## C++代码 10 | 11 | ```cpp 12 | #include 13 | using namespace std; 14 | using gg = long long; 15 | int main() { 16 | ios::sync_with_stdio(false); 17 | cin.tie(0); 18 | gg ai, bi; 19 | cin >> ai >> bi; 20 | ai *= bi; 21 | while (ai % 10 == 0) 22 | ai /= 10; 23 | while (ai != 0) { 24 | cout << ai % 10; 25 | ai /= 10; 26 | } 27 | return 0; 28 | } 29 | ``` 30 | -------------------------------------------------------------------------------- /PAT/Basic Level/1087. 有多少不同的值.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | gg ni; 8 | cin >> ni; 9 | unordered_set us; 10 | for (gg i = 1; i <= ni; ++i) { 11 | us.insert(i / 2 + i / 3 + i / 5); 12 | } 13 | cout << us.size(); 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /PAT/Basic Level/1088. 三人行.md: -------------------------------------------------------------------------------- 1 | # 【PAT B-1088】三人行 2 | 3 | ## 题意概述 4 | 5 | 子曰:`三人行,必有我师焉。择其善者而从之,其不善者而改之。` 6 | 7 | 本题给定甲、乙、丙三个人的能力值关系为:甲的能力值确定是 2 位正整数;把甲的能力值的 2 个数字调换位置就是乙的能力值;甲乙两人能力差是丙的能力值的 X 倍;乙的能力值是丙的 Y 倍。请你指出谁比你强应`从之`,谁比你弱应`改之`。 8 | 9 | ## 输入输出格式 10 | 11 | 输入在一行中给出三个正整数,依次为:M(你自己的能力值)、X 和 Y。 12 | 13 | 在一行中首先输出甲的能力值,随后依次输出甲、乙、丙三人与你的关系:如果其比你强,输出`Cong`;平等则输出`Ping`;比你弱则输出`Gai`。其间以 1 个空格分隔,行首尾不得有多余空格。注意:如果解不唯一,则以甲的最大解为准进行判断;如果解不存在,则输出`No Solution`。 14 | 15 | ## 数据规模 16 | 17 | $$0 31 | using namespace std; 32 | using gg = long long; 33 | int main() { 34 | ios::sync_with_stdio(false); 35 | cin.tie(0); 36 | array p{}; 37 | gg mi, xi, yi; 38 | cin >> mi >> xi >> yi; 39 | for (gg i = 99; i >= 10; --i) { 40 | gg j = i % 10 * 10 + i / 10; 41 | p = {i * 1.0, j * 1.0, j * 1.0 / yi}; 42 | if (abs(p[2] - abs(i - j) * 1.0 / xi) < 1e-6) { 43 | cout << p[0]; 44 | for (auto i : p) { 45 | cout << ' ' << (i > mi ? "Cong" : i < mi ? "Gai" : "Ping"); 46 | } 47 | return 0; 48 | } 49 | } 50 | cout << "No Solution"; 51 | return 0; 52 | } 53 | ``` 54 | -------------------------------------------------------------------------------- /PAT/Basic Level/1089. 狼人杀-简单版.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | gg ni; 8 | cin >> ni; 9 | vector input(ni + 1); 10 | for (gg i = 1; i <= ni; ++i) { 11 | cin >> input[i]; 12 | } 13 | for (gg i = 1; i <= ni; ++i) { // i号玩家是狼人 14 | for (gg j = i + 1; j <= ni; ++j) { // j号玩家是狼人 15 | gg lier = 0, wolflier = 0; 16 | for (gg k = 1; k <= ni; ++k) { 17 | if (input[k] > 0 xor (abs(input[k]) != i and 18 | abs(input[k]) != j)) { // k号玩家在撒谎 19 | ++lier; 20 | if (k == i or k == j) { //狼人在撒谎 21 | ++wolflier; 22 | } 23 | } 24 | } 25 | if (lier == 2 and wolflier == 1) { //找到了一组解 26 | cout << i << " " << j; 27 | return 0; 28 | } 29 | } 30 | } 31 | cout << "No Solution"; 32 | return 0; 33 | } -------------------------------------------------------------------------------- /PAT/Basic Level/1090. 危险品装箱.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | int main() { 5 | ios::sync_with_stdio(false); 6 | cin.tie(0); 7 | gg ni, mi, ki, ai, bi; 8 | cin >> ni >> mi; 9 | //存储不相容的物品对 10 | unordered_map> um; 11 | while (ni--) { 12 | cin >> ai >> bi; 13 | um[ai].insert(bi); 14 | um[bi].insert(ai); 15 | } 16 | while (mi--) { 17 | cin >> ki; 18 | unordered_set us; 19 | while (ki--) { 20 | cin >> ai; 21 | us.insert(ai); 22 | } 23 | for (auto i : us) { //遍历货物清单 24 | if (um.count(i)) { //有不相容的物品 25 | for (auto j : um[i]) { //遍历不相容的物品 26 | if (us.count(j)) { //不相容的物品在该箱中 27 | cout << "No\n"; 28 | goto loop; 29 | } 30 | } 31 | } 32 | } 33 | cout << "Yes\n"; 34 | loop:; 35 | } 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /PAT/Basic Level/1091. N-自守数.md: -------------------------------------------------------------------------------- 1 | # 【PAT B-1091】N-自守数 2 | 3 | ## 题意概述 4 | 5 | 如果某个数 K 的平方乘以 N 以后,结果的末尾几位数等于 K,那么就称这个数为`N-自守数`。例如$3\times{92}^2=25392$,而 25392 的末尾两位正好是 92,所以 92 是一个 3-自守数。 6 | 7 | 本题就请你编写程序判断一个给定的数字是否关于某个 N 是 N-自守数。 8 | 9 | ## 输入输出格式 10 | 11 | 输入在第一行中给出正整数 M,随后一行给出 M 个待检测的、不超过 1000 的正整数。 12 | 13 | 对每个需要检测的数字,如果它是 N-自守数就在一行中输出最小的 N 和$NK^2$的值,以一个空格隔开;否则输出`No`。 14 | 15 | ## 数据规模 16 | 17 | $$N<10,M\le20$$ 18 | 19 | ## 算法设计 20 | 21 | 由于要比较 NK^2 的末尾几位与 K 的大小关系,我们可以对$NK^2$进行求余运算。假设 K 有 i 位数,则将$NK^2$对${10}^i$求余的结果与 K 进行比较,看是否相等即可得出结果。关键如何确定 m 是多少呢?我们可以额外设置一个变量 m,初始化为 1。定义一个循环,循环中让 K 每次除以 10 并向下取整,同时令 m 每次乘 10。当 K 的值变成 0 时,有$m={10}^i$。 22 | 23 | ## C++代码 24 | 25 | ```cpp 26 | #include 27 | using namespace std; 28 | using gg = long long; 29 | int main() { 30 | ios::sync_with_stdio(false); 31 | cin.tie(0); 32 | gg mi, ki; 33 | cin >> mi; 34 | while (mi--) { 35 | cin >> ki; 36 | gg m = 1; 37 | for (gg i = ki; i != 0; i /= 10) 38 | m *= 10; 39 | for (gg n = 1; n < 10; ++n) { 40 | if (n * ki * ki % m == ki) { 41 | cout << n << ' ' << n * ki * ki << '\n'; 42 | goto loop; 43 | } 44 | } 45 | cout << "No\n"; 46 | loop:; 47 | } 48 | return 0; 49 | } 50 | ``` 51 | -------------------------------------------------------------------------------- /PAT/Basic Level/1092. 最好吃的月饼.md: -------------------------------------------------------------------------------- 1 | # 【PAT B-1092】最好吃的月饼 2 | 3 | ## 输入输出格式 4 | 5 | 输入首先给出两个正整数 N 和 M,分别为月饼的种类数(于是默认月饼种类从 1 到 N 编号)和参与统计的城市数量。接下来 M 行,每行给出 N 个非负整数(均不超过${10}^6$),其中第 i 个整数为第 i 种月饼的销量(块)。数字间以空格分隔。 6 | 7 | 在第一行中输出最大销量,第二行输出销量最大的月饼的种类编号。如果冠军不唯一,则按编号递增顺序输出并列冠军。数字间以 1 个空格分隔,行首尾不得有多余空格。 8 | 9 | ## 数据规模 10 | 11 | $$N\le1000,M\le100$$ 12 | 13 | ## C++代码 14 | 15 | ```cpp 16 | #include 17 | using namespace std; 18 | using gg = long long; 19 | int main() { 20 | ios::sync_with_stdio(false); 21 | cin.tie(0); 22 | gg ni, mi, ai; 23 | cin >> ni >> mi; 24 | vector v(ni); 25 | while (mi--) { 26 | for (int i = 0; i < v.size(); ++i) { 27 | cin >> ai; 28 | v[i] += ai; 29 | } 30 | } 31 | gg ans = *max_element(v.begin(), v.end()); 32 | cout << ans << '\n'; 33 | bool space = false; 34 | for (gg i = 0; i < v.size(); ++i) { 35 | if (v[i] == ans) { 36 | cout << (space ? " " : "") << (i + 1); 37 | space = true; 38 | } 39 | } 40 | return 0; 41 | } 42 | ``` 43 | -------------------------------------------------------------------------------- /PAT/Basic Level/1093. 字符串A+B.md: -------------------------------------------------------------------------------- 1 | # 【PAT B-1093】字符串 A+B 2 | 3 | ## 题意概述 4 | 5 | 给定两个字符串 A 和 B,本题要求你输出 A+B,即两个字符串的并集。要求先输出 A,再输出 B,但重复的字符必须被剔除。 6 | 7 | ## 输入输出格式 8 | 9 | 输入在两行中分别给出 A 和 B。 10 | 11 | 在一行中输出题面要求的 A 和 B 的和。 12 | 13 | ## 数据规模 14 | 15 | A 和 B 均为长度不超过${10}^6$的、由可见 ASCII 字符和空格组成的、由回车标识结束的非空字符串。 16 | 17 | ## 算法设计 18 | 19 | 由于 ASCII 码只有 128 位,可以定义 bitset<128>类型变量 h 来记录字符是否出现过。然后遍历 A 和 B 两个字符串,输出第一次出现的字符并随时更新 h 即可。 20 | 21 | ## C++代码 22 | 23 | ```cpp 24 | #include 25 | using namespace std; 26 | int main() { 27 | ios::sync_with_stdio(false); 28 | cin.tie(0); 29 | string s; 30 | bitset<128> h; 31 | while (getline(cin, s)) { 32 | for (char c : s) { 33 | if (not h[c]) { 34 | h[c] = true; 35 | cout << c; 36 | } 37 | } 38 | } 39 | return 0; 40 | } 41 | ``` 42 | -------------------------------------------------------------------------------- /PAT/Basic Level/1094. 谷歌的招聘.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | using gg = long long; 4 | bool isPrime(gg n) { 5 | if (n < 2) // n小于2,一定不是素数 6 | return false; 7 | for (gg i = 2; i <= (gg)sqrt(n); ++i) //遍历2~根号n所有的数 8 | if (n % i == 0) // n能被i整除,说明n不是素数 9 | return false; 10 | return true; // n不能被2~n任何数整除,则n是素数 11 | } 12 | int main() { 13 | ios::sync_with_stdio(false); 14 | cin.tie(0); 15 | gg li, ki; 16 | string s; 17 | cin >> li >> ki >> s; 18 | for (int i = 0; i < s.size() - ki + 1; ++i) { 19 | string n = s.substr(i, ki); 20 | if (isPrime(stoll(n))) { 21 | cout << n; 22 | return 0; 23 | } 24 | } 25 | cout << "404"; 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /PAT/Basic Level/1095. 解码PAT准考证.md: -------------------------------------------------------------------------------- 1 | 请参考[1153. Decode Registration Card of PAT](../Advanced%20Level/1153.%20Decode%20Registration%20Card%20of%20PAT.md) -------------------------------------------------------------------------------- /书籍勘误.md: -------------------------------------------------------------------------------- 1 | 本文是对书籍《算法详解(C++11 语言描述)》的勘误说明,尽管在出版之前,我和出版社编辑都对书籍进行了多次校对,但书籍中还是存在一些错误,由此对您造成的不便,深感抱歉。 2 | 3 | 1. 第 31 页 1.10 节,例题 1-5【PAT B-1071】的【C++代码】中,第 12、16、19 行代码中,原文中的错误描述为`Total=`,正确的描述为`Total = `,即`=`两端应各有一个空格字符。 4 | 2. 第 371 页例题 12-8【PAT A-1086】的【C++代码】中,第 4 行代码中,原文中的错误描述为`gg left,ggright`,正确的描述为`gg left,gg right`,即`ggright`中缺少一个空格字符。 5 | 3. 第 428 页,拓扑排序的第 4 行代码中,原文中的错误描述为`vectortop(MAX),degree(MAX)`,正确的描述为`vectortop,degree(MAX)`,即`top`应定义成空的`vector`。 6 | 4. 第 434 页 14.5.2 节,原文的错误描述为`将v加入到S_{unknown}集合中,并更新v所邻接的顶点的dis值`,正确的描述应为`将v加入到S_{known}集合中,并更新v所邻接的顶点的dis值`,即要把$S_{unknown}$改为$S_{known}$。 7 | 5. 第 436 页第 17 行代码,原文的错误描述为`if(dis[p[0]]!=p[1])`,正确的描述应为`if(dis[p[1]]!=p[0])`。 8 | 6. 第 500 页 16.2 节,原文的错误描述为`你需要保证在运行本章的程序时,你使用的编译器支持C++17。你需要保证在运行本节的程序时,你使用的编译器支持C++17。`,正确的描述应为`你需要保证在运行本章的程序时,你使用的编译器支持C++17。`,即文字重复了 2 次。 9 | --------------------------------------------------------------------------------