├── .DS_Store ├── README.md └── 算法笔记讲解 ├── .DS_Store ├── PPT ├── .DS_Store ├── 算法笔记讲解第1~3章.key └── 算法笔记讲解第4章.key └── SourceCode ├── .DS_Store ├── 第七章 数据结构专题一 栈队列链表 ├── .DS_Store ├── 7.1 栈 │ ├── .DS_Store │ ├── A1051 Pop Sequence .cpp │ └── 简单计算器.cpp ├── 7.2 队列 │ ├── .DS_Store │ └── A1056 Mice and Rice.cpp └── 7.3 链表 │ ├── .DS_Store │ ├── A1032 Sharing.cpp │ ├── A1052 Linked List Sorting.cpp │ ├── A1074_Reversing Linked List .cpp │ └── A1097_Deduplication on a Linked List.cpp ├── 第三章 入门模拟 ├── .DS_Store ├── A1002 A+B for Polynomials.cpp ├── A1009 Product of Polynomials.cpp ├── A1042 Shuffling Machine.cpp ├── A1046 Shortest Distance.cpp ├── A1065 A+B and C (64bit).cpp ├── B1001 害死人不偿命的(3n+1)猜想.cpp ├── B1008 数组元素循环右移问题.cpp ├── B1009 说反话 .cpp ├── B1010 一元多项式求导.cpp ├── B1011 A+B 和 C.cpp ├── B1012 数字分类.cpp ├── B1016 部分A+B.cpp ├── B1018 锤子剪刀布.cpp ├── B1022 D进制的A+B.cpp ├── B1026 程序运行时间.cpp ├── B1032 挖掘机技术哪家强.cpp ├── B1036 跟奥巴马一起编程.cpp └── B1046 划拳 .cpp ├── 第九章 数据结构专题二树 ├── .DS_Store ├── 9.2 二叉树的遍历 │ ├── .DS_Store │ ├── A1020 Tree Traversals.cpp │ ├── A1086 Tree Traversals Again.cpp │ └── A1102 Invert a Binary Tree.cpp ├── 9.3 树的遍历 │ ├── .DS_Store │ ├── A1004 Counting Leaves.cpp │ ├── A1053 Path of Equal Weight.cpp │ ├── A1079 Total Sales of Supply Chain.cpp │ ├── A1090 Highest Price in Supply Chain.cpp │ ├── A1094 The Largest Generation.cpp │ └── A1106 Lowest Price in Supply Chain.cpp ├── 9.4 二叉树 │ ├── .DS_Store │ ├── A1043_Is It a Binary Search Tree_晴神法.cpp │ ├── A1043_Is It a Binary Search Tree_柳神法.cpp.cpp │ ├── A1064 Complete Binary Search Tree.cpp │ └── A1099 Build A Binary Search Tree.cpp ├── 9.5 平衡二叉树 │ ├── .DS_Store │ └── A1066 Root of AVL Tree.cpp ├── 9.6 并查集 │ ├── .DS_Store │ ├── A1107 Social Clusters .cpp │ ├── 为什么不能直接使用father[i]而要用findFather(i).png │ └── 好朋友.cpp └── 9.7 堆 │ └── A1098 Insertion or Heap Sort.cpp ├── 第五章 数学问题 ├── .DS_Store ├── 5.1简单数学 │ ├── .DS_Store │ ├── A1008 Elevator.cpp │ ├── A1049 Counting Ones .cpp │ ├── A1069 The Black Hole of Numbers.cpp │ ├── A1104 Sum of Number Segments .cpp │ └── B1003 我要通过!.cpp ├── 5.2最大公约数与最小公倍数 │ ├── .DS_Store │ └── B1008 数组元素循环右移问题.cpp ├── 5.3分数的四则运算 │ ├── .DS_Store │ ├── A1081 Rational Sum.cpp │ └── A1088 Rational Arithmetic.cpp ├── 5.4素数 │ ├── .DS_Store │ ├── A1015 Reversible Primes.cpp │ ├── A1078 Hashing.cpp │ ├── B1007 素数对猜想.cpp │ └── B1013 数素数.cpp ├── 5.5质因子分解 │ ├── .DS_Store │ ├── A1059 Prime Factors.cpp │ └── A1096 Consecutive Factors.cpp └── 5.6大整数运算 │ ├── .DS_Store │ ├── A1023 Have Fun with Numbers.cpp │ ├── A1024 Palindromic Number.cpp │ └── B1017 A除以B.cpp ├── 第八章 搜索专题DFS与BFS ├── .DS_Store ├── A1091 Acute Stroke.cpp └── A1103 Integer Factorization.cpp ├── 第六章 C++标准模版库介绍 ├── .DS_Store ├── 6.1 vector │ ├── .DS_Store │ ├── A1039 Course List for Student .cpp │ └── A1047 Student List for Course.cpp ├── 6.2 set │ ├── .DS_Store │ └── A1063 Set Similarity .cpp ├── 6.3 string │ ├── .DS_Store │ └── A1060 Are They Equal .cpp └── 6.4 map │ ├── .DS_Store │ ├── A1022 Digital Librar.cpp │ ├── A1054 The Dominant Color.cpp │ ├── A1071 Speech Patterns.cpp │ └── A1100 Mars Numbers.cpp ├── 第十章 图算法专题 └── 10.3 图的遍历 │ ├── .DS_Store │ ├── A1013 Battle Over Cities.cpp │ ├── A1021 Deepest Root .cpp │ ├── A1034 Head of a Gang.cpp │ └── A1076 Forwards on Weibo .cpp └── 第四章 算法初步 ├── .DS_Store ├── TwoPointers ├── .DS_Store ├── A1029_Median.cpp ├── A1085 Perfect Sequenc_upper_bound().cpp └── A1089_Insert or Merge.cpp ├── 二分 ├── .DS_Store ├── A1010_Radix.cpp ├── A1044_Shopping in Mars.cpp ├── A1085 Perfect Sequenc_upper_bound().cpp ├── A1085 Perfect Sequence_BinarySearch.cpp └── 木棒切割问题.cpp ├── 其他 ├── A1093_Count PAT's.cpp └── A1101_Quick Sort .cpp ├── 排序 ├── .DS_Store ├── A1012 The Best Rank.cpp ├── A1016 Phone Bills_统一法.cpp ├── A1016 Phone Bills_追及法.cpp ├── A1025 PAT Ranking .cpp ├── A1028 List Sorting.cpp ├── A1055 The World's Richest.cpp ├── A1062 Talent and Virtue.cpp ├── A1075 PAT Judge.cpp ├── A1080 Graduate Admission.cpp ├── A1083 List Grades.cpp └── A1095 Cars on Campus.cpp ├── 散列 ├── .DS_Store ├── A1041 Be Unique.cpp ├── A1048 Find Coins.cpp ├── A1050 String Subtraction.cpp ├── A1084 Broken Keyboard.cpp ├── A1092 To Buy or Not to Buy.cpp ├── B1005 继续(3n+1)猜想.cpp ├── B1033 旧键盘打字.cpp ├── B1038 统计同成绩学生.cpp ├── B1042 字符统计.cpp ├── B1043 输出PATest.cpp └── B1047 编程团体赛 .cpp └── 贪心 ├── .DS_Store ├── A1033 To Fill or Not to Fill .cpp ├── A1037 Magic Coupon .cpp ├── A1038 Recover the Smallest Number .cpp ├── A1067 Sort with Swap(0, i) .cpp ├── B1020 月饼 .cpp └── B1023 组个最小数.cpp /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/merelydust/Data-Structure-and-Algorithm/8e4d7dcd4793d10af9cce5d8714d4ec1a177f0eb/.DS_Store -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 数据结构和算法 2 | 3 | ### 费曼学习法 4 | 5 | *什么是费曼学习法?* 一言以蔽之,以教促学。 6 | 7 | 详细四步骤: 8 | 9 | 1. 对一样新东西,解释给一无所知的“小孩子”听(要不断地举实例)。 10 | 2. 找到你理解较困难的/无法解释清楚的知识点。 11 | 3. 回顾手头资料,加强巩固该知识点,直到弄懂。 12 | 4. 重复以上三个步骤,直到你能**简单准确**地描述这一块知识。 13 | 14 | 额外参考:[我的算法笔记一周目](https://github.com/merelydust/PAT-Advanced-Level/tree/master/%E7%AE%97%E6%B3%95%E7%AC%94%E8%AE%B0) 15 | -------------------------------------------------------------------------------- /算法笔记讲解/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/merelydust/Data-Structure-and-Algorithm/8e4d7dcd4793d10af9cce5d8714d4ec1a177f0eb/算法笔记讲解/.DS_Store -------------------------------------------------------------------------------- /算法笔记讲解/PPT/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/merelydust/Data-Structure-and-Algorithm/8e4d7dcd4793d10af9cce5d8714d4ec1a177f0eb/算法笔记讲解/PPT/.DS_Store -------------------------------------------------------------------------------- /算法笔记讲解/PPT/算法笔记讲解第1~3章.key: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/merelydust/Data-Structure-and-Algorithm/8e4d7dcd4793d10af9cce5d8714d4ec1a177f0eb/算法笔记讲解/PPT/算法笔记讲解第1~3章.key -------------------------------------------------------------------------------- /算法笔记讲解/PPT/算法笔记讲解第4章.key: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/merelydust/Data-Structure-and-Algorithm/8e4d7dcd4793d10af9cce5d8714d4ec1a177f0eb/算法笔记讲解/PPT/算法笔记讲解第4章.key -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/merelydust/Data-Structure-and-Algorithm/8e4d7dcd4793d10af9cce5d8714d4ec1a177f0eb/算法笔记讲解/SourceCode/.DS_Store -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第七章 数据结构专题一 栈队列链表/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/merelydust/Data-Structure-and-Algorithm/8e4d7dcd4793d10af9cce5d8714d4ec1a177f0eb/算法笔记讲解/SourceCode/第七章 数据结构专题一 栈队列链表/.DS_Store -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第七章 数据结构专题一 栈队列链表/7.1 栈/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/merelydust/Data-Structure-and-Algorithm/8e4d7dcd4793d10af9cce5d8714d4ec1a177f0eb/算法笔记讲解/SourceCode/第七章 数据结构专题一 栈队列链表/7.1 栈/.DS_Store -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第七章 数据结构专题一 栈队列链表/7.1 栈/A1051 Pop Sequence .cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | int main() { 6 | int m, n, k; scanf("%d %d %d", &m, &n, &k); 7 | int arr[1010] = {0}; 8 | while (k--) { 9 | stack s; 10 | for (int i = 0; i < n; ++i) scanf("%d", &arr[i]); 11 | int now = 0; 12 | for (int i = 1; i <= n && now < n && s.size() < m; ++i) { 13 | s.push(i); 14 | while (!s.empty() && s.top() == arr[now] && now < n) { 15 | s.pop(); ++now; 16 | } 17 | } 18 | if (now < n) printf("NO\n"); 19 | else printf("YES\n"); 20 | } 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第七章 数据结构专题一 栈队列链表/7.1 栈/简单计算器.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | using namespace std; 9 | 10 | struct node { 11 | double num; 12 | char op; 13 | bool flag; // true表示操作数 false表示操作符 14 | }; 15 | 16 | string str; 17 | stack s; // 操作栈 18 | queue q; // 后缀表达式序列 19 | map opRank; // 标记操作符优先级 20 | 21 | void change() { // 将中缀表达式变成后缀表达式 22 | node tmp; 23 | for (int i = 0; i < str.length();) { 24 | if (isdigit(str[i])) { 25 | tmp.flag = true; 26 | tmp.num = str[i++] - '0'; 27 | while (i < str.length() && isdigit(str[i])) tmp.num = tmp.num * 10 + str[i++] - '0'; 28 | q.push(tmp); 29 | } 30 | else { 31 | tmp.flag = false; 32 | tmp.op = str[i]; 33 | while (!s.empty() && opRank[tmp.op] <= opRank[s.top().op]) { 34 | q.push(s.top()); s.pop(); 35 | } 36 | s.push(tmp); 37 | ++i; 38 | } 39 | } 40 | while (!s.empty()) { 41 | q.push(s.top()); s.pop(); 42 | } 43 | } 44 | 45 | double cal() { 46 | double tmp1, tmp2; // 每个操作符有需要两个操作数 47 | node cur, tmp; 48 | while (!q.empty()) { 49 | cur = q.front(); 50 | q.pop(); 51 | if (cur.flag) s.push(cur); 52 | else { 53 | tmp2 = s.top().num; s.pop(); 54 | tmp1 = s.top().num; s.pop(); 55 | tmp.flag = true; // 临时记录操作数 56 | switch (cur.op) { 57 | case '+': tmp.num = tmp1 + tmp2; 58 | break; 59 | case '-': tmp.num = tmp1 - tmp2; 60 | break; 61 | case '*': tmp.num = tmp1 * tmp2; 62 | break; 63 | case '/': tmp.num = tmp1 / tmp2; 64 | break; 65 | } 66 | s.push(tmp); 67 | } 68 | } 69 | return s.top().num; 70 | } 71 | 72 | int main() { 73 | opRank['+'] = opRank['-'] = 1; 74 | opRank['*'] = opRank['/'] = 2; 75 | while (getline(cin, str) && str != "0") { 76 | for (auto it = str.end(); it != str.begin(); --it) { 77 | if (*it == ' ') str.erase(it); // 去除表达式中的空格 78 | } 79 | while (!s.empty()) s.pop(); 80 | change(); 81 | printf("%.2lf\n", cal()); 82 | } 83 | return 0; 84 | } 85 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第七章 数据结构专题一 栈队列链表/7.2 队列/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/merelydust/Data-Structure-and-Algorithm/8e4d7dcd4793d10af9cce5d8714d4ec1a177f0eb/算法笔记讲解/SourceCode/第七章 数据结构专题一 栈队列链表/7.2 队列/.DS_Store -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第七章 数据结构专题一 栈队列链表/7.2 队列/A1056 Mice and Rice.cpp: -------------------------------------------------------------------------------- 1 | /*** 2 | 思路: 3 | 用队列模拟 每轮取group次(队列前ng个人做比较) 建组不够ng就提前break 4 | 每轮被淘汰的人名次=晋级组数+1 5 | 每小组优胜者推入队列 6 | ***/ 7 | #include 8 | #include 9 | using namespace std; 10 | 11 | struct node { 12 | int w, rank; 13 | }; 14 | 15 | int main() { 16 | int np, ng; scanf("%d %d", &np, &ng); 17 | node arr[1010]; 18 | for (int i = 0; i < np; ++i) scanf("%d", &arr[i].w); 19 | queue Q; int index; 20 | for (int i = 0; i < np; ++i) { 21 | scanf("%d", &index); Q.push(index); 22 | } 23 | int now = np, group = 0; // 当前剩余人数 当前组数 24 | while (Q.size() > 1) { 25 | group = now / ng; 26 | if (now % ng) ++group; 27 | for (int i = 0; i < group; ++i) { 28 | int maxId = Q.front(); 29 | for (int j = 0; j < ng; ++j) { 30 | if (i * ng + j == now) break; 31 | if (arr[Q.front()].w > arr[maxId].w) maxId = Q.front(); 32 | arr[Q.front()].rank = group + 1; 33 | Q.pop(); 34 | } 35 | Q.push(maxId); 36 | } 37 | now = group; 38 | } 39 | arr[Q.front()].rank = 1; 40 | for (int i = 0; i < np; ++i) { 41 | if (i) printf(" "); 42 | printf("%d", arr[i].rank); 43 | } 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第七章 数据结构专题一 栈队列链表/7.3 链表/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/merelydust/Data-Structure-and-Algorithm/8e4d7dcd4793d10af9cce5d8714d4ec1a177f0eb/算法笔记讲解/SourceCode/第七章 数据结构专题一 栈队列链表/7.3 链表/.DS_Store -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第七章 数据结构专题一 栈队列链表/7.3 链表/A1032 Sharing.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | const int maxn = 100010; 3 | int nexts[maxn], hashtable[maxn] = {0}; 4 | 5 | int main() { 6 | int head1, head2, n; scanf("%d %d %d", &head1, &head2, &n); 7 | int address, next; char data; 8 | for (int i = 0; i < n; ++i) { 9 | scanf("%d %c %d", &address, &data, &next); 10 | nexts[address] = next; 11 | } 12 | int p; 13 | for (p = head1; p != -1; p = nexts[p]) hashtable[p] = 1; 14 | for (p = head2; p != -1; p = nexts[p]) { 15 | if (hashtable[p]) break; 16 | } 17 | if (p == -1) printf("-1\n"); 18 | else printf("%05d\n", p); 19 | } 20 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第七章 数据结构专题一 栈队列链表/7.3 链表/A1052 Linked List Sorting.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | const int maxn = 100010; 5 | 6 | struct node { 7 | int address, data, next; 8 | bool flag; // 标记是否为有效节点 9 | }nodes[maxn]; 10 | 11 | bool cmp(node a, node b) { 12 | return a.flag != b.flag ? a.flag > b.flag : a.data < b.data; 13 | } 14 | 15 | int main() { 16 | for (int i = 0; i < maxn; ++i) nodes[i].flag = false; 17 | int n, head; scanf("%d %d", &n, &head); 18 | for (int i = 0; i < n; ++i) { 19 | int a, b, c; scanf("%d %d %d", &a, &b, &c); 20 | nodes[a] = {a, b, c}; 21 | } 22 | int cnt = 0; 23 | for (int p = head; p != -1; p = nodes[p].next) { 24 | nodes[p].flag = true; 25 | ++cnt; 26 | } 27 | if (!cnt) { // 最后一个测试点 在给定头节点的情况下居然会没有有效节点= =? 28 | printf("0 -1\n"); return 0; 29 | } 30 | sort(nodes, nodes+maxn, cmp); 31 | printf("%d %05d\n", cnt, nodes[0].address); 32 | for (int i = 0; i < cnt; ++i) { 33 | printf("%05d %d ", nodes[i].address, nodes[i].data); 34 | if (i != cnt-1) printf("%05d\n", nodes[i+1].address); 35 | else printf("-1\n"); 36 | } 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第七章 数据结构专题一 栈队列链表/7.3 链表/A1074_Reversing Linked List .cpp: -------------------------------------------------------------------------------- 1 | /*** 2 | 建立结构体node 存储本身地址 data next地址 3 | 建立vector validNodes 4 | 晴神的思路 把vector分为n/k块 每块反转输出 每个节点的next等于它前一个的地址 5 | 每块末尾节点的next等于前一块末尾的地址preEnd 6 | ***/ 7 | #include 8 | #include 9 | #include 10 | using namespace std; 11 | 12 | const int maxn = 100010; 13 | struct node { 14 | int address, data, next; 15 | }nodes[maxn]; 16 | 17 | int main() { 18 | int head, n, k; scanf("%d %d %d", &head, &n, &k); 19 | node tmp; 20 | for (int i = 0; i < n; ++i) { 21 | scanf("%d %d %d", &tmp.address, &tmp.data, &tmp.next); 22 | nodes[tmp.address] = tmp; 23 | } 24 | bool end = false; 25 | bool begin = true; 26 | int i =0; 27 | while (!end) { 28 | stack s; vector v; 29 | while (s.size() < k) { 30 | s.push(nodes[head]); v.push_back(nodes[head]); 31 | if (nodes[head].next == -1) { 32 | end = true; break; // 已经是最后一个节点 33 | } 34 | head = nodes[head].next; 35 | } 36 | if (s.size() == k) { 37 | while (!s.empty()) { 38 | node now = s.top(); 39 | if(!begin) printf("%05d\n", now.address); 40 | printf("%05d %d ", now.address, now.data); 41 | s.pop(); 42 | if(!s.empty()){ 43 | node next = s.top(); 44 | printf("%05d\n", next.address); 45 | begin = true; 46 | }else{ 47 | if (i+1==n) printf("-1\n"); 48 | begin = false; 49 | } 50 | i++; 51 | } 52 | } 53 | else { 54 | for (int j = 0, len = v.size(); j < len; ++j) { 55 | if(!begin) printf("%05d\n", v[j].address); 56 | printf("%05d %d ", v[j].address, v[j].data); 57 | if (v[j].next == -1) printf("-1\n"); 58 | else printf("%05d\n", v[j+1].address); 59 | begin = true; 60 | } 61 | } 62 | 63 | } 64 | return 0; 65 | } 66 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第七章 数据结构专题一 栈队列链表/7.3 链表/A1097_Deduplication on a Linked List.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | const int maxn = 100010; 7 | int hashtable[maxn] = {0}; 8 | struct node { 9 | int address, data, next; 10 | }nodes[maxn]; 11 | 12 | int main() { 13 | int head, n; scanf("%d %d", &head, &n); 14 | node tmp; 15 | while (n--) { 16 | scanf("%d %d %d", &tmp.address, &tmp.data, &tmp.next); 17 | nodes[tmp.address] = tmp; 18 | } 19 | node headNode = nodes[head]; bool end = false; 20 | vector uv, v; 21 | while (!end) { 22 | if (hashtable[abs(headNode.data)]) v.push_back(headNode); 23 | else { 24 | uv.push_back(headNode); hashtable[abs(headNode.data)] = 1; 25 | } 26 | if (headNode.next == -1) break; 27 | headNode = nodes[headNode.next]; 28 | } 29 | for (int i = 0, len = uv.size(); i < len; ++i) { 30 | printf("%05d %d ", uv[i].address, uv[i].data); 31 | if (i == len-1) printf("-1\n"); 32 | else printf("%05d\n", uv[i+1].address); 33 | } 34 | for (int i = 0, len = v.size(); i < len; ++i) { 35 | printf("%05d %d ", v[i].address, v[i].data); 36 | if (i == len-1) printf("-1\n"); 37 | else printf("%05d\n", v[i+1].address); 38 | } 39 | } 40 | 41 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第三章 入门模拟/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/merelydust/Data-Structure-and-Algorithm/8e4d7dcd4793d10af9cce5d8714d4ec1a177f0eb/算法笔记讲解/SourceCode/第三章 入门模拟/.DS_Store -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第三章 入门模拟/A1002 A+B for Polynomials.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | int main() { 6 | int k1, k2; 7 | map> m; 8 | cin >> k1; 9 | while (k1--) { 10 | int ex; double co; 11 | cin >> ex >> co; m[ex] += co; 12 | } 13 | cin >> k2; 14 | while (k2--) { 15 | int ex; double co; 16 | cin >> ex >> co; m[ex] += co; 17 | } 18 | map::iterator it; 19 | int cnt = 0; 20 | for (it = m.begin(); it != m.end(); it++) { 21 | if (it->second) cnt++; // 系数为0不输出 22 | } 23 | cout << cnt; 24 | for (it = m.begin(); it != m.end(); it++) { 25 | if (it->second) printf(" %d %.1f", it->first, it->second); 26 | } 27 | return 0; 28 | } 29 | 30 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第三章 入门模拟/A1009 Product of Polynomials.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | int main() { 6 | int k1, k2; 7 | map > m; 8 | double n1[10][2], n2[10][2]; // 乘法不像加法 指数会变 所以开两个二维数组方便计算 9 | cin >> k1; 10 | for (int i = 0; i < k1; i++) { 11 | int ex; double co; 12 | cin >> ex >> co; 13 | n1[i][0] = ex; 14 | n1[i][1] = co; 15 | } 16 | cin >> k2; 17 | for (int i = 0; i < k2; i++) { 18 | int ex; double co; 19 | cin >> ex >> co; 20 | n2[i][0] = ex; 21 | n2[i][1] = co; 22 | } 23 | for (int i = 0; i < k1; i++) { 24 | for (int j = 0; j < k2; j++) { 25 | int ex = int(n1[i][0]) + int(n2[j][0]); 26 | double co = n1[i][1] * n2[j][1]; 27 | m[ex] += co; 28 | } 29 | } 30 | map::iterator it; int cnt = 0; 31 | for (it = m.begin(); it != m.end(); ++it) { 32 | if (it->second) cnt++; 33 | } 34 | cout << cnt; 35 | for (it = m.begin(); it != m.end(); it++) { 36 | if (!it->second) continue; 37 | printf(" %d %.1f", it->first, it->second); 38 | } 39 | printf("\n"); 40 | return 0; 41 | } 42 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第三章 入门模拟/A1042 Shuffling Machine.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | const int maxn = 60; 6 | 7 | int main() { 8 | int k; scanf("%d", &k); 9 | int order[maxn], givenOrder[maxn], newOrder[maxn]; string cards[maxn], card; 10 | for (int i = 1; i <= 54; ++i) { 11 | scanf("%d", &givenOrder[i]); order[i] = i; 12 | } 13 | for (int i = 1; i <= 54; ++i) { 14 | int num = i % 13; if (num % 13 == 0) num += 13; 15 | if (i < 14) card = "S" + to_string(num); 16 | else if (i < 27) card = "H" + to_string(num); 17 | else if (i < 40) card = "C" + to_string(num); 18 | else if (i < 53) card = "D" + to_string(num); 19 | else card = "J" + to_string(i % 13); 20 | cards[i] = card; 21 | } 22 | while (k--) { 23 | for (int i = 1; i <= 54; ++i) newOrder[givenOrder[i]] = order[i]; // 新位置 = givenOrder让order去的位置 24 | memcpy(order, newOrder, sizeof(order)); // 更新初始顺序 25 | } 26 | for (int i = 1; i <= 54; ++i) { 27 | cout << cards[order[i]]; 28 | if (i != 54) cout << " "; 29 | else cout << endl; 30 | } 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第三章 入门模拟/A1046 Shortest Distance.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | const int maxn = 100010; 5 | int sumDis[maxn] = {0}; // 从点i到点i+1的顺时针累计距离 6 | 7 | int main() { 8 | int n, tmp, circle = 0; scanf("%d", &n); 9 | for (int i = 1; i <= n; ++i) { 10 | scanf("%d", &tmp); sumDis[i] = sumDis[i-1] + tmp; circle += tmp; 11 | } 12 | int m, s, e; scanf("%d", &m); 13 | while (m--) { 14 | scanf("%d %d", &s, &e); if (s > e) swap(s, e); 15 | int tmp = sumDis[e-1] - sumDis[s-1]; // 去i而不是i+1 所以索引-1 16 | printf("%d\n", min(tmp, circle-tmp)); 17 | } 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第三章 入门模拟/A1065 A+B and C (64bit).cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int main() { 5 | int n; cin >> n; 6 | for (int i = 1; i <= n; i++) { 7 | long long a, b, c; 8 | cin >> a >> b >> c; 9 | long long d = a + b; 10 | printf("Case #%d: ", i); 11 | if (a < 0 && b < 0 && d >= 0) { 12 | printf("false\n"); 13 | continue; 14 | } 15 | if ((a > 0 && b > 0 && d <= 0) || (a+b > c)) printf("true\n"); 16 | else printf("false\n"); 17 | } 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第三章 入门模拟/B1001 害死人不偿命的(3n+1)猜想.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int main() { 5 | int n; scanf("%d", &n); 6 | int cnt = 0; 7 | while (n != 1) { 8 | if (n % 2) { // 如果n是奇数 9 | n = (3*n + 1) / 2; 10 | } 11 | else n /= 2; // 如果n是偶数 12 | cnt++; 13 | } 14 | printf("%d\n", cnt); 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第三章 入门模拟/B1008 数组元素循环右移问题.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | const int maxn = 110; 4 | 5 | int main() { 6 | int n, m; scanf("%d %d", &n, &m); int arr[maxn] = {0}; 7 | for (int i = 0; i < n; ++i) scanf("%d", &arr[i]); 8 | m %= n; // 避免重复移动 9 | for (int i = n-m; i < n; ++i) printf("%d ", arr[i]); 10 | for (int i = 0; i < n-m; ++i) { 11 | printf("%d", arr[i]); 12 | if (i != n-m-1) printf(" "); 13 | else printf("\n"); 14 | } 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第三章 入门模拟/B1009 说反话 .cpp: -------------------------------------------------------------------------------- 1 | #include // 涉及到字符串 用iostream更方便 2 | #include 3 | using namespace std; 4 | 5 | int main() { 6 | string word[80]; int cnt = 0; 7 | while (cin >> word[cnt]) cnt++; // 保存所有读入的单词 8 | for (int i = cnt-1; i >= 0; i--) { 9 | cout << word[i]; 10 | if (i) cout << ' '; 11 | else cout << endl; // i=0时说明是最后一个单词 不输出空格 12 | } 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第三章 入门模拟/B1010 一元多项式求导.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int main() { 5 | int co, index; 6 | int cnt = 0; 7 | while (cin >> co >> index) { 8 | if (index) { 9 | if (cnt) cout << ' '; 10 | co = index * co; 11 | --index; 12 | cout << co << ' ' << index; 13 | cnt++; 14 | } 15 | } 16 | if (cnt == 0) cout << "0 0"; 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第三章 入门模拟/B1011 A+B 和 C.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int main() { 5 | int t; scanf("%d", &t); 6 | long long a, b, c; 7 | for (int i = 1; i <= t; ++i) { 8 | scanf("%lld %lld %lld", &a, &b, &c); 9 | printf("Case #%d: ", i); 10 | if (a + b > c) printf("true\n"); 11 | else printf("false\n"); 12 | } 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第三章 入门模拟/B1012 数字分类.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | int main() { 8 | int n, tmp; scanf("%d", &n); 9 | int a[10] = {0}; bool find[10] = {0}; double a4, sum4 = 0.0; int cnt4 = 0; 10 | int mark2 = 1; 11 | while (n--) { 12 | scanf("%d", &tmp); int mod = tmp % 5; 13 | if (tmp % 10 == 0) { 14 | a[1] += tmp; find[1] = true; 15 | } 16 | else if (mod == 1) { 17 | a[2] += mark2 * tmp; mark2 *= -1; find[2] = true; 18 | } 19 | else if (mod == 2) { 20 | ++a[3]; find[3] = true; 21 | } 22 | else if (mod == 3) { 23 | sum4 += 1.0 * tmp; find[4] = true; ++cnt4; 24 | } 25 | else if (mod == 4) { 26 | a[5] = max(a[5], tmp); find[5] = true; 27 | } 28 | } 29 | if (find[4]) a4 = sum4 / cnt4; 30 | for (int i = 1; i <= 5; ++i) { 31 | if (i != 1) printf(" "); 32 | if (!find[i]) printf("N"); 33 | else if (i == 4) printf("%.1f", a4); 34 | else printf("%d", a[i]); 35 | } printf("\n"); 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第三章 入门模拟/B1016 部分A+B.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | int main() { 7 | string sa, sb; char da, db; long long a = 0, b = 0; 8 | cin >> sa >> da >> sb >> db; 9 | int nDa = int(count(sa.begin(), sa.end(), da)); 10 | if (nDa) { 11 | string tmpa(nDa, da); a = stoll(tmpa); 12 | } 13 | int nDb = int(count(sb.begin(), sb.end(), db)); 14 | if (nDb) { 15 | string tmpb(nDb, db); b = stoll(tmpb); 16 | } 17 | cout << a + b << endl; 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第三章 入门模拟/B1018 锤子剪刀布.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int main() { 5 | int jiawin = 0, yiwin = 0, same = 0; 6 | int jia[3] = {0}; 7 | int yi[3] = {0}; 8 | int n; 9 | cin >> n; 10 | while (n--) { 11 | char g1, g2; 12 | cin >> g1 >> g2; 13 | if (g1 == 'B' && g2 == 'C') { 14 | jiawin++; 15 | jia[0]++; 16 | } 17 | else if (g1 == 'C' && g2 == 'J') { 18 | jiawin++; 19 | jia[1]++; 20 | } 21 | else if (g1 == 'J' && g2 == 'B') { 22 | jiawin++; 23 | jia[2]++; 24 | } 25 | else if (g2 == 'B' && g1 == 'C') { 26 | yiwin++; 27 | yi[0]++; 28 | } 29 | else if (g2 == 'C' && g1 == 'J') { 30 | yiwin++; 31 | yi[1]++; 32 | } 33 | else if (g2 == 'J' && g1 == 'B') { 34 | yiwin++; 35 | yi[2]++; 36 | } 37 | else same++; 38 | } 39 | cout << jiawin << ' ' << same << ' ' << yiwin << endl; 40 | cout << yiwin << ' '<< same << ' ' << jiawin << endl; 41 | int maxjia = jia[0] >= jia[1] ? 0 : 1; // 注意是>= 优先选择字典序小的 42 | maxjia = jia[maxjia] >= jia[2] ? maxjia : 2; 43 | int maxyi = yi[0] >= yi[1] ? 0 : 1; 44 | maxyi = yi[maxyi] >= yi[2] ? maxyi : 2; 45 | char ges[3] = {'B', 'C', 'J',}; 46 | cout << ges[maxjia] << ' ' << ges[maxyi]; 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第三章 入门模拟/B1022 D进制的A+B.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int main() { 5 | int a, b, c, d; scanf("%d %d %d", &a, &b, &d); 6 | c = a + b; 7 | int arr[31] = {0}, len = 0; // 数组模拟数字 8 | do { 9 | arr[len++] = c % d; // 数组低位对应数字低位 10 | c /= d; 11 | } while (c); 12 | for (int i = len-1; i >= 0; --i) printf("%d", arr[i]); // 从高位到低位输出 13 | printf("\n"); 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第三章 入门模拟/B1026 程序运行时间.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | int main() { 6 | double c1, c2; scanf("%lf %lf", &c1, &c2); 7 | int seconds = (c2-c1+50) / 100; // +50是为了四舍五入 如果小数位>=50 则+50后整数位+1 8 | int hour = seconds / 3600; 9 | seconds %= 3600; 10 | int minute = seconds / 60; 11 | seconds %= 60; 12 | printf("%02d:%02d:%02d\n", hour, minute, seconds); 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第三章 入门模拟/B1032 挖掘机技术哪家强.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int school[100010] = {0}; // 学校数量<=参赛人数 5 | 6 | int main() { 7 | int n; scanf("%d", &n); 8 | int ans = -1, index, sch, grade; // 初始化最高分为-1 最高分学校 所属学校 选手得分 9 | while (n--) { 10 | scanf("%d %d", &sch, &grade); school[sch] += grade; 11 | if (school[sch] > ans) { // 更新最高分 12 | ans = school[sch]; index = sch; 13 | } 14 | } 15 | printf("%d %d\n", index, ans); 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第三章 入门模拟/B1036 跟奥巴马一起编程.cpp: -------------------------------------------------------------------------------- 1 | /*** 2 | 正方形一共四条边 上边下边正常循环打印即可 3 | 左右两边 因为计算机是一行一行打印的 所以每一行只在行首行尾打印字符 中间是空格 4 | ***/ 5 | 6 | #include 7 | using namespace std; 8 | 9 | int main() { 10 | int n; char ch; scanf("%d %c", &n, &ch); 11 | for (int i = 0; i < n; ++i) printf("%c", ch); // 打印上边 12 | printf("\n"); 13 | for (int i = 2, row = n / 2 + n % 2; i < row; ++i) { // 去除上下边 n如果是奇数 四舍五入行数要+1 14 | printf("%c", ch); // 行首 15 | for (int j = 0; j < n-2; ++j) printf(" "); // 中间n-2个空格 16 | printf("%c\n", ch); // 行尾 换行 17 | } 18 | for (int i = 0; i < n; ++i) printf("%c", ch); // 打印下边 19 | printf("\n"); 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第三章 入门模拟/B1046 划拳 .cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int main() { 5 | int n; cin >> n; 6 | int jia = 0, yi = 0; 7 | for (int i = 0; i < n; ++i) { 8 | int jiahan, jiahua, yihan, yihua; 9 | cin >> jiahan >> jiahua >> yihan >> yihua; 10 | int s = jiahan + yihan; 11 | if (s == jiahua && s != yihua) yi++; 12 | if (s == yihua && s != jiahua) jia++; 13 | } 14 | cout << jia << ' ' << yi << endl; 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第九章 数据结构专题二树/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/merelydust/Data-Structure-and-Algorithm/8e4d7dcd4793d10af9cce5d8714d4ec1a177f0eb/算法笔记讲解/SourceCode/第九章 数据结构专题二树/.DS_Store -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第九章 数据结构专题二树/9.2 二叉树的遍历/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/merelydust/Data-Structure-and-Algorithm/8e4d7dcd4793d10af9cce5d8714d4ec1a177f0eb/算法笔记讲解/SourceCode/第九章 数据结构专题二树/9.2 二叉树的遍历/.DS_Store -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第九章 数据结构专题二树/9.2 二叉树的遍历/A1020 Tree Traversals.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | const int maxn = 40; 6 | int post[maxn], in[maxn]; 7 | 8 | struct node { 9 | int data; 10 | node* left; 11 | node* right; 12 | node() { 13 | left = right = NULL; 14 | } 15 | }; 16 | 17 | node* create(int postL, int postR, int inL, int inR) { 18 | if (postL > postR) return NULL; 19 | node* root = new node; 20 | root->data = post[postR]; 21 | int pos = inL; 22 | while (in[pos] != root->data) ++pos; 23 | int numLeft = pos - inL; 24 | root->left = create(postL, postL+numLeft-1, inL, pos-1); 25 | root->right = create(postL+numLeft, postR-1, pos+1, inR); 26 | return root; 27 | } 28 | 29 | void layerTra(node* root) { 30 | queue Q; 31 | Q.push(root); 32 | while (!Q.empty()) { 33 | node* fro = Q.front(); 34 | if (fro->data != root->data) printf(" "); 35 | printf("%d", fro->data); 36 | Q.pop(); 37 | if (fro->left != NULL) Q.push(fro->left); 38 | if (fro->right != NULL) Q.push(fro->right); 39 | } 40 | printf("\n"); 41 | } 42 | 43 | int main() { 44 | int n; scanf("%d", &n); 45 | for (int i = 0; i < n; ++i) scanf("%d", &post[i]); 46 | for (int i = 0; i < n; ++i) scanf("%d", &in[i]); 47 | node* root = create(0, n-1, 0, n-1); 48 | layerTra(root); 49 | return 0; 50 | } 51 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第九章 数据结构专题二树/9.2 二叉树的遍历/A1086 Tree Traversals Again.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | vector pre, in, post, value; 8 | void create(int root, int inL, int inR) { // root-根节点在前序序列中的下标 9 | if (inL > inR) return; 10 | int pos = inL; 11 | while (in[pos] != pre[root] && pos < inR) ++pos; 12 | int numLeft = pos - inL; 13 | create(root+1, inL, pos-1); // 推入左子树 14 | create(root+1+numLeft, pos+1, inR); // 推入右子树 15 | post.push_back(pre[root]); // 推入根节点 16 | } 17 | 18 | int main() { 19 | int n, data, key = 0; 20 | scanf("%d", &n); 21 | char str[10] = {0}; 22 | stack s; 23 | while (~scanf("%s", str)) { 24 | if (strlen(str) == 4) { 25 | scanf("%d", &data); 26 | value.push_back(data); 27 | s.push(key); 28 | pre.push_back(key++); 29 | } 30 | else { 31 | in.push_back(s.top()); 32 | s.pop(); 33 | } 34 | } 35 | create(0, 0, n-1); 36 | printf("%d", value[post[0]]); 37 | for (int i = 1; i < n; ++i) printf(" %d", value[post[i]]); 38 | printf("\n"); 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第九章 数据结构专题二树/9.2 二叉树的遍历/A1102 Invert a Binary Tree.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | const int maxn = 20; 6 | bool isLeaf[maxn] = {0}, inq[maxn] = {0}; 7 | struct node { 8 | int left, right; 9 | node() { 10 | left = right = -1; 11 | } 12 | }nodes[maxn]; 13 | 14 | void invert(int root) { 15 | if (root == -1) return; 16 | invert(nodes[root].left); 17 | invert(nodes[root].right); 18 | swap(nodes[root].left, nodes[root].right); 19 | } 20 | 21 | void layerTra(int root) { 22 | if (root == -1) return; 23 | queue Q; 24 | Q.push(root); inq[root] = true; 25 | while (!Q.empty()) { 26 | int fro = Q.front(); 27 | if (fro != root) printf(" "); 28 | printf("%d", fro); 29 | Q.pop(); 30 | if (nodes[fro].left != -1) Q.push(nodes[fro].left); 31 | if (nodes[fro].right != -1) Q.push(nodes[fro].right); 32 | } 33 | printf("\n"); 34 | } 35 | 36 | int cnt = 0, n; 37 | void inorderTra(int Root) { 38 | if (Root == -1) return; 39 | inorderTra(nodes[Root].left); 40 | printf("%d", Root); ++cnt; 41 | if (cnt < n) printf(" "); 42 | inorderTra(nodes[Root].right); 43 | } 44 | 45 | int main() { 46 | scanf("%d", &n); 47 | char l, r; 48 | for (int i = 0; i < n; ++i) { 49 | scanf(" %c %c", &l, &r); // 最前的空格吸收换行符 50 | if (l == '-') nodes[i].left = -1; 51 | else { 52 | nodes[i].left = l - '0'; 53 | isLeaf[nodes[i].left] = true; 54 | } 55 | if (r == '-') nodes[i].right = -1; 56 | else { 57 | nodes[i].right = r - '0'; 58 | isLeaf[nodes[i].right] = true; 59 | } 60 | } 61 | int root = -1; 62 | for (int i = 0; i < n; ++i) { 63 | if (!isLeaf[i]) { 64 | root = i; break; 65 | } 66 | } 67 | invert(root); 68 | layerTra(root); 69 | inorderTra(root); printf("\n"); 70 | return 0; 71 | } 72 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第九章 数据结构专题二树/9.3 树的遍历/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/merelydust/Data-Structure-and-Algorithm/8e4d7dcd4793d10af9cce5d8714d4ec1a177f0eb/算法笔记讲解/SourceCode/第九章 数据结构专题二树/9.3 树的遍历/.DS_Store -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第九章 数据结构专题二树/9.3 树的遍历/A1004 Counting Leaves.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | const int maxn = 110; 6 | 7 | int n, m, id, k, child; 8 | vector v[maxn]; 9 | map mp; 10 | 11 | void dfs(int now, int layer) { 12 | if (v[now].empty()) { 13 | ++mp[layer]; 14 | return; 15 | } 16 | for (int i = 0; i < v[now].size(); ++i) { 17 | dfs(v[now][i], layer+1); 18 | } 19 | } 20 | 21 | int main() { 22 | scanf("%d", &n); 23 | if (!n) return 0; 24 | scanf("%d", &m); 25 | for (int i = 0; i < m; ++i) { 26 | scanf("%d %d", &id, &k); 27 | while (k--) { 28 | scanf("%d", &child); 29 | v[id].push_back(child); 30 | } 31 | } 32 | dfs(1, 1); 33 | int maxLayer = mp.rbegin()->first; 34 | for (int i = 1; i <= maxLayer; ++i) { 35 | printf("%d", mp[i]); 36 | if (i != maxLayer) printf(" "); 37 | else printf("\n"); 38 | } 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第九章 数据结构专题二树/9.3 树的遍历/A1053 Path of Equal Weight.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | int n, m, s; 6 | vector seq; 7 | 8 | struct node { 9 | int w; 10 | vector children; 11 | }nodes[110]; 12 | 13 | bool cmp(int a, int b) { 14 | return nodes[a].w > nodes[b].w; 15 | } 16 | 17 | void dfs(int now, int sum) { 18 | if (nodes[now].children.empty() && sum == s) { 19 | for (int i = 0; i < seq.size(); ++i) { 20 | printf("%d", nodes[seq[i]].w); 21 | if (i != seq.size()-1) printf(" "); 22 | else printf("\n"); 23 | } 24 | return; 25 | } 26 | if (sum > s || nodes[now].children.empty()) return; 27 | for (int i = 0; i < nodes[now].children.size(); ++i) { 28 | seq.push_back(nodes[now].children[i]); 29 | dfs(seq.back(), sum + nodes[seq.back()].w); 30 | seq.pop_back(); 31 | } 32 | } 33 | 34 | int main() { 35 | scanf("%d %d %d", &n, &m, &s); 36 | for (int i = 0; i < n; ++i) scanf("%d", &nodes[i].w); 37 | for (int i = 0; i < m; ++i) { 38 | int index, k, child; 39 | scanf("%d %d", &index, &k); 40 | while (k--) { 41 | scanf("%d", &child); 42 | nodes[index].children.push_back(child); 43 | } 44 | sort(nodes[index].children.begin(), nodes[index].children.end(), cmp); 45 | } 46 | seq.push_back(0); 47 | dfs(0, nodes[0].w); 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第九章 数据结构专题二树/9.3 树的遍历/A1079 Total Sales of Supply Chain.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | const int maxn = 100010; 6 | double rootPrice, r, ans; 7 | 8 | struct node { 9 | int products; 10 | vector children; 11 | }nodes[maxn]; 12 | 13 | void dfs(int now, int layer) { 14 | if (nodes[now].children.empty()) { 15 | ans += nodes[now].products * rootPrice * pow(1+r, layer); // 根的layer是0 即没有加价 16 | return; 17 | } 18 | for (int i = 0; i < nodes[now].children.size(); ++i) { 19 | dfs(nodes[now].children[i], layer+1); 20 | } 21 | } 22 | 23 | int main() { 24 | int n; 25 | ans = 0; 26 | scanf("%d %lf %lf", &n, &rootPrice, &r); 27 | r /= 100; 28 | for (int i = 0; i < n; ++i) { 29 | int k, child; scanf("%d", &k); 30 | if (k == 0) scanf("%d", &nodes[i].products); 31 | while (k--) { 32 | scanf("%d", &child); 33 | nodes[i].children.push_back(child); 34 | } 35 | } 36 | dfs(0, 0); 37 | printf("%.1f\n", ans); 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第九章 数据结构专题二树/9.3 树的遍历/A1090 Highest Price in Supply Chain.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | using namespace std; 6 | const int maxn = 100010; 7 | 8 | int n, father, root, maxLayer, cnt; 9 | double rootPrice, r; 10 | vector children[maxn]; 11 | 12 | void dfs(int now, int layer) { 13 | if (children[now].empty()) { 14 | if (layer > maxLayer) { 15 | maxLayer = layer; 16 | cnt = 1; 17 | } 18 | else if (layer == maxLayer) ++cnt; 19 | return; 20 | } 21 | for (int i = 0; i < children[now].size(); ++i) { 22 | dfs(children[now][i], layer+1); 23 | } 24 | } 25 | 26 | int main() { 27 | scanf("%d %lf %lf", &n, &rootPrice, &r); 28 | r /= 100; 29 | for (int i = 0; i < n; ++i) { 30 | scanf("%d", &father); 31 | if (father != -1) children[father].push_back(i); 32 | else root = i; 33 | } 34 | maxLayer = 0; cnt = 0; 35 | dfs(root, 0); 36 | printf("%.2f %d\n", rootPrice * pow(1+r, maxLayer), cnt); 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第九章 数据结构专题二树/9.3 树的遍历/A1094 The Largest Generation.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | int n, m, id, k, child; 8 | vector v[110]; 9 | int mp[110] = {0}; 10 | 11 | void dfs(int now, int layer) { 12 | ++mp[layer]; 13 | if (v[now].empty()) return; 14 | for (int i = 0; i < v[now].size(); ++i) dfs(v[now][i], layer+1); 15 | } 16 | 17 | int main() { 18 | int n, m; scanf("%d %d", &n, &m); 19 | for (int i = 0; i < m; ++i) { 20 | scanf("%d %d", &id, &k); 21 | while (k--) { 22 | scanf("%d", &child); v[id].push_back(child); 23 | } 24 | } 25 | dfs(1, 1); 26 | int maxLayer = 0, maxValue = -1; 27 | for (int i = 1; i < 110; ++i) { 28 | if (mp[i] > maxValue) { 29 | maxValue = mp[i]; maxLayer = i; 30 | } 31 | } 32 | printf("%d %d\n", maxValue, maxLayer); 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第九章 数据结构专题二树/9.3 树的遍历/A1106 Lowest Price in Supply Chain.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | const int maxn = 100010; 6 | 7 | int n, k, child, low, cnt; 8 | double rootPrice, r; 9 | vector v[maxn]; 10 | 11 | void dfs(int now, int layer) { 12 | if (v[now].empty()) { 13 | if (layer < low) { 14 | low = layer; 15 | cnt = 1; 16 | } 17 | else if (layer == low) ++cnt; 18 | return; 19 | } 20 | for (int i = 0; i < v[now].size(); ++i) { 21 | if (layer + 1 > low) return; 22 | dfs(v[now][i], layer+1); 23 | } 24 | } 25 | 26 | int main() { 27 | scanf("%d %lf %lf", &n, &rootPrice, &r); 28 | r /= 100; 29 | for (int i = 0; i < n; ++i) { 30 | scanf("%d", &k); 31 | while (k--) { 32 | scanf("%d", &child); 33 | v[i].push_back(child); 34 | } 35 | } 36 | low = maxn; cnt = 0; 37 | dfs(0, 0); 38 | printf("%.4f %d\n", rootPrice * pow(1+r, low), cnt); 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第九章 数据结构专题二树/9.4 二叉树/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/merelydust/Data-Structure-and-Algorithm/8e4d7dcd4793d10af9cce5d8714d4ec1a177f0eb/算法笔记讲解/SourceCode/第九章 数据结构专题二树/9.4 二叉树/.DS_Store -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第九章 数据结构专题二树/9.4 二叉树/A1043_Is It a Binary Search Tree_晴神法.cpp: -------------------------------------------------------------------------------- 1 | // 根据先序序列构建BST 因为递归地先插入根节点 再插入左子树右子树 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | struct node { 7 | int data; 8 | node* left; 9 | node* right; 10 | }; 11 | 12 | void insert(node*& root, int data) { 13 | if (root == NULL) { 14 | root = new node; root->data = data; 15 | root->left = root->right = NULL; 16 | return; 17 | } 18 | if (data < root->data) insert(root->left, data); 19 | else insert(root->right, data); 20 | } 21 | 22 | void preOrder(node* root, vector& vi) { // 先序遍历的结果存在vi 23 | if (root == NULL) return; 24 | vi.push_back(root->data); 25 | preOrder(root->left, vi); 26 | preOrder(root->right, vi); 27 | } 28 | 29 | void preOrderMirror(node* root, vector& vi) { 30 | if (root == NULL) return; 31 | vi.push_back(root->data); 32 | preOrderMirror(root->right, vi); 33 | preOrderMirror(root->left, vi); 34 | } 35 | 36 | void postOrder(node* root, vector& vi) { 37 | if (root == NULL) return; 38 | postOrder(root->left, vi); 39 | postOrder(root->right, vi); 40 | vi.push_back(root->data); 41 | } 42 | 43 | void postOrderMirror(node* root, vector& vi) { 44 | if (root == NULL) return; 45 | postOrderMirror(root->right, vi); 46 | postOrderMirror(root->left, vi); 47 | vi.push_back(root->data); 48 | } 49 | 50 | vector origin, pre, preM, post, postM; 51 | int main() { 52 | int n, data; scanf("%d", &n); 53 | node* root = NULL; 54 | for (int i = 0; i < n; ++i) { 55 | scanf("%d", &data); 56 | origin.push_back(data); 57 | insert(root, data); 58 | } 59 | preOrder(root, pre); 60 | preOrderMirror(root, preM); 61 | postOrder(root, post); 62 | postOrderMirror(root, postM); 63 | if (origin == pre) { 64 | printf("YES\n"); 65 | for (int i = 0; i < post.size(); ++i) { 66 | if (i) printf(" "); 67 | printf("%d", post[i]); 68 | } 69 | } 70 | else if (origin == preM) { 71 | printf("YES\n"); 72 | for (int i = 0; i < postM.size(); ++i) { 73 | if (i) printf(" "); 74 | printf("%d", postM[i]); 75 | } 76 | } 77 | else printf("NO\n"); 78 | delete []root; 79 | return 0; 80 | } 81 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第九章 数据结构专题二树/9.4 二叉树/A1043_Is It a Binary Search Tree_柳神法.cpp.cpp: -------------------------------------------------------------------------------- 1 | // 先假设是BST 把前序序列转化为后序序列 2 | // (前序序列首元素为根 左子树数据<=根节点数据<=右子树数据) 3 | // 如果不是BST 转化函数会提前return 结果序列长度 5 | #include 6 | using namespace std; 7 | bool isMirror; 8 | vector pre, post; 9 | 10 | void getPost(int root, int tail) { 11 | if(root > tail) return ; 12 | int i = root + 1, j = tail; 13 | if(!isMirror) { 14 | while(i <= tail && pre[root] > pre[i]) i++; 15 | while(j > root && pre[root] <= pre[j]) j--; 16 | } else { 17 | while(i <= tail && pre[root] <= pre[i]) i++; 18 | while(j > root && pre[root] > pre[j]) j--; 19 | } 20 | // 如果是BST 前序序列一定是 左左左leftEnd rightEnd右右右 21 | if(i - j != 1) return ; 22 | getPost(root + 1, j); 23 | getPost(i, tail); 24 | post.push_back(pre[root]); 25 | } 26 | 27 | int main() { 28 | int n; 29 | scanf("%d", &n); 30 | pre.resize(n); 31 | for (int i = 0; i < n; ++i) scanf("%d", &pre[i]); 32 | getPost(0, n-1); 33 | if (post.size() != n) { 34 | isMirror = true; 35 | post.clear(); 36 | getPost(0, n-1); 37 | } 38 | if (post.size() == n) { 39 | printf("YES\n%d", post[0]); 40 | for (int i = 1; i < n; ++i) printf(" %d", post[i]); 41 | } 42 | else printf("NO\n"); 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第九章 数据结构专题二树/9.4 二叉树/A1064 Complete Binary Search Tree.cpp: -------------------------------------------------------------------------------- 1 | // 有序序列=BST中序遍历序列 2 | #include 3 | #include 4 | using namespace std; 5 | const int maxn = 1010; 6 | int n, cnt = 0, arr[maxn], cbt[maxn]; 7 | 8 | void inOrder(int root) { 9 | if (root > n) return; 10 | inOrder(2*root); 11 | cbt[root] = arr[cnt++]; 12 | inOrder(2*root+1); 13 | } 14 | 15 | int main() { 16 | scanf("%d", &n); 17 | for (int i = 0; i < n; ++i) scanf("%d", &arr[i]); 18 | sort(arr, arr+n); 19 | inOrder(1); 20 | for (int i = 1; i <=n; ++i) { 21 | printf("%d", cbt[i]); 22 | if (i != n) printf(" "); 23 | else printf("\n"); 24 | } 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第九章 数据结构专题二树/9.4 二叉树/A1099 Build A Binary Search Tree.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | const int maxn = 110; int n; 7 | int numbers[maxn]; 8 | 9 | struct node { 10 | int data, left, right; 11 | }nodes[maxn]; 12 | 13 | int i = 0; // numbers的索引 14 | void inOrder(int root) { 15 | if (root == -1) return; 16 | inOrder(nodes[root].left); 17 | nodes[root].data = numbers[i++]; 18 | inOrder(nodes[root].right); 19 | } 20 | 21 | int num = 0; // 记录已经输出的节点数 22 | void layerOrder(int root) { 23 | queue Q; Q.push(root); 24 | while (!Q.empty()) { 25 | int fro = Q.front(); Q.pop(); 26 | printf("%d", nodes[fro].data); num++; 27 | if (num < n) printf(" "); 28 | else printf("\n"); 29 | if (nodes[fro].left != -1) Q.push(nodes[fro].left); 30 | if (nodes[fro].right != -1) Q.push(nodes[fro].right); 31 | } 32 | } 33 | 34 | int main() { 35 | scanf("%d", &n); int l, r; 36 | for (int i = 0; i < n; ++i) { 37 | scanf("%d %d", &l, &r); 38 | nodes[i].left = l; nodes[i].right = r; 39 | } 40 | for (int i = 0; i < n; ++i) scanf("%d", &numbers[i]); 41 | sort(numbers, numbers+n); 42 | inOrder(0); 43 | layerOrder(0); 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第九章 数据结构专题二树/9.5 平衡二叉树/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/merelydust/Data-Structure-and-Algorithm/8e4d7dcd4793d10af9cce5d8714d4ec1a177f0eb/算法笔记讲解/SourceCode/第九章 数据结构专题二树/9.5 平衡二叉树/.DS_Store -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第九章 数据结构专题二树/9.5 平衡二叉树/A1066 Root of AVL Tree.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | struct node { 6 | int data, height; 7 | node* left; 8 | node* right; 9 | node() { 10 | left = right = NULL; 11 | height = 1; 12 | } 13 | }; 14 | 15 | node* newNode(int v) { 16 | node* Node = new node; 17 | Node->data = v; 18 | return Node; 19 | }; 20 | 21 | int getHeight(node* root) { 22 | if (root == NULL) return 0; 23 | return root->height; 24 | } 25 | 26 | void updateHeight(node* root) { 27 | root->height = max(getHeight(root->left), getHeight(root->right)) + 1; 28 | } 29 | 30 | int getBF(node* root) { 31 | return getHeight(root->left) - getHeight(root->right); 32 | } 33 | 34 | void L(node* &root) { 35 | node* tmp = root->right; 36 | root->right = tmp->left; 37 | tmp->left = root; 38 | updateHeight(root); 39 | updateHeight(tmp); 40 | root = tmp; 41 | } 42 | 43 | void R(node* &root) { 44 | node* tmp = root->left; 45 | root->left = tmp->right; 46 | tmp->right = root; 47 | updateHeight(root); 48 | updateHeight(tmp); 49 | root = tmp; 50 | } 51 | 52 | void insert(node* &root, int v) { 53 | if (root == NULL) { 54 | root = newNode(v); 55 | return; 56 | } 57 | else if (v < root->data) { 58 | insert(root->left, v); 59 | updateHeight(root); 60 | if (getBF(root) == 2) { // 左子树失衡 61 | if (getBF(root->left) == 1) R(root); // 左左型 62 | else if (getBF(root->left) == -1) { // 左右型 63 | L(root->left); 64 | R(root); 65 | } 66 | } 67 | } 68 | else if (v > root->data) { 69 | insert(root->right, v); 70 | updateHeight(root); 71 | if (getBF(root) == -2) { // 右子树失衡 72 | if (getBF(root->right) == -1) L(root); // 右右型 73 | else if (getBF(root->right) == 1) { // 右左型 74 | R(root->right); 75 | L(root); 76 | } 77 | } 78 | } 79 | } 80 | 81 | int main() { 82 | int n, v; scanf("%d", &n); 83 | node* root = NULL; 84 | for (int i = 0; i < n; ++i) { 85 | scanf("%d", &v); 86 | insert(root, v); 87 | } 88 | printf("%d\n", root->data); 89 | } 90 | 91 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第九章 数据结构专题二树/9.6 并查集/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/merelydust/Data-Structure-and-Algorithm/8e4d7dcd4793d10af9cce5d8714d4ec1a177f0eb/算法笔记讲解/SourceCode/第九章 数据结构专题二树/9.6 并查集/.DS_Store -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第九章 数据结构专题二树/9.6 并查集/A1107 Social Clusters .cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | using namespace std; 7 | const int maxn = 1010; 8 | map > hobby; 9 | map cnt; 10 | int father[maxn]; 11 | 12 | int findFather(int x) { 13 | int a = x; 14 | while (father[x] != x) x = father[x]; 15 | while (a != x) { 16 | int b = a; 17 | a = father[a]; 18 | father[b] = x; 19 | } 20 | return x; 21 | } 22 | 23 | void unionFather(int x, int y) { 24 | int faX = findFather(x), faY = findFather(y); 25 | if (faX != faY) father[faX] = faY; 26 | } 27 | 28 | int main() { 29 | int n, k, h; scanf("%d", &n); 30 | for (int i = 1; i <= n; ++i) father[i] = i; // 记得初始化 31 | for (int i = 1; i <= n; ++i) { 32 | scanf("%d: ", &k); 33 | while (k--) { 34 | scanf("%d", &h); 35 | if (hobby[h].empty()) hobby[h].push_back(i); 36 | else unionFather(i, hobby[h].back()); 37 | } 38 | } 39 | for (int i = 1; i <= n; ++i) ++cnt[findFather(i)]; // ++cnt[father[i]]是错的 40 | printf("%d\n", (int)cnt.size()); 41 | vector ans; 42 | for (auto it = cnt.begin(); it != cnt.end(); ++it) ans.push_back(it->second); 43 | sort(ans.begin(), ans.end(), greater()); 44 | for (int i = 0; i < ans.size(); ++i) { 45 | printf("%d", ans[i]); 46 | if (i != ans.size()-1) printf(" "); 47 | else printf("\n"); 48 | } 49 | return 0; 50 | } 51 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第九章 数据结构专题二树/9.6 并查集/为什么不能直接使用father[i]而要用findFather(i).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/merelydust/Data-Structure-and-Algorithm/8e4d7dcd4793d10af9cce5d8714d4ec1a177f0eb/算法笔记讲解/SourceCode/第九章 数据结构专题二树/9.6 并查集/为什么不能直接使用father[i]而要用findFather(i).png -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第九章 数据结构专题二树/9.6 并查集/好朋友.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | int father[110]; 3 | 4 | int findFather(int x) { 5 | int a = x; 6 | while (father[x] != x) x = father[x]; 7 | while (a != x) { 8 | int b = a; 9 | a = father[a]; 10 | father[b] = x; 11 | } 12 | return x; 13 | } 14 | 15 | void unionFather(int x, int y) { 16 | int faX = findFather(x), faY = findFather(y); 17 | if (father[x] != father[y]) father[faX] = faY; 18 | } 19 | 20 | int main() { 21 | int n, m, a, b; scanf("%d %d", &n, &m); 22 | for (int i = 1; i <= n; ++i) father[i] = i; 23 | while (m--) { 24 | scanf("%d %d", &a, &b); 25 | unionFather(a, b); 26 | } 27 | int cnt = 0; 28 | for (int i = 1; i <= n; ++i) { 29 | if (father[i] == i) ++cnt; 30 | } 31 | printf("%d\n", cnt); 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第九章 数据结构专题二树/9.7 堆/A1098 Insertion or Heap Sort.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | void downAdjust(vector& b, int low, int high) { 7 | int i = low, j = 2 * i; 8 | while (j <= high) { 9 | if (j+1 <= high && b[j+1] > b[j]) ++j; 10 | if (b[j] > b[i]) { 11 | swap(b[j], b[i]); 12 | i = j; j = 2 * i; 13 | } 14 | else break; 15 | } 16 | } 17 | 18 | int main() { 19 | int n, p = 2; 20 | scanf("%d", &n); 21 | vector a(n+1), b(n+1); 22 | for (int i = 1; i <= n; ++i) scanf("%d", &a[i]); 23 | for (int i = 1; i <= n; ++i) scanf("%d", &b[i]); 24 | while (p <= n && b[p-1] <= b[p]) ++p; // 插入排序前几个数字会是升序 25 | int index = p; // 记录最后一个有序数字索引 26 | while (p <= n && a[p] == b[p]) ++p; // 前面几个数字是升序 剩下的数字又跟原始序列一样 -> 插入排序 27 | if (p == n+1) { 28 | printf("Insertion Sort\n"); 29 | sort(b.begin(), b.begin() + index + 1); // 多排序一位 30 | } 31 | else { 32 | printf("Heap Sort\n"); 33 | p = n; 34 | while (p > 2 && b[p] >= b[1]) --p; // 从后往前找到第一个小于当前堆顶的位置 就是无序序列的末尾 35 | swap(b[1], b[p]); 36 | downAdjust(b, 1, p-1); 37 | } 38 | printf("%d", b[1]); 39 | for (int i = 2; i <= n; ++i) printf(" %d", b[i]); 40 | return 0; 41 | } 42 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第五章 数学问题/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/merelydust/Data-Structure-and-Algorithm/8e4d7dcd4793d10af9cce5d8714d4ec1a177f0eb/算法笔记讲解/SourceCode/第五章 数学问题/.DS_Store -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第五章 数学问题/5.1简单数学/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/merelydust/Data-Structure-and-Algorithm/8e4d7dcd4793d10af9cce5d8714d4ec1a177f0eb/算法笔记讲解/SourceCode/第五章 数学问题/5.1简单数学/.DS_Store -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第五章 数学问题/5.1简单数学/A1008 Elevator.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int main() { 5 | int n; scanf("%d", &n); 6 | int arr[110]; 7 | for (int i = 0; i < n; ++i) scanf("%d", &arr[i]); 8 | int before = 0, time = 0; 9 | for (int i = 0; i < n; ++i) { 10 | if (arr[i] > before) time += 6 * (arr[i] - before); 11 | else if (arr[i] < before) time += 4 * (before - arr[i]); 12 | time += 5; 13 | before = arr[i]; 14 | } 15 | printf("%d\n", time); 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第五章 数学问题/5.1简单数学/A1049 Counting Ones .cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int main() { 5 | int n, a = 1, ans = 0; 6 | int left, now, right; 7 | scanf("%d", &n); 8 | while (n / a != 0) { 9 | left = n / (a * 10); 10 | now = n / a % 10; 11 | right = n % a; 12 | if (now == 0) ans += left * a; 13 | else if (now == 1) ans += left * a + right + 1; 14 | else ans += (left + 1) * a; 15 | a *= 10; 16 | } 17 | printf("%d\n", ans); 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第五章 数学问题/5.1简单数学/A1069 The Black Hole of Numbers.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | using namespace std; 7 | 8 | int main() { 9 | string s; cin >> s; 10 | do { 11 | while (s.length() < 4) s = "0" + s; // 不足四位补的0也是要纳入计算的 不只是输出格式 12 | sort(s.begin(), s.end(), less()); int a = stoi(s); // a数字升序 13 | sort(s.begin(), s.end(), greater()); int b = stoi(s); // b数字降序 14 | int c = b - a; 15 | printf("%04d - %04d = %04d\n", b, a, c); 16 | s = to_string(c); // 更新a 17 | }while (s != "6174" && s != "0"); 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第五章 数学问题/5.1简单数学/A1104 Sum of Number Segments .cpp: -------------------------------------------------------------------------------- 1 | // 每个数会出现(n - i) * (i + 1)次 i是数字的序号 从0开始 2 | // 虽然是找规律题 可以这样理解 3 | // 一个序列中的第i个数字 它后面(算上它自己)有n-i个数字 所以在以它开头的子序列中它会被算n-i次 子序列为{n}的情况在这里被囊括 4 | // 同时 它前面的数字 有一个的话 以它开头的子序列中就可以拼接到后面 它又会被算一轮 -> 前面的数字有k个 5 | // 所以 它被加的总次数 = (前面的数字个数+1)* (后面的数字即n-i) 6 | 7 | #include 8 | 9 | int main(){ 10 | int n; scanf("%d", &n); 11 | double tmp = 0, sum = 0; 12 | for(int i = 0; i < n; ++i){ 13 | scanf("%lf", &tmp); 14 | sum += (tmp * (n - i) * (i + 1)); 15 | } 16 | printf("%.2f\n", sum); 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第五章 数学问题/5.1简单数学/B1003 我要通过!.cpp: -------------------------------------------------------------------------------- 1 | //PAT 正确 2 | //(A+)PAT(A+) 3 | //aP(A+)Tc -> aP(A+1)ATca 4 | //-> PT中间有n个A 那么(P前面的字符串长度)* n = T后面的字符串长度 5 | #include 6 | #include 7 | #include 8 | using namespace std; 9 | 10 | int main() { 11 | int q; cin >> q; 12 | while (q--) { 13 | string s; cin >> s; 14 | map mp; bool flag = true; 15 | int pre = 0, mid = 0, end = 0; 16 | for (int i = 0, len = s.length(); i < len; ++i) { 17 | ++mp[s[i]]; 18 | if ((mp['T'] && !mp['P']) || mp['P'] > 1 || mp['T'] > 1) { 19 | flag = false; break; 20 | } 21 | if (s[i] == 'A') { 22 | if (!mp['P']) ++pre; 23 | else if (!mp['T']) ++mid; 24 | else ++end; 25 | } 26 | } 27 | if (flag && mp['P'] && mp['A'] && mp['T'] && mp.size() == 3 && pre * mid == end) cout << "YES" << endl; // 第一次只用用map.size()没有AC 是因为在判断语句里生成了值为0的键 28 | else cout << "NO" << endl; 29 | } 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第五章 数学问题/5.2最大公约数与最小公倍数/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/merelydust/Data-Structure-and-Algorithm/8e4d7dcd4793d10af9cce5d8714d4ec1a177f0eb/算法笔记讲解/SourceCode/第五章 数学问题/5.2最大公约数与最小公倍数/.DS_Store -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第五章 数学问题/5.2最大公约数与最小公倍数/B1008 数组元素循环右移问题.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() { 4 | int n, m; scanf("%d %d", &n, &m); 5 | m %= n; 6 | int arr[110]; 7 | for (int i = 0; i < n; ++i) scanf("%d", &arr[i]); 8 | for (int i = n-m; i < n; ++i) printf("%d ", arr[i]); // 如果m=0 这个循环不会被执行 9 | for (int i = 0; i < n-m-1; ++i) printf("%d ", arr[i]); 10 | printf("%d\n", arr[n-m-1]); 11 | return 0; 12 | } 13 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第五章 数学问题/5.3分数的四则运算/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/merelydust/Data-Structure-and-Algorithm/8e4d7dcd4793d10af9cce5d8714d4ec1a177f0eb/算法笔记讲解/SourceCode/第五章 数学问题/5.3分数的四则运算/.DS_Store -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第五章 数学问题/5.3分数的四则运算/A1081 Rational Sum.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include // 用cmath会报错ambiguous reference 3 | using namespace std; 4 | typedef long long ll; 5 | 6 | struct Fraction { 7 | ll up, down; 8 | }; 9 | 10 | ll gcd(ll a, ll b) { 11 | return !b ? a : gcd(b, a % b); 12 | } 13 | 14 | void simple(Fraction& a) { 15 | if (a.down < 0) { 16 | a.down = -a.down; a.up = -a.up; 17 | } 18 | if (a.up == 0) a.down = 1; 19 | else { 20 | ll d = gcd(a.up, a.down); 21 | a.down /= d; a.up /= d; 22 | } 23 | } 24 | 25 | void print(Fraction a) { 26 | if (a.down == 1) printf("%lld\n", a.up); 27 | else if (abs(a.up) > a.down) printf("%lld %lld/%lld\n", abs(a.up)/a.down, abs(a.up)%a.down, a.down); 28 | else printf("%lld/%lld\n", a.up, a.down); 29 | } 30 | 31 | void add(Fraction& a, Fraction b) { 32 | a.up = a.up * b.down + b.up * a.down; 33 | a.down *= b.down; 34 | simple(a); 35 | } 36 | 37 | int main() { 38 | int n; scanf("%d", &n); 39 | Fraction ans = Fraction{0, 1}, tmp; 40 | while (n--) { 41 | scanf("%lld/%lld", &tmp.up, &tmp.down); 42 | add(ans, tmp); 43 | } 44 | print(ans); 45 | return 0; 46 | } 47 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第五章 数学问题/5.3分数的四则运算/A1088 Rational Arithmetic.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | typedef long long ll; 5 | 6 | struct Fraction { 7 | ll up, down; 8 | }; 9 | 10 | ll gcd(ll a, ll b) { 11 | a = abs(a); b = abs(b); 12 | return !b ? a : gcd(b, a%b); 13 | } 14 | 15 | Fraction simple(Fraction a) { 16 | if (a.down < 0) { 17 | a.down = -a.down; a.up = -a.up; // 虽然测试数据的分母不为0 但是运算过程中可能产生负分母 18 | } 19 | if (a.up == 0) a.down = 1; 20 | ll d = gcd(a.up, a.down); 21 | a.up /= d; a.down /= d; 22 | return a; 23 | } 24 | 25 | void print(Fraction a) { 26 | a = simple(a); 27 | bool neg = a.up < 0; 28 | if (neg) printf("("); 29 | if (a.down == 1) printf("%lld", a.up); 30 | else if (a.down == 0) printf("Inf"); 31 | else if (abs(a.up) > a.down) printf("%lld %lld/%lld", a.up/a.down, abs(a.up)%a.down, a.down); 32 | else printf("%lld/%lld", a.up, a.down); 33 | if (neg) printf(")"); 34 | } 35 | 36 | Fraction add(Fraction a, Fraction b) { 37 | a.up = a.up*b.down + b.up*a.down; 38 | a.down *= b.down; 39 | return a; 40 | } 41 | 42 | Fraction mul(Fraction a, Fraction b) { 43 | a.up *= b.up; a.down *= b.down; 44 | return a; 45 | } 46 | 47 | int main() { 48 | Fraction a, b; 49 | scanf("%lld/%lld %lld/%lld", &a.up, &a.down, &b.up, &b.down); 50 | print(a); printf(" + "); print(b); printf(" = "); print(add(a, b)); printf("\n"); 51 | print(a); printf(" - "); print(b); printf(" = "); print(add(a, Fraction{-b.up, b.down})); printf("\n"); 52 | print(a); printf(" * "); print(b); printf(" = "); print(mul(a, b)); printf("\n"); 53 | print(a); printf(" / "); print(b); printf(" = "); print(mul(a, Fraction{b.down, b.up})); printf("\n"); 54 | return 0; 55 | } 56 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第五章 数学问题/5.4素数/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/merelydust/Data-Structure-and-Algorithm/8e4d7dcd4793d10af9cce5d8714d4ec1a177f0eb/算法笔记讲解/SourceCode/第五章 数学问题/5.4素数/.DS_Store -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第五章 数学问题/5.4素数/A1015 Reversible Primes.cpp: -------------------------------------------------------------------------------- 1 | /*** 2 | 判断n是否为素数 3 | 把数字n以d进制表示dn 逆转得到rdn 4 | 把rdn转化为十进制 5 | 判断rn是否为素数 6 | ***/ 7 | #include 8 | #include 9 | #include 10 | using namespace std; 11 | 12 | bool isPrime(int a) { 13 | if (a <= 1) return false; 14 | int sqr = int(sqrt(1.0 * a)); 15 | for (int i = 2; i <= sqr; ++i) { 16 | if (a % i == 0) return false; 17 | } 18 | return true; 19 | } 20 | 21 | string toD(int n, int d) { 22 | string rdn = ""; 23 | while (n) { 24 | rdn += to_string(n % d); 25 | n /= d; 26 | } 27 | return rdn; 28 | } 29 | 30 | int to10(string rdn, int d) { 31 | int rn = 0, mul = 1, len = int(rdn.length()); 32 | for (int i = len - 1; i >= 0; --i) { 33 | rn += (rdn[i] - '0') * mul; 34 | mul *= d; 35 | } 36 | return rn; 37 | } 38 | 39 | int main() { 40 | int n, d; scanf("%d", &n); 41 | while (n > 0) { 42 | scanf("%d", &d); 43 | if (isPrime(n) && isPrime(to10(toD(n, d), d) ) ) printf("Yes\n"); 44 | else printf("No\n"); 45 | scanf("%d", &n); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第五章 数学问题/5.4素数/A1078 Hashing.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | const int maxn = 10010; 5 | bool hashtable[maxn] = {0}; 6 | 7 | bool isPrime(int a) { 8 | if (a <= 1) return false; 9 | int sqr = int(sqrt(1.0 * a)); 10 | for (int i = 2; i <= sqr; ++i) { 11 | if (a % i == 0) return false; 12 | } 13 | return true; 14 | } 15 | 16 | int main() { 17 | int m, n, tmp, pos; scanf("%d %d", &m, &n); 18 | while (!isPrime(m)) ++m; 19 | for (int i = 0; i < n; ++i) { 20 | scanf("%d", &tmp); 21 | int step = 0; bool find = false; 22 | do { 23 | pos = (tmp + step * step) % m; 24 | if (pos >= m) break; 25 | if (!hashtable[pos]) { 26 | printf("%d", pos); hashtable[pos] = true; 27 | find = true; break; 28 | } 29 | ++step; 30 | } while (step < m); 31 | if (!find) printf("-"); 32 | if (i != n-1) printf(" "); 33 | else printf("\n"); 34 | } 35 | return 0; 36 | } 37 | 38 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第五章 数学问题/5.4素数/B1007 素数对猜想.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | const int maxn = 10010; int n; 5 | int prime[maxn] = {0}; // 先用非法值填充 6 | 7 | bool isPrime(int a) { 8 | if (a <= 1) return false; 9 | int sqr = int(sqrt(1.0 * a)); 10 | for (int i = 2; i <= sqr; ++i) { 11 | if (a % i == 0) return false; 12 | } 13 | return true; 14 | } 15 | 16 | void findPrime() { 17 | int cnt = 0; 18 | for (int i = 2; i <= n; ++i) { 19 | if (isPrime(i)) prime[cnt++] = i; 20 | } 21 | } 22 | 23 | int main() { 24 | scanf("%d", &n); 25 | findPrime(); 26 | int ans = 0; 27 | for (int i = 1; prime[i]; ++i) { // 可能一个素数也没有 28 | if (prime[i] - prime[i-1] == 2) ++ans; 29 | } 30 | printf("%d\n", ans); 31 | } 32 | 33 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第五章 数学问题/5.4素数/B1013 数素数.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | bool isPrime(int a) { 6 | if (a <= 1) return false; 7 | int sqr = int(sqrt(1.0 * a)); 8 | for (int i = 2; i <= sqr; ++i) { 9 | if (a % i == 0) return false; 10 | } 11 | return true; 12 | } 13 | 14 | int main() { 15 | int m, n; scanf("%d %d", &m, &n); 16 | int prime[10010], cnt = 0, i = 2; 17 | while (cnt < n) { 18 | if (isPrime(i)) prime[cnt++] = i; 19 | ++i; 20 | } 21 | int j = m-1; 22 | while (j < n) { 23 | int line = 0; 24 | while (line < 10 && j < n) { 25 | printf("%d", prime[j]); ++line; ++j; 26 | if (line != 10 && j != n) printf(" "); 27 | else printf("\n"); 28 | } 29 | } 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第五章 数学问题/5.5质因子分解/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/merelydust/Data-Structure-and-Algorithm/8e4d7dcd4793d10af9cce5d8714d4ec1a177f0eb/算法笔记讲解/SourceCode/第五章 数学问题/5.5质因子分解/.DS_Store -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第五章 数学问题/5.5质因子分解/A1059 Prime Factors.cpp: -------------------------------------------------------------------------------- 1 | // 一个坑 虽然题目说输出素数 但1=1也要输出 2 | #include 3 | #include 4 | using namespace std; 5 | typedef long long ll; 6 | 7 | bool isPrime(ll n) { 8 | if (n <= 1) return false; 9 | ll sqr = ll(sqrt(1.0 * n)); 10 | for (ll i = 2; i <= sqr; ++i) { 11 | if (n % i == 0) return false; 12 | } 13 | return true; 14 | } 15 | 16 | int main() { 17 | ll n; scanf("%lld", &n); 18 | printf("%lld=", n); 19 | if (n == 1) { 20 | printf("1"); return 0; 21 | } 22 | ll sqr = ll(sqrt(1.0 * n)); 23 | bool flag = false; 24 | for (ll i = 2; i <= sqr; ++i) { 25 | if (isPrime(i)) { 26 | int cnt = 0; 27 | while (n % i == 0) { 28 | n /= i; ++cnt; 29 | } 30 | if (cnt) { 31 | if (flag) printf("*"); 32 | printf("%lld", i); 33 | flag = true; // 标记已经有数字输出 34 | } 35 | if (cnt > 1) printf("^%d", cnt); 36 | } 37 | } 38 | if (n > 1) { 39 | if (flag) printf("*"); 40 | printf("%lld", n); 41 | } 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第五章 数学问题/5.5质因子分解/A1096 Consecutive Factors.cpp: -------------------------------------------------------------------------------- 1 | // 一个坑 两种情况下maxlen=1 n除了1和本身外只有一个因数 n为质数(maxlen不是0 2 | #include 3 | #include 4 | using namespace std; 5 | typedef long long ll; 6 | 7 | int main() { 8 | ll n; scanf("%lld", &n); 9 | ll sqr = ll(sqrt(1.0 * n)); 10 | ll maxlen = 0, start = n; // 如果最大长度为0就输出数字本身 11 | for (ll i = 2; i <= sqr; ++i) { 12 | ll j = i, tmp = i; 13 | while (n % tmp == 0) { 14 | ++j; tmp *= j; 15 | } 16 | if (j-i > maxlen) { // j-1-i+1 > maxlen 17 | maxlen = j-i; start = i; 18 | } 19 | } 20 | if (maxlen == 0) printf("1\n%lld", start); 21 | else { 22 | printf("%lld\n", maxlen); 23 | for (int i = 0; i < maxlen; ++i) { 24 | if (i != maxlen-1) printf("%lld*", start+i); 25 | else printf("%lld\n", start+i); 26 | } 27 | } 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第五章 数学问题/5.6大整数运算/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/merelydust/Data-Structure-and-Algorithm/8e4d7dcd4793d10af9cce5d8714d4ec1a177f0eb/算法笔记讲解/SourceCode/第五章 数学问题/5.6大整数运算/.DS_Store -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第五章 数学问题/5.6大整数运算/A1023 Have Fun with Numbers.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | const int maxn = 25; 5 | int hashtable[maxn] = {0}; 6 | 7 | struct bign { 8 | int len, d[maxn]; 9 | bign() { 10 | len = 0; memset(d, 0, sizeof(d)); 11 | } 12 | }; 13 | 14 | void change(char str[], bign& a) { 15 | a.len = int(strlen(str)); 16 | for (int i = 0; i < a.len; ++i) { 17 | a.d[i] = str[a.len-1-i] - '0'; 18 | ++hashtable[a.d[i]]; 19 | } 20 | } 21 | 22 | bign mul(bign a) { 23 | bign b; int carry = 0; 24 | for (int i = 0; i < a.len; ++i) { 25 | int tmp = a.d[i] * 2 + carry; 26 | carry = tmp / 10; 27 | b.d[b.len++] = tmp % 10; 28 | } 29 | if (carry) b.d[b.len++] = carry; 30 | return b; 31 | } 32 | 33 | int main() { 34 | char str[maxn]; scanf("%s", str); 35 | bign a; change(str, a); 36 | bign b = mul(a); 37 | bool flag = true; 38 | for (int i = 0; i < b.len; ++i) { 39 | if (!hashtable[b.d[i]]) { 40 | flag = false; break; 41 | } 42 | --hashtable[b.d[i]]; 43 | } 44 | flag ? printf("Yes\n") : printf("No\n"); 45 | for (int i = b.len-1; i >= 0; --i) { 46 | printf("%d", b.d[i]); 47 | } 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第五章 数学问题/5.6大整数运算/A1024 Palindromic Number.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | const int maxn = 1000; 5 | 6 | struct bign { 7 | int len, d[maxn]; 8 | bign() { 9 | len = 0; memset(d, 0, sizeof(d)); 10 | } 11 | }; 12 | 13 | void change(char str[], bign& a) { 14 | a.len = int(strlen(str)); 15 | for (int i = 0; i < a.len; ++i) a.d[i] = str[a.len-1-i] - '0'; 16 | } 17 | 18 | void add(bign& a) { 19 | bign b = a; 20 | int carry = 0; 21 | for (int i = 0; i < a.len; ++i) { 22 | int tmp = a.d[i] + b.d[b.len-1-i] + carry; 23 | a.d[i] = tmp % 10; 24 | carry = tmp / 10; 25 | } 26 | if (carry) a.d[a.len++] = carry; 27 | } 28 | 29 | bool isP(bign a) { 30 | for (int i = 0, mid = a.len / 2; i <= mid; ++i) { 31 | if (a.d[i] != a.d[a.len-1-i]) return false; 32 | } 33 | return true; 34 | } 35 | 36 | int main() { 37 | char str[maxn]; scanf("%s", str); 38 | bign a; change(str, a); 39 | int step; scanf("%d", &step); 40 | int cnt = 0; 41 | while (!isP(a) && cnt < step) { 42 | add(a); ++cnt; 43 | } 44 | for (int i = a.len-1; i >= 0; --i) printf("%d", a.d[i]); 45 | printf("\n"); 46 | printf("%d\n", cnt); 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第五章 数学问题/5.6大整数运算/B1017 A除以B.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | const int maxn = 1010; 5 | 6 | struct bign { 7 | int len, d[maxn]; 8 | bign() { 9 | len = 0; memset(d, 0, sizeof(d)); 10 | } 11 | }; 12 | 13 | void change(char str[], bign& a) { 14 | a.len = int(strlen(str)); 15 | for (int i = 0; i < a.len; ++i) a.d[i] = str[a.len-1-i] - '0'; 16 | } 17 | 18 | int divide(bign a, int b, bign& ans) { 19 | int r = 0; 20 | for (int i = a.len-1; i >= 0; --i) { 21 | r = a.d[i] + r*10; 22 | if (r < b) ans.d[i] = 0; 23 | else { 24 | ans.d[i] = r / b; 25 | r = r % b; 26 | } 27 | } 28 | while (ans.d[ans.len-1] == 0 && ans.len > 1) --ans.len; 29 | return r; 30 | } 31 | 32 | int main() { 33 | bign a; char tmp[maxn]; int b; 34 | scanf("%s", tmp); change(tmp, a); 35 | scanf("%d", &b); 36 | bign ans = a; 37 | int r = divide(a, b, ans); 38 | for (int i = ans.len-1; i >= 0; --i) printf("%d", ans.d[i]); 39 | printf(" %d\n", r); 40 | return 0; 41 | } 42 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第八章 搜索专题DFS与BFS/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/merelydust/Data-Structure-and-Algorithm/8e4d7dcd4793d10af9cce5d8714d4ec1a177f0eb/算法笔记讲解/SourceCode/第八章 搜索专题DFS与BFS/.DS_Store -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第八章 搜索专题DFS与BFS/A1091 Acute Stroke.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | int m, n, l, t, vol = 0; 6 | 7 | struct node { 8 | int x, y, z, flag; 9 | node() { 10 | flag = 0; 11 | } 12 | }; 13 | int matrix[1300][130][60] = {0}; 14 | bool inq[1290][130][61] = {false}; 15 | int X[] = {0, 0, 0, 0, 1, -1}; 16 | int Y[] = {0, 0, 1, -1, 0, 0}; 17 | int Z[] = {1, -1, 0, 0, 0, 0}; 18 | 19 | bool judge(int x, int y, int z) { 20 | if (x < 0 || x >= m || y < 0 || y >= n || z < 0 || z >= l) return false; // 越界 21 | if (!matrix[x][y][z] || inq[x][y][z]) return false; // 非法 22 | return true; 23 | } 24 | 25 | int bfs(int x, int y, int z) { 26 | node Node; Node.x = x; Node.y = y; Node.z = z; 27 | queue Q; 28 | Q.push(Node); inq[Node.x][Node.y][Node.z] = true; 29 | int cnt = 1; 30 | while (!Q.empty()) { 31 | node fro = Q.front(); 32 | Q.pop(); 33 | for (int i = 0; i < 6; ++i) { 34 | int newX = fro.x + X[i], newY = fro.y + Y[i], newZ = fro.z + Z[i]; 35 | if (judge(newX, newY, newZ)) { 36 | node newNode; newNode.x = newX; newNode.y = newY; newNode.z = newZ; 37 | Q.push(newNode); inq[newX][newY][newZ] = true; ++cnt; 38 | } 39 | } 40 | } 41 | return cnt; 42 | } 43 | 44 | int main() { 45 | scanf("%d %d %d %d", &m, &n, &l, &t); 46 | for (int k = 0; k < l; ++k) { 47 | for (int i = 0; i < m; ++i) { 48 | for (int j = 0; j < n; ++j) { 49 | scanf("%d", &matrix[i][j][k]); 50 | } 51 | } 52 | } 53 | for (int k = 0; k < l; ++k) { 54 | for (int i = 0; i < m; ++i) { 55 | for (int j = 0; j < n; ++j) { 56 | if (matrix[i][j][k] && !inq[i][j][k]) { 57 | int cnt = bfs(i, j, k); 58 | if (cnt >= t) vol += cnt; 59 | } 60 | } 61 | } 62 | } 63 | printf("%d\n", vol); 64 | return 0; 65 | } 66 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第八章 搜索专题DFS与BFS/A1103 Integer Factorization.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | int n, sqr, k, p, maxSumFac = -1; 7 | vector tmp, ans, squares; 8 | 9 | void init() { // 打表解决超时 10 | for (int i = 0; i <= sqr; ++i) { 11 | int num = 1; 12 | for (int j = 0; j < p; ++j) num *= i; 13 | squares.push_back(num); 14 | } 15 | } 16 | 17 | void dfs(int index, int nowK, int sumNum, int sumFac) { 18 | if (nowK == k && sumNum == n) { 19 | if (sumFac > maxSumFac) { 20 | maxSumFac= sumFac; 21 | ans = tmp; 22 | } 23 | return; 24 | } 25 | if (index == 0 || nowK > k || sumNum > n) return; 26 | 27 | tmp.push_back(index); // 选的分支 28 | dfs(index, nowK + 1, sumNum + squares[index], sumFac + index); 29 | tmp.pop_back(); // 不选的分支 30 | dfs(index-1, nowK, sumNum, sumFac); 31 | } 32 | 33 | int main() { 34 | scanf("%d %d %d", &n, &k, &p); 35 | sqr = int(sqrt(1.0 * n)); 36 | init(); 37 | dfs(sqr, 0, 0, 0); 38 | if (maxSumFac == -1) printf("Impossible\n"); 39 | else { 40 | printf("%d = ", n); 41 | for (int i = 0; i < ans.size(); ++i) { 42 | if (i) printf(" + "); 43 | printf("%d^%d", ans[i], p); 44 | } 45 | printf("\n"); 46 | return 0; 47 | } 48 | } 49 | 50 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第六章 C++标准模版库介绍/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/merelydust/Data-Structure-and-Algorithm/8e4d7dcd4793d10af9cce5d8714d4ec1a177f0eb/算法笔记讲解/SourceCode/第六章 C++标准模版库介绍/.DS_Store -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第六章 C++标准模版库介绍/6.1 vector/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/merelydust/Data-Structure-and-Algorithm/8e4d7dcd4793d10af9cce5d8714d4ec1a177f0eb/算法笔记讲解/SourceCode/第六章 C++标准模版库介绍/6.1 vector/.DS_Store -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第六章 C++标准模版库介绍/6.1 vector/A1039 Course List for Student .cpp: -------------------------------------------------------------------------------- 1 | #include // 用流会超时 2 | #include 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | int main() { 8 | int n, k; scanf("%d %d", &n, &k); 9 | map > mp; 10 | while (k--) { 11 | int c, cNum; scanf("%d %d", &c, &cNum); 12 | while (cNum--) { 13 | char name[10]; scanf("%s", name); 14 | mp[name].insert(c); 15 | } 16 | } 17 | while (n--) { 18 | char name[10]; scanf("%s", name); 19 | printf("%s %d", name, int(mp[name].size())); 20 | if (mp[name].size()) { 21 | for (auto it = mp[name].begin(); it != mp[name].end(); ++it) printf(" %d", *it); 22 | } 23 | printf("\n"); 24 | } 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第六章 C++标准模版库介绍/6.1 vector/A1047 Student List for Course.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include // 用set会超时 改成每次都sort可以AC 5 | using namespace std; 6 | 7 | int main() { 8 | int n, k; scanf("%d %d", &n, &k); 9 | vector arr[2510]; 10 | char name[10] = {0}; int num, index; 11 | for (int i = 0; i < n; ++i) { 12 | scanf("%s %d", name, &num); 13 | while (num--) { 14 | scanf("%d", &index); 15 | arr[index].push_back(name); 16 | } 17 | } 18 | for (int i = 1; i <= k; ++i) { 19 | printf("%d %d\n", i, (int)arr[i].size()); 20 | if (arr[i].empty()) continue; 21 | sort(arr[i].begin(), arr[i].end()); 22 | for (int j = 0, len = (int)arr[i].size(); j < len; ++j) printf("%s\n", arr[i][j].c_str()); 23 | } 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第六章 C++标准模版库介绍/6.2 set/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/merelydust/Data-Structure-and-Algorithm/8e4d7dcd4793d10af9cce5d8714d4ec1a177f0eb/算法笔记讲解/SourceCode/第六章 C++标准模版库介绍/6.2 set/.DS_Store -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第六章 C++标准模版库介绍/6.2 set/A1063 Set Similarity .cpp: -------------------------------------------------------------------------------- 1 | // 用哈希表会内存超限= = 2 | #include 3 | #include 4 | using namespace std; 5 | const int N = 51; 6 | 7 | int main() { 8 | int n, m, q, v, st1, st2; 9 | set st[N]; 10 | scanf("%d", &n); 11 | for (int i = 1; i <= n; ++i) { 12 | scanf("%d", &m); 13 | for (int j = 0; j < m; ++j) { 14 | scanf("%d", &v); st[i].insert(v); 15 | } 16 | } 17 | scanf("%d", &q); 18 | for (int i = 0; i < q; ++i) { 19 | scanf("%d %d", &st1, &st2); 20 | int totalNum = (int)st[st2].size(), sameNum = 0; 21 | for (auto it = st[st1].begin(); it != st[st1].end(); ++it) { 22 | if (st[st2].find(*it) != st[st2].end()) sameNum++; 23 | else totalNum++; 24 | } 25 | printf("%.1lf%%\n", sameNum * 100.0 / totalNum); // 先乘再除 比 先除再乘 误差小 26 | } 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第六章 C++标准模版库介绍/6.3 string/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/merelydust/Data-Structure-and-Algorithm/8e4d7dcd4793d10af9cce5d8714d4ec1a177f0eb/算法笔记讲解/SourceCode/第六章 C++标准模版库介绍/6.3 string/.DS_Store -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第六章 C++标准模版库介绍/6.3 string/A1060 Are They Equal .cpp: -------------------------------------------------------------------------------- 1 | // 把读入数字转化成 0.xx * 10^exp 2 | // 对于大于1的数字 原数字小数点前有几位就是10的几次方 dotPos 3 | // 对于小于1的数字 第一个非零数与小数点之间有几位就是10的负几次方 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | int n, expA = 0, expB = 0; string a, b; 9 | 10 | void solve(string& s, int& exp) { 11 | while (s[0] == '0') s.erase(0, 1); // 去除多余前导0 12 | if (s.empty()) { 13 | s = "0"; exp = 0; 14 | } 15 | else if (s[0] == '.') { 16 | s.erase(0, 1); 17 | while (s[0] == '0') { 18 | --exp; 19 | s.erase(0,1); 20 | } 21 | if (s.empty()) { 22 | s = "0"; exp = 0; 23 | } 24 | } 25 | else { 26 | int dotPos = int(s.find(".")); 27 | if (dotPos != string::npos) { 28 | exp = dotPos; 29 | s.erase(dotPos, 1); 30 | } 31 | else exp = s.length(); 32 | } 33 | s = s.substr(0, n); 34 | while (s.length() < n) s += "0"; 35 | } 36 | 37 | int main() { 38 | cin >> n >> a >> b; 39 | solve(a, expA); solve(b, expB); 40 | if (expA == expB && a == b) printf("YES 0.%s*10^%d\n", a.c_str(), expA); 41 | else printf("NO 0.%s*10^%d 0.%s*10^%d\n", a.c_str(), expA, b.c_str(), expB); 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第六章 C++标准模版库介绍/6.4 map/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/merelydust/Data-Structure-and-Algorithm/8e4d7dcd4793d10af9cce5d8714d4ec1a177f0eb/算法笔记讲解/SourceCode/第六章 C++标准模版库介绍/6.4 map/.DS_Store -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第六章 C++标准模版库介绍/6.4 map/A1022 Digital Librar.cpp: -------------------------------------------------------------------------------- 1 | // 对每一种查询方式都建立一个map string-set 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | void query(map >& mp, string q) { 10 | if (mp.find(q) == mp.end()) printf("Not Found\n"); 11 | else { 12 | for (auto it = mp[q].begin(); it != mp[q].end(); ++it) printf("%07d\n", *it); 13 | } 14 | } 15 | 16 | int main() { 17 | int n; cin >> n; 18 | map > title2id, author2id, key2id, publish2id, year2id; 19 | int id; string tmp; 20 | while (n--) { 21 | cin >> id; getchar(); // 吸收换行符 22 | getline(cin, tmp); title2id[tmp].insert(id); 23 | getline(cin, tmp); author2id[tmp].insert(id); 24 | while (cin >> tmp) { 25 | key2id[tmp].insert(id); 26 | if (getchar() == '\n') break; 27 | } 28 | getline(cin, tmp); publish2id[tmp].insert(id); 29 | getline(cin, tmp); year2id[tmp].insert(id); 30 | } 31 | int m; cin >> m; int tag; string q; 32 | while (m--) { 33 | scanf("%d: ", &tag); getline(cin, q); 34 | cout << tag << ": " << q << endl; 35 | switch (tag) { 36 | case 1: query(title2id, q); 37 | break; 38 | case 2: query(author2id, q); 39 | break; 40 | case 3: query(key2id, q); 41 | break; 42 | case 4: query(publish2id, q); 43 | break; 44 | case 5: query(year2id, q); 45 | break; 46 | } 47 | } 48 | return 0; 49 | } 50 | 51 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第六章 C++标准模版库介绍/6.4 map/A1054 The Dominant Color.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | int main() { 6 | int m, n, tmp; scanf("%d %d", &m, &n); 7 | map mp; 8 | for (int row = 0; row < n; ++row) { 9 | for (int col = 0; col < m; ++ col) { 10 | scanf("%d", &tmp); mp[tmp]++; 11 | } 12 | } 13 | int half = m * n / 2; 14 | map::iterator it = mp.begin(); 15 | for (; it != mp.end(); ++it) { 16 | if (it->second > half) { 17 | printf("%d\n", it->first); break; 18 | } 19 | } 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第六章 C++标准模版库介绍/6.4 map/A1071 Speech Patterns.cpp: -------------------------------------------------------------------------------- 1 | // 单词之间以非alnum为界限 2 | #include 3 | #include 4 | #include 5 | #include 6 | using namespace std; 7 | 8 | int main() { 9 | string s; getline(cin, s); 10 | map m; 11 | int index = 0, len = int(s.length()); 12 | while (index < len) { 13 | if (!isalnum(s[index])) ++index; 14 | else { 15 | string word = ""; 16 | while (isalnum(s[index])) word += tolower(s[index++]); 17 | m[word]++; 18 | } 19 | } 20 | string ans = ""; int cnt = 0; 21 | for (auto it = m.begin(); it != m.end(); ++it) { 22 | if (it->second > cnt) { 23 | cnt = it->second; ans = it->first; 24 | } 25 | } 26 | cout << ans << " " << cnt << endl; 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第六章 C++标准模版库介绍/6.4 map/A1100 Mars Numbers.cpp: -------------------------------------------------------------------------------- 1 | /*** 2 | 地球数字转火星数字:a*13^1 + b -> hDigit[a] + digit[b] 3 | 火星数字转地球数字:str1 str2 -> str1对应的索引*13^1 + str对应的索引 4 | ***/ 5 | #include 6 | #include 7 | #include 8 | using namespace std; 9 | 10 | string digit[] = {"tret", "jan", "feb", "mar", "apr", "may", "jun", 11 | "jly", "aug", "sep", "oct", "nov", "dec",}; 12 | string hDigit[] = {"", "tam", "hel", "maa", "huh", "tou", "kes", 13 | "hei", "elo", "syy", "lok", "mer", "jou"}; 14 | 15 | string total[] = {"tret", "jan", "feb", "mar", "apr", "may", "jun", 16 | "jly", "aug", "sep", "oct", "nov", "dec", "", "tam", "hel", "maa", "huh", "tou", "kes", 17 | "hei", "elo", "syy", "lok", "mer", "jou"}; 18 | 19 | string earth2Mars(int n) { 20 | if (!n) return "tret"; 21 | string ans = ""; bool add = false; 22 | if (n >= 13) { 23 | ans += hDigit[n/13]; n %= 13; add = true; 24 | } 25 | if (n) { 26 | if (add) ans += " "; 27 | ans += digit[n]; 28 | } 29 | return ans; 30 | } 31 | 32 | int mars2Earth(string n) { 33 | int ans = 0; 34 | if (n.length() > 4) { // 如果有两部分 长度一定会大于4 35 | string s = n.substr(0, n.find(" ")); 36 | for (int i = 1; i <= 12; ++i) { 37 | if (hDigit[i] == s) { 38 | ans += 13 * i; break; 39 | } 40 | } 41 | n.erase(0, n.find(" ")+1); 42 | } 43 | for (int i = 0; i <= 25; ++i) { 44 | if (total[i] == n) { 45 | if (i <= 12) ans += i; 46 | else ans += (i-13) * 13; 47 | } 48 | } 49 | return ans; 50 | } 51 | 52 | int main() { 53 | int N; cin >> N; string tmp; 54 | getchar(); // 吸收换行符 55 | while (N--) { 56 | getline(cin, tmp); 57 | if (isdigit(tmp[0])) cout << earth2Mars(stoi(tmp)) << endl; 58 | else cout << mars2Earth(tmp) << endl; 59 | } 60 | return 0; 61 | } 62 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第十章 图算法专题/10.3 图的遍历/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/merelydust/Data-Structure-and-Algorithm/8e4d7dcd4793d10af9cce5d8714d4ec1a177f0eb/算法笔记讲解/SourceCode/第十章 图算法专题/10.3 图的遍历/.DS_Store -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第十章 图算法专题/10.3 图的遍历/A1013 Battle Over Cities.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | const int maxn = 1010; 6 | vector Adj[maxn]; 7 | bool vis[maxn] = {false}; 8 | int n, m, k, u, v, destroy; 9 | 10 | void dfs(int u) { 11 | if (u == destroy) return; 12 | vis[u] = true; 13 | for (int i = 0; i < Adj[u].size(); ++i) { 14 | if (!vis[Adj[u][i]]) dfs(Adj[u][i]); 15 | } 16 | } 17 | 18 | int main() { 19 | scanf("%d %d %d", &n, &m, &k); 20 | for (int i = 0; i < m; ++i) { 21 | scanf("%d %d", &u, &v); 22 | Adj[u].push_back(v); Adj[v].push_back(u); 23 | } 24 | while (k--) { 25 | scanf("%d", &destroy); 26 | memset(vis, 0, sizeof(vis)); 27 | int block = 0; 28 | for (int i = 1; i <= n; ++i) { 29 | if (!vis[i] && i != destroy) { 30 | ++block; 31 | dfs(i); 32 | } 33 | } 34 | printf("%d\n", block-1); // 需要新建的边数=连通块个数-1 35 | } 36 | return 0; 37 | } 38 | 39 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第十章 图算法专题/10.3 图的遍历/A1021 Deepest Root .cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | using namespace std; 6 | const int maxn = 10010; 7 | vector Adj[maxn]; 8 | // bool vis[maxn] = {false}; 不需要判断是否访问过了 因为你是在寻找最长路径 不是在遍历图啊喂! 9 | int father[maxn]; 10 | set ans; vector tmp; 11 | int n, u, v, maxDepth; 12 | 13 | void init() { 14 | for (int i = 1; i <= n; ++i) father[i] = i; 15 | } 16 | 17 | int findFather(int x) { 18 | int a = x; 19 | while (father[x] != x) x = father[x]; 20 | while (a != x) { 21 | int b = a; 22 | a = father[a]; 23 | father[b] = x; 24 | } 25 | return x; 26 | } 27 | 28 | void unionFather(int x, int y) { 29 | int faX = findFather(x), faY = findFather(y); 30 | if (faX != faY) father[faX] = faY; // 注意 是father[faX] = faY 不是father[x] = faY 31 | } 32 | 33 | void dfs(int u, int pre, int depth) { 34 | if (depth > maxDepth) { 35 | maxDepth = depth; 36 | tmp.clear(); tmp.push_back(u); 37 | } 38 | else if (depth == maxDepth) tmp.push_back(u); 39 | for (int i = 0; i < Adj[u].size(); ++i) { 40 | int v = Adj[u][i]; 41 | if (v == pre) continue; // 无向图不走回头路 42 | dfs(v, u, depth+1); 43 | } 44 | } 45 | 46 | int main() { 47 | scanf("%d", &n); 48 | init(); 49 | for (int i = 1; i < n; ++i) { 50 | scanf("%d %d", &u, &v); 51 | Adj[u].push_back(v); Adj[v].push_back(u); 52 | unionFather(u, v); 53 | } 54 | unordered_set numF; 55 | for (int i = 1; i <= n; ++i) numF.insert(findFather(i)); 56 | if (numF.size() > 1) { 57 | printf("Error: %d components\n", int(numF.size())); 58 | } 59 | else { 60 | maxDepth = 0; 61 | dfs(1, -1, 1); 62 | for (auto it = tmp.begin(); it != tmp.end(); ++it) ans.insert(*it); 63 | tmp.clear(); 64 | maxDepth = 0; // 因为第一次求的的值不一定就是最大值 65 | dfs(*(ans.rbegin()), -1, 1); 66 | for (auto it = tmp.begin(); it != tmp.end(); ++it) ans.insert(*it); 67 | for (auto it = ans.begin(); it != ans.end(); ++it) printf("%d\n", *it); 68 | } 69 | return 0; 70 | } 71 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第十章 图算法专题/10.3 图的遍历/A1034 Head of a Gang.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | using namespace std; 6 | int id = 1; // 给人名编码 7 | map mp; 8 | map rmp; 9 | map gang; 10 | const int maxn = 2020; 11 | int n, k; 12 | int G[maxn][maxn] = {0}, weight[maxn] = {0}; 13 | bool vis[maxn] = {false}; 14 | 15 | int getId(string s) { 16 | if (!mp[s]) { 17 | mp[s] = id; 18 | rmp[id] = s; 19 | return id++; 20 | } 21 | else return mp[s]; 22 | } 23 | 24 | void dfs(int u, int& cnt, int& w, int& head) { 25 | vis[u] = true; ++cnt; 26 | if (weight[u] > weight[head]) head = u; 27 | for (int v = 1; v < maxn; ++v) { 28 | if (G[u][v] > 0) { // 判断vis放到了后面是避免环的影响 29 | w += G[u][v]; G[u][v] = G[v][u] = 0; 30 | if (!vis[v]) dfs(v, cnt, w, head); 31 | } 32 | } 33 | } 34 | 35 | 36 | int main() { 37 | cin >> n >> k; 38 | string a, b; int time; 39 | for (int i = 0; i < n; ++i) { 40 | cin >> a >> b >> time; 41 | int id1 = getId(a), id2 = getId(b); 42 | G[id1][id2] += time; G[id2][id1] += time; 43 | weight[id1] += time; weight[id2] += time; // 多存储一份权重是为了判断head 因为在图遍历中会清除重复边权 44 | } 45 | for (int u = 1; u < maxn; ++u) { 46 | if (!vis[u]) { 47 | int cnt = 0, w = 0, head = u; 48 | dfs(u, cnt, w, head); 49 | if (cnt > 2 && w > k) { 50 | gang[rmp[head]] = cnt; 51 | } 52 | } 53 | } 54 | printf("%d\n",int(gang.size())); 55 | for (auto it = gang.begin(); it != gang.end(); ++it) printf("%s %d\n", (it->first).c_str(), it->second); 56 | return 0; 57 | } 58 | 59 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第十章 图算法专题/10.3 图的遍历/A1076 Forwards on Weibo .cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | using namespace std; 6 | const int maxn = 1010; 7 | 8 | struct node { 9 | int id, layer; 10 | }; 11 | vector Adj[maxn]; 12 | bool inq[maxn] = {0}; 13 | int n, l, k, num, id; 14 | 15 | int bfs(node now) { 16 | queue Q; 17 | Q.push(now); inq[now.id] = true; 18 | int cnt = 0; 19 | while (!Q.empty()) { 20 | node fro = Q.front(); 21 | Q.pop(); 22 | for (int i = 0; i < Adj[fro.id].size(); ++i) { // fro写成now找了半天(吐血 23 | node v = Adj[fro.id][i]; 24 | v.layer = fro.layer + 1; 25 | if (!inq[v.id]) { 26 | if (v.layer > l) return cnt; 27 | Q.push(v); inq[v.id] = true; 28 | ++cnt; 29 | } 30 | } 31 | } 32 | return cnt; 33 | } 34 | 35 | int main() { 36 | scanf("%d %d", &n, &l); 37 | for (int i = 1; i <= n; ++i) { 38 | scanf("%d", &num); 39 | while (num--) { 40 | scanf("%d", &id); 41 | Adj[id].push_back(node{i, 0}); // 邻接表存储粉丝 42 | } 43 | } 44 | scanf("%d", &k); 45 | while (k--) { 46 | scanf("%d", &id); 47 | memset(inq, false, sizeof(inq)); 48 | printf("%d\n", bfs(node{id, 0})); 49 | } 50 | return 0; 51 | } 52 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第四章 算法初步/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/merelydust/Data-Structure-and-Algorithm/8e4d7dcd4793d10af9cce5d8714d4ec1a177f0eb/算法笔记讲解/SourceCode/第四章 算法初步/.DS_Store -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第四章 算法初步/TwoPointers/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/merelydust/Data-Structure-and-Algorithm/8e4d7dcd4793d10af9cce5d8714d4ec1a177f0eb/算法笔记讲解/SourceCode/第四章 算法初步/TwoPointers/.DS_Store -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第四章 算法初步/TwoPointers/A1029_Median.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | const int Max = 1000001; 4 | int a[Max]; 5 | int main(){ 6 | int n, m; 7 | scanf("%d", &n); 8 | for(int k = 0; k < n; ++k) 9 | scanf("%d", &a[k]); 10 | scanf("%d", &m); 11 | a[n] = (1<<31) -1; 12 | int mid = (n+m -1)/2; 13 | int cnt = 0, i = 0, j= 0, b = 0; 14 | if(m > 0){scanf("%d", &b);} 15 | while(cnt < mid){ 16 | if(j >= m) b = (1<<31) -1; 17 | if(a[i] < b)i++; 18 | else {scanf("%d", &b);j++;} 19 | cnt++; 20 | } 21 | printf("%d\n", ((a[i] 3 | #include 4 | using namespace std; 5 | 6 | int main() { 7 | int n, p; scanf("%d %d", &n, &p); 8 | long long arr[100010]; 9 | for (int i = 0; i < n; ++i) scanf("%lld", &arr[i]); 10 | sort(arr, arr+n); 11 | int i = 0, j = 0, cnt = 1; 12 | while (i < n && j < n) { 13 | while (j < n && arr[i] * p >= arr[j]) { 14 | cnt = max(j-i+1, cnt); j++; 15 | } 16 | i++; 17 | } 18 | printf("%d\n", cnt); 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第四章 算法初步/TwoPointers/A1089_Insert or Merge.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | const int maxn = 110; 6 | int origin[maxn], cpyOri[maxn], changed[maxn]; 7 | int n; 8 | 9 | bool isSame(int a[], int b[]) { 10 | for (int i = 0; i < n; ++i) { 11 | if (a[i] != b[i]) return false; 12 | } 13 | return true; 14 | } 15 | 16 | void printArray(int a[]) { 17 | for (int i = 0; i < n; ++i) { 18 | if (i) printf(" "); 19 | printf("%d", a[i]); 20 | } 21 | printf("\n"); 22 | } 23 | 24 | bool insertSort() { 25 | bool flag = false; 26 | for (int i = 1; i < n; ++i) { // 插入排序 第一位左边为空 不需要操作 所以i从1开始 27 | if (i != 1 && isSame(cpyOri, changed)) flag = true; // 不是初始序列且相同 28 | int tmp = cpyOri[i], j = i; // 用tmp暂存主元(要插入的元素)的值 j从右往左使主元左侧有序 29 | while (j >= 1 && cpyOri[j-1] > tmp) { //把大于主元的数往右挪 30 | cpyOri[j] = cpyOri[j-1]; --j; 31 | } 32 | cpyOri[j] = tmp; // 找到了插入位置 插入主元的值 33 | if (flag) return true; // 在这里返回 同时完成了目标序列的下一轮排序 34 | } 35 | return false; 36 | } 37 | 38 | void mergeSort() { 39 | bool flag = false; 40 | for (int step = 2; step / 2 <= n; step *= 2) { 41 | if (step != 2 && isSame(cpyOri, changed)) flag = true; 42 | for (int i = 0; i < n; i += step) sort(cpyOri+i, cpyOri+min(i+step, n)); //一组一组地排序 43 | if (flag) return; 44 | } 45 | } 46 | 47 | int main() { 48 | scanf("%d", &n); 49 | for (int i = 0; i < n; ++i) { 50 | scanf("%d", &origin[i]); cpyOri[i] = origin[i]; 51 | } 52 | for (int i = 0; i < n; ++i) scanf("%d", &changed[i]); 53 | if (insertSort()) { 54 | printf("Insertion Sort\n"); printArray(cpyOri); 55 | } 56 | else { 57 | printf("Merge Sort\n"); 58 | for (int i = 0; i < n; ++i) cpyOri[i] = origin[i]; 59 | mergeSort(); printArray(cpyOri); 60 | } 61 | return 0; 62 | } 63 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第四章 算法初步/二分/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/merelydust/Data-Structure-and-Algorithm/8e4d7dcd4793d10af9cce5d8714d4ec1a177f0eb/算法笔记讲解/SourceCode/第四章 算法初步/二分/.DS_Store -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第四章 算法初步/二分/A1010_Radix.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | #define MAX_NUM 9223372036854775807 6 | string n1, n2; int tag; 7 | long long radix1; 8 | unsigned long long lln1, lln2; 9 | 10 | unsigned long long transfer(string stringN, unsigned long long radix) { // 把字符串从radix进制转成十进制 11 | unsigned long long longN = 0; unsigned long long mul = 1;unsigned long len = stringN.length(); 12 | for (long i = len - 1; i >= 0; --i) { 13 | if (stringN[i] >= 'a') longN += (stringN[i] - 'a' + 10) * mul; 14 | else longN += (stringN[i] - '0') * mul; 15 | if (longN >= MAX_NUM) return MAX_NUM; // 判断溢出 16 | mul *= radix; 17 | } 18 | return longN; 19 | } 20 | 21 | unsigned long long findLeft(string num) { 22 | unsigned long long digit = 0, len = num.length(), tmp; 23 | for (int i = 0; i < len; ++i) { 24 | if (num[i] >= 'a') tmp = num[i] - 'a' + 10; 25 | else tmp = num[i] - '0'; 26 | if (tmp > digit) digit = tmp; 27 | } 28 | return digit+1; 29 | } 30 | 31 | unsigned long long search() { // 二分查找是否存在一个radix使条件成立 32 | unsigned long long left = findLeft(n2), right = max(left, lln1)+1, mid; 33 | // 上界是下界与另外一个进制中的较大值 34 | // 因为可操作的数字 如果在另一个数字的进制下还是小于另一个数字 在另一个数字的进制加一下还是他自己 不可能比另一个数字大了 35 | // 1000进制的10还是10 不是1001 36 | if (lln1 == MAX_NUM) return 0; 37 | while (left <= right) { // 查询元素必须存在 所以使用<= 38 | mid = (left + right) / 2; lln2 = transfer(n2, mid); 39 | if (lln2 == lln1) return mid; 40 | else if(lln2 < lln1) { // 每位的权重(radix)要增加 41 | left = mid + 1; 42 | } 43 | else if(lln2 > lln1 || lln2 >= MAX_NUM) { // 每位的权重要减小 44 | right = mid - 1; 45 | } 46 | } 47 | return 0; 48 | } 49 | 50 | void swap( unsigned long long& a, unsigned long long& b) { 51 | unsigned long long tmp = a; a = b; b = tmp; 52 | } 53 | 54 | int main() { 55 | cin >> n1 >> n2 >> tag >> radix1; 56 | if (n1.compare(n2) == 0){ 57 | cout << radix1 << endl; 58 | return 0; 59 | } 60 | if (radix1 ==1 || radix1==0){ 61 | cout << "Impossible" << endl; 62 | return 0; 63 | } 64 | if (tag == 2) swap(n1, n2); 65 | lln1 = transfer(n1, radix1); 66 | unsigned long long ans = search(); 67 | if (!ans) cout << "Impossible" << endl; 68 | else cout << ans << endl; 69 | } 70 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第四章 算法初步/二分/A1044_Shopping in Mars.cpp: -------------------------------------------------------------------------------- 1 | // 查找题->二分查找 2 | // 钱的累加是单调递增的->sum[] 3 | // 两个端点i,j之间的钱是sum[j]-sum[i-1] -> 4 | // sum[j]-sum[i-1]=m ->sum[j] = sum[i-1]+m -> 5 | // 枚举左端点i 查找是否存在使该等式恰好成立的右端点j 6 | // 否则 寻找第一个大于sum[i-1]+m的sum[j]->上界 7 | 8 | #include 9 | using namespace std; 10 | 11 | int sum[100010]; 12 | int upper_bound(int l, int r, int x) { 13 | int left = l, right = r, mid; 14 | while(left < right) { 15 | mid = (left + right) / 2; 16 | if (sum[mid] > x) right = mid; 17 | else left = mid + 1; 18 | } 19 | return left; 20 | } 21 | 22 | int main() { 23 | int n, m; scanf("%d %d", &n, &m); 24 | int nearm = 100010001; sum[0] = 0; 25 | for (int i = 1; i <= n; ++i) { 26 | scanf("%d", &sum[i]); sum[i] += sum[i-1]; 27 | } 28 | for (int i = 1; i <= n; ++i) { // 枚举左端点 29 | int j = upper_bound(i, n+1, sum[i-1]+m); // 找到右端点/上界 30 | if (sum[j-1] - sum[i-1] == m) { // 找到了恰好够付的方案 31 | nearm = m; break; 32 | } 33 | else if (j <=n && sum[j]-sum[i-1] < nearm) { // 大于m但更接近m的点 34 | nearm = sum[j]-sum[i-1]; // 更新nearm 35 | } 36 | } 37 | for (int i = 1; i <= n; ++i) { // 列出所有方案 m/nearm 38 | int j = upper_bound(i, n+1, sum[i-1]+nearm); 39 | if (sum[j-1]-sum[i-1] == nearm) printf("%d-%d\n", i, j-1); 40 | } 41 | return 0; 42 | } 43 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第四章 算法初步/二分/A1085 Perfect Sequenc_upper_bound().cpp: -------------------------------------------------------------------------------- 1 | // 二分查找法 使用upper_bound函数 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | const int maxn = 100010; 7 | int n, p, a[maxn]; // a为升序 8 | 9 | int main() { 10 | scanf("%d %d", &n, &p); 11 | for (int i = 0; i < n; ++i) scanf("%d", &a[i]); 12 | sort(a, a+n); 13 | int ans = 1; // 最大长度 至少有一个数 14 | for (int i = 0; i < n; ++i) { 15 | int end = upper_bound(a+i+1, a+n, (long long)a[i] * p) - a; // 上限为这个东西 16 | ans = max(ans, end - i); 17 | } 18 | printf("%d\n", ans); 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第四章 算法初步/二分/A1085 Perfect Sequence_BinarySearch.cpp: -------------------------------------------------------------------------------- 1 | // 二分查找法 (暴力枚举复杂度为n^2 会超时) 2 | // 排序后从左到右扫描数列 对于每一个a[i] 寻找从a[i+1]到a[n-1]中第一个超过a[i]*p的数字的位置end 3 | // 这样 end-i就是对位置i而言满足a[j] <= a[i]*p的最远长度 4 | // 取所有end-i的最大值即为所求 复杂度为logn 5 | #include 6 | #include 7 | #include 8 | using namespace std; 9 | 10 | const int maxn = 100010; 11 | int n, p, a[maxn]; // a为升序 12 | 13 | int binarySearch(int i, long long x) { // 在[i+1, n-1]中寻找第一个大于x的数的位置 14 | if (a[n-1] <= x) return n; // 如果所有数都不大于x 15 | int left = i+1, right = n-1, mid; 16 | while (left < right) { // 注意是<不是<= 因为x不需要真的存在于队列中 ==的时候就是把x该在的位置返回 17 | mid = (left + (right-left)/2); 18 | if (a[mid] > x) right = mid; // mid处符合条件 说明第一个符合条件在mid处或者mid的左边 19 | else left = mid+1; 20 | } 21 | return left; // while结束的时候left==right 22 | } 23 | 24 | int main() { 25 | scanf("%d %d", &n, &p); 26 | for (int i = 0; i < n; ++i) scanf("%d", &a[i]); 27 | sort(a, a+n); 28 | int ans = 1; // 最大长度 至少有一个数 29 | for (int i = 0; i < n; ++i) { 30 | int end = binarySearch(i, (long long)a[i] * p); // 第一个大于x的数字的位置 31 | ans = max(ans, end - i); 32 | } 33 | printf("%d\n", ans); 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第四章 算法初步/二分/木棒切割问题.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | const int maxn = 10010; 5 | 6 | int main() { 7 | int n, k; scanf("%d %d", &n, &k); // n个木棒 至少得到k段木棒 木棒不用整除 8 | int arr[maxn]; for (int i = 0; i < n; ++i) scanf("%d", &arr[i]); 9 | sort(arr, arr+n); 10 | int left = 1, right = arr[n-1]; // 长度至少为1 至多为最长木棒的长度 11 | while (left < right) { // 找到第一个满足tmpK < k的长度L 然后L-1即为所求 12 | int mid = (left + right) / 2, tmpK = 0; 13 | for (int i = 0 ; i < n; ++i) tmpK += arr[i] / mid; 14 | if (tmpK >= k) left = mid+1; 15 | else right = mid; 16 | } 17 | printf("%d\n", left - 1); 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第四章 算法初步/其他/A1093_Count PAT's.cpp: -------------------------------------------------------------------------------- 1 | // PAT的个数等于=(A左边P的个数)*(A右边T的个数)* A的个数 2 | // 为了更高效 这里的乘采用累加的方法 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | int main() { 8 | const int maxn= 100010; long long div = 1000000007; 9 | int leftP[maxn] = {0}, rightTNum = 0, ans = 0; 10 | string s; cin >> s; int len = s.length(); 11 | for (int i = 0; i < len; ++i) { 12 | if (i) leftP[i] = leftP[i-1]; 13 | if (s[i] == 'P') leftP[i]++; 14 | } 15 | for (int i = len; i >= 0; --i) { 16 | if (s[i] == 'T') rightTNum++; 17 | else if (s[i] == 'A') ans = (ans + leftP[i]*rightTNum) % div; 18 | } 19 | printf("%d\n", ans); 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第四章 算法初步/其他/A1101_Quick Sort .cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | int main() { 7 | int n; scanf("%d", &n); 8 | const int maxn = 100010, INF = (1<<31)-1; int arr[maxn]; 9 | int leftMax[maxn], rightMin[maxn]; leftMax[0] = -1; rightMin[n-1] = INF; 10 | for (int i = 0; i < n; ++i) scanf("%d", &arr[i]); 11 | for (int i = 1; i < n; ++i) leftMax[i] = max(leftMax[i-1], arr[i-1]); 12 | for (int i = n - 2; i >= 0; --i) rightMin[i] = min(rightMin[i+1], arr[i+1]); 13 | int ans[maxn]; int cnt = 0; 14 | for (int i = 0; i < n; ++i) { 15 | if (arr[i] >= leftMax[i] && arr[i] <= rightMin[i]) ans[cnt++] = arr[i]; 16 | } 17 | printf("%d\n", cnt); 18 | sort(ans, ans+cnt); 19 | for (int i = 0; i < cnt; ++i) { 20 | if (i) printf(" "); 21 | printf("%d", ans[i]); 22 | } 23 | printf("\n"); 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第四章 算法初步/排序/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/merelydust/Data-Structure-and-Algorithm/8e4d7dcd4793d10af9cce5d8714d4ec1a177f0eb/算法笔记讲解/SourceCode/第四章 算法初步/排序/.DS_Store -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第四章 算法初步/排序/A1012 The Best Rank.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | int ranks[1000000][4] = {0}; // 空间换时间 高效索引 按优先级存储 ranka rankc rankm ranke 6 | int subjectindex; 7 | char subject[4] = {'A', 'C', 'M', 'E'}; 8 | 9 | struct stu { 10 | int id, grade[4]; // 也按优先级存储 11 | }; 12 | 13 | bool cmp(stu a, stu b) { // 按不同的学科排序 14 | return a.grade[subjectindex] > b.grade[subjectindex]; 15 | } 16 | 17 | int main() { 18 | int n, m; scanf("%d %d", &n, &m); 19 | stu students[n]; 20 | for (int i = 0; i < n; ++i) { 21 | int total = 0; 22 | scanf("%d", &students[i].id); 23 | for (int j = 1; j < 4; ++j) { 24 | scanf("%d", &students[i].grade[j]); total += students[i].grade[j]; 25 | } 26 | students[i].grade[0] = total; // 大家平均数的分母都是4 取分子就行了 27 | } 28 | 29 | for (subjectindex = 0; subjectindex < 4; ++subjectindex) { // 填写四个ranks 30 | sort(students, students+n, cmp); 31 | int rank = 1, premark = students[0].grade[subjectindex]; 32 | for (int j = 0; j < n; ++j) { 33 | if (students[j].grade[subjectindex] != premark) { 34 | rank = j + 1; // j从0开始索引 所以这里要加一 35 | premark = students[j].grade[subjectindex]; 36 | } 37 | ranks[students[j].id][subjectindex] = rank; 38 | } 39 | } 40 | 41 | for (int i = 0; i < m; ++i) { // 查询 42 | int tmp; scanf("%d", &tmp); 43 | if (!ranks[tmp][0]) printf("N/A\n"); // 如果总分是0说明这个考生不存在 44 | else { 45 | int minindex = 0; 46 | for (int j = 0; j < 4; ++j) { 47 | if (ranks[tmp][j] < ranks[tmp][minindex]) minindex = j; 48 | } 49 | printf("%d %c\n", ranks[tmp][minindex], subject[minindex]); 50 | } 51 | } 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第四章 算法初步/排序/A1016 Phone Bills_统一法.cpp: -------------------------------------------------------------------------------- 1 | // 有三个诡异的超时点= = 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | using namespace std; 9 | 10 | struct record { 11 | string owner; 12 | int dd, hh, mm, time, status; // status0代表online 1代表offline 13 | }; 14 | 15 | bool cmp(record a, record b) { 16 | if (a.dd != b.dd) return a.dd < b.dd; 17 | else if (a.hh < b. hh) return a.hh < b.hh; 18 | else return a.mm < b.mm; 19 | } 20 | 21 | int tolls[24] = {0}, sumTolls[24] = {0}; 22 | 23 | double calCost(record a) { 24 | double cost = a.dd * 60 * sumTolls[23] + a.mm * tolls[a.hh]; 25 | cost += !a.hh ? 0 : 60 * sumTolls[a.hh-1]; 26 | return cost; 27 | } 28 | 29 | void cal(vector& v) { 30 | double total = 0; 31 | for (int i = 1; i < v.size(); i += 2) { 32 | printf("%02d:%02d:%02d %02d:%02d:%02d ", v[i-1].dd, v[i-1].hh, v[i-1].mm, v[i].dd, v[i].hh, v[i].mm); 33 | double cost = calCost(v[i]) - calCost(v[i-1]); 34 | printf("%d $%.2f\n", v[i].time-v[i-1].time, cost / 100.0); 35 | total += cost; 36 | } 37 | printf("Total amount: $%.2f\n", total / 100.0); 38 | } 39 | 40 | int main() { 41 | for (int i = 0; i < 24; ++i) { 42 | scanf("%d", &tolls[i]); 43 | if (i) sumTolls[i] = tolls[i] + sumTolls[i-1]; 44 | else sumTolls[i] = tolls[i]; 45 | } 46 | int n, month = 0; scanf("%d", &n); 47 | map > mp; record tmp; char str1[30] = {0}, str2[30] = {0}; 48 | for (int i = 0; i < n; ++i) { 49 | scanf("%s %d:%d:%d:%d %s", str1, &month, &tmp.dd, &tmp.hh, &tmp.mm, str2); 50 | tmp.owner = str1; tmp.status = !strcmp(str2, "on-line") ? 0 : 1; tmp.time = tmp.dd*24*60 + tmp.hh*60 + tmp.mm; 51 | mp[tmp.owner].push_back(tmp); 52 | } 53 | for (auto it = mp.begin(); it != mp.end(); ++it) { 54 | vector valid; sort(it->second.begin(), it->second.end(), cmp); 55 | for (int i = 1; i < it->second.size(); ++i) { 56 | if (!it->second[i-1].status && it->second[i].status) { 57 | valid.push_back(it->second[i-1]); valid.push_back(it->second[i]); 58 | } 59 | } 60 | if (valid.empty()) continue; 61 | printf("%s %02d\n", valid[0].owner.c_str(), month); 62 | cal(valid); 63 | } 64 | return 0; 65 | } 66 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第四章 算法初步/排序/A1016 Phone Bills_追及法.cpp: -------------------------------------------------------------------------------- 1 | // 有三个诡异的超时点 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | using namespace std; 9 | 10 | struct record { 11 | string owner; 12 | int dd, hh, mm, status; // status0代表online 1代表offline 13 | }; 14 | 15 | bool cmp(record a, record b) { 16 | if (a.dd != b.dd) return a.dd < b.dd; 17 | else if (a.hh < b. hh) return a.hh < b.hh; 18 | else return a.mm < b.mm; 19 | } 20 | 21 | int tolls[24]; 22 | void cal(vector& v) { 23 | double total = 0; 24 | for (int i = 1; i < v.size(); i += 2) { 25 | printf("%02d:%02d:%02d %02d:%02d:%02d ", v[i-1].dd, v[i-1].hh, v[i-1].mm, v[i].dd, v[i].hh, v[i].mm); 26 | int time = 0; double cost = 0; 27 | while (v[i-1].dd != v[i].dd || v[i-1].hh != v[i].hh || v[i-1].mm != v[i].mm) { 28 | ++v[i-1].mm; ++time; cost += tolls[v[i-1].hh]; 29 | if (v[i-1].mm == 60) { // 小时进位 30 | ++v[i-1].hh; v[i-1].mm = 0; 31 | } 32 | if (v[i-1].hh == 24) { // 天数进位 33 | ++v[i-1].dd; v[i-1].hh = 0; 34 | } 35 | } 36 | printf("%d $%.2f\n", time, cost / 100.0); 37 | total += cost; 38 | } 39 | printf("Total amount: $%.2f\n", total / 100.0); 40 | } 41 | 42 | int main() { 43 | for (int i = 0; i < 24; ++i) scanf("%d", &tolls[i]); 44 | int n, month = 0; scanf("%d", &n); 45 | map > mp; record tmp; char str1[30] = {0}, str2[30] = {0}; 46 | for (int i = 0; i < n; ++i) { 47 | scanf("%s %d:%d:%d:%d %s", str1, &month, &tmp.dd, &tmp.hh, &tmp.mm, str2); 48 | tmp.owner = str1; tmp.status = !strcmp(str2, "on-line") ? 0 : 1; 49 | mp[tmp.owner].push_back(tmp); 50 | } 51 | for (auto it = mp.begin(); it != mp.end(); ++it) { 52 | vector valid; sort(it->second.begin(), it->second.end(), cmp); 53 | for (int i = 1; i < it->second.size(); ++i) { 54 | if (!it->second[i-1].status && it->second[i].status) { 55 | valid.push_back(it->second[i-1]); valid.push_back(it->second[i]); 56 | } 57 | } 58 | if (valid.empty()) continue; 59 | printf("%s %02d\n", valid[0].owner.c_str(), month); 60 | cal(valid); 61 | } 62 | return 0; 63 | } 64 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第四章 算法初步/排序/A1025 PAT Ranking .cpp: -------------------------------------------------------------------------------- 1 | /*** 2 | n个考场 接下来n块 3 | k 每个考场人数 接下来k行 4 | 考生ID(13位)分数 5 | 6 | 输出 7 | 考生总数 按总排名从小到大输出 排名相同按ID字典序排名 8 | 考生ID 总排名 考场号 考场排名 9 | ***/ 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | using namespace std; 16 | 17 | struct stu { 18 | string id; int place, score, rank[2]; // rank[0]-考场排名 rank[1]总排名 19 | }; 20 | 21 | bool cmp(stu a, stu b) { 22 | if (a.score != b.score) return a.score > b.score; 23 | else return a.id < b.id; 24 | } 25 | 26 | void giveRank(vector& v, int now) { // now指示现在是考场排名还是总排名 27 | if (v.empty()) return; 28 | int r = 1, preScore = v[0].score; 29 | for (int i = 1; i <= v.size(); ++i) { 30 | if (v[i-1].score != preScore) { 31 | r = i; preScore = v[i-1].score; 32 | } 33 | v[i-1].rank[now] = r; 34 | } 35 | } 36 | 37 | int main() { 38 | int n, k; scanf("%d", &n); 39 | vector students; stu student; 40 | for (int i = 1; i <= n; ++i) { 41 | scanf("%d", &k); vector tmp; 42 | for (int j = 0; j < k; ++j) { 43 | cin >> student.id >> student.score; student.place = i; 44 | tmp.push_back(student); 45 | } 46 | sort(tmp.begin(), tmp.end(), cmp); giveRank(tmp, 0); 47 | students.insert(students.end(), tmp.begin(), tmp.end()); 48 | } 49 | sort(students.begin(), students.end(), cmp); giveRank(students, 1); 50 | cout << students.size() << endl; 51 | for (int i = 0; i < students.size(); ++i) { 52 | printf("%s %d %d %d\n", students[i].id.c_str(), students[i].rank[1], students[i].place, students[i].rank[0]); 53 | } 54 | return 0; 55 | } 56 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第四章 算法初步/排序/A1028 List Sorting.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | const int maxn = 100010; 6 | 7 | struct stu { 8 | string inf[3]; // id name grade 9 | }students[maxn]; 10 | 11 | int c; 12 | bool cmp(stu a, stu b) { 13 | if (a.inf[c] != b.inf[c]) return a.inf[c] < b.inf[c]; 14 | else return a.inf[0] < b.inf[0]; 15 | } 16 | 17 | int main() { 18 | int n; scanf("%d %d", &n, &c); --c; 19 | char str[10] = {0}; 20 | for (int i = 0; i < n; ++i) { 21 | for (int j = 0; j < 3; ++j) { 22 | scanf("%s", str); students[i].inf[j] = str; 23 | }; 24 | } 25 | sort(students, students+n, cmp); 26 | for (int i = 0; i < n; ++i) { 27 | for (int j = 0; j < 3; ++j) { 28 | printf("%s", students[i].inf[j].c_str()); 29 | if (j != 2) printf(" "); 30 | else printf("\n"); 31 | } 32 | } 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第四章 算法初步/排序/A1055 The World's Richest.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | using namespace std; 6 | const int maxn = 100010; 7 | 8 | struct peo { 9 | string name; 10 | int age, wealth; 11 | }people[maxn]; 12 | 13 | bool cmp(peo a, peo b) { 14 | if (a.wealth != b.wealth) return a.wealth > b.wealth; 15 | if (a.age != b.age) return a.age < b.age; 16 | return a.name < b.name; 17 | } 18 | 19 | int main() { 20 | int n, k; scanf("%d %d", &n, &k); 21 | for (int i = 0; i < n; ++i) { 22 | char str[10] = {0}; 23 | scanf("%s %d %d", str, &people[i].age, &people[i].wealth); 24 | people[i].name = str; 25 | } 26 | sort(people, people+n, cmp); 27 | for (int i = 1; i <= k; ++i) { 28 | printf("Case #%d:\n", i); 29 | int m, amin, amax; scanf("%d %d %d", &m, &amin, &amax); 30 | int cnt = 0; 31 | for (int j = 0; j < n; ++j) { 32 | if (cnt == m) break; 33 | if (people[j].age >= amin && people[j].age <= amax) { 34 | printf("%s %d %d\n", people[j].name.c_str(), people[j].age, people[j].wealth); 35 | ++cnt; 36 | } 37 | } 38 | if (!cnt) printf("None\n"); 39 | } 40 | return 0; 41 | } 42 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第四章 算法初步/排序/A1062 Talent and Virtue.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | struct stu { 8 | string id; 9 | int vir, tal, total; 10 | int grade; // 考生的等第 sages noblemen... 11 | }; 12 | 13 | bool cmp(stu a, stu b) { 14 | if (a.grade != b.grade) return a.grade < b.grade; // 等第优先级最高 15 | if (a.total != b.total) return a.total > b.total; 16 | else if (a.vir != b.vir) return a.vir > b.vir; 17 | return a.id < b.id; 18 | } 19 | 20 | int main() { 21 | int n, l, h; scanf("%d %d %d", &n, &l, &h); 22 | vector students; stu tmp; char tmpid[10] = {0}; 23 | while (n--) { 24 | scanf("%s %d %d", tmpid, &tmp.vir, &tmp.tal); tmp.id = tmpid; 25 | tmp.total = tmp.vir + tmp.tal; 26 | if (tmp.vir < l || tmp.tal < l) continue; // 不合格者不计入统计 27 | if (tmp.vir >= h && tmp.tal >= h) tmp.grade = 1; // 分等第 28 | else if (tmp.vir >= h) tmp.grade = 2; 29 | else if (tmp.vir >= tmp.tal) tmp.grade = 3; 30 | else tmp.grade = 4; 31 | students.push_back(tmp); 32 | } 33 | sort(students.begin(), students.end(), cmp); 34 | printf("%d\n", students.size()); 35 | for (int i = 0; i < students.size(); ++i) printf("%s %d %d\n", students[i].id.c_str(), students[i].vir, students[i].tal); 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第四章 算法初步/排序/A1075 PAT Judge.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | struct stu { 7 | int id; 8 | int score[6]; // 开6个 在接收输入的时候就不用对题号做处理了 9 | int total, perfect; 10 | bool submit; // 是否有能过编译的提交过决定是否被输出 11 | }students[100010]; // 数组下标为学生考号 12 | 13 | bool cmp(stu a, stu b) { 14 | if (a.total != b.total) return a.total > b.total; 15 | else if (a.perfect != b.perfect) return a.perfect > b.perfect; 16 | return a.id < b.id; 17 | } 18 | int n, k, m; 19 | void init() { // 技巧:单独init 20 | for (int i = 1; i <= n; ++i) { // It is then assumed that the user id's are 5-digit numbers from 00001 to N 21 | students[i].id = i; 22 | students[i].total = students[i].perfect = 0; 23 | students[i].submit = false; 24 | memset(students[i].score, -1, sizeof(students[i].score)); // 没提交过的分数为-1 跟提交了但是编译没过分数为0区别 25 | } 26 | } 27 | 28 | int main() { 29 | scanf("%d %d %d", &n, &k, &m); 30 | init(); 31 | int full[6]; // 记录题目分值 32 | for (int i = 1; i <= k; ++i) scanf("%d", &full[i]); 33 | int uid, pid, grade; 34 | for (int i = 0; i < m; ++i) { 35 | scanf("%d %d %d", &uid, &pid, &grade); 36 | if (grade != -1) students[uid].submit = true; // 有能过编译的提交 37 | if ((grade == -1) && (students[uid].score[pid] == -1)) { // 考生提交了 编译没通过 38 | students[uid].score[pid] = 0; 39 | } 40 | if (grade > students[uid].score[pid]) { // 更新每题最高得分 41 | students[uid].score[pid] = grade; 42 | if (grade == full[pid]) students[uid].perfect++; 43 | } 44 | } 45 | for (int i = 1; i <= n; ++i) { 46 | for (int j = 1; j <= k; ++j) { 47 | if (students[i].score[j] == -1) continue; 48 | students[i].total += students[i].score[j]; 49 | } 50 | } 51 | sort(students+1, students+1+n, cmp); 52 | int rank = 1; 53 | for (int i = 1; i <= n && students[i].submit; ++i) { 54 | if (!students[i].submit) continue; 55 | if (i > 1 && students[i].total != students[i-1].total) { 56 | rank = i; // 如果和前一位分数不同 其排名=其在队列中位置 57 | } 58 | printf("%d %05d %d", rank, students[i].id, students[i].total); 59 | for (int j = 1; j <= k; ++j) { 60 | if (students[i].score[j] == -1) printf(" -"); 61 | else printf(" %d", students[i].score[j]); 62 | } 63 | printf("\n"); 64 | } 65 | return 0; 66 | } 67 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第四章 算法初步/排序/A1080 Graduate Admission.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | struct stu { 7 | int id; 8 | double g1, g2, g3; 9 | int choice[5]; 10 | }; 11 | 12 | bool cmp(stu a, stu b) { 13 | if (a.g3 != b.g3) return a.g3 > b.g3; 14 | return a.g1 > b.g1; 15 | } 16 | bool cmpId(stu a, stu b) { 17 | return a.id < b.id; 18 | } 19 | 20 | int main() { 21 | int n, m, k; scanf("%d %d %d", &n, &m, &k); 22 | int schoolsLimit[100]; vector inschool[100]; 23 | vector students; stu tmp; 24 | for (int i = 0; i < m; ++i) scanf("%d", &schoolsLimit[i]); 25 | for (int i = 0; i < n; ++i) { 26 | tmp.id = i; 27 | scanf("%lf %lf", &tmp.g1, &tmp.g2); 28 | tmp.g3 = (tmp.g1 + tmp.g2) / 2; 29 | for (int j = 0; j < k; ++j) scanf("%d", &tmp.choice[j]); 30 | students.push_back(tmp); 31 | } 32 | 33 | sort(students.begin(), students.end(), cmp); // rank靠前的先安排 34 | for (int i = 0; i < n; ++i) { 35 | for (int j = 0; j < k; ++j) { 36 | int want = students[i].choice[j]; 37 | if (inschool[want].size() < schoolsLimit[want]) { // 想去的学校还有名额 38 | inschool[want].push_back(students[i]); break; 39 | } 40 | else { 41 | if (inschool[want].back().g3 == students[i].g3 && inschool[want].back().g1 == students[i].g1) { // 没名额了 但是该考生和该校录取的最后一名高考总分相同 42 | inschool[want].push_back(students[i]); break; 43 | } 44 | } 45 | } 46 | } 47 | for (int i = 0; i < m; ++i) { 48 | if (inschool[i].size() == 0) printf("\n"); 49 | else { 50 | sort(inschool[i].begin(), inschool[i].end(), cmpId); 51 | for (int j = 0; j < inschool[i].size(); ++j) { 52 | if (j) printf(" "); 53 | printf("%d", inschool[i][j].id); 54 | } 55 | printf("\n"); 56 | } 57 | } 58 | return 0; 59 | } 60 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第四章 算法初步/排序/A1083 List Grades.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | struct stu { 8 | string name, id; 9 | int grade; 10 | }; 11 | 12 | bool cmp(stu a, stu b) { 13 | return a.grade < b.grade; 14 | } 15 | 16 | int main() { 17 | int n; cin >> n; 18 | vector students; stu tmp; 19 | for (int i = 0; i < n; ++i) { 20 | cin >> tmp.name >> tmp.id >> tmp.grade; 21 | students.push_back(tmp); 22 | } 23 | int grade1, grade2; cin >> grade1 >> grade2; 24 | sort(students.begin(), students.end(), cmp); 25 | bool find = false; 26 | for (int i = n-1; i >= 0; --i) { 27 | if (students[i].grade < grade1) break; 28 | if (students[i].grade >= grade1 && students[i].grade <= grade2) { 29 | cout << students[i].name << ' ' << students[i].id << endl; 30 | find = true; 31 | } 32 | } 33 | if (!find) cout << "NONE" << endl; 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第四章 算法初步/排序/A1095 Cars on Campus.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | struct car { 10 | char id[8]; 11 | int time; 12 | char status[4]; 13 | }all[10010], valid[10010]; 14 | 15 | int timetoint(int hh, int mm, int ss) { 16 | return hh * 3600 + mm * 60 + ss; 17 | } 18 | 19 | bool cmpByIdAndTime(car a, car b) { 20 | if (strcmp(a.id, b.id)) return strcmp(a.id, b.id) < 0; 21 | return a.time < b.time; 22 | } 23 | 24 | bool cmpByTime(car a, car b) { 25 | return a.time < b.time; 26 | } 27 | 28 | int main() { 29 | int n, k, hh, mm, ss; 30 | map parktime; // car->staytime 31 | scanf("%d %d", &n, &k); 32 | for (int i = 0; i < n; ++i) { 33 | scanf("%s %d:%d:%d %s", all[i].id, &hh, &mm, &ss, all[i].status); 34 | all[i].time = timetoint(hh, mm, ss); 35 | } 36 | sort(all, all+n, cmpByIdAndTime); 37 | int maxtime = -1; int validnum = 0; 38 | for (int i = 0; i < n-1; ++i) { 39 | if (!strcmp(all[i].id, all[i+1].id) && 40 | !strcmp(all[i].status, "in") && 41 | !strcmp(all[i+1].status, "out")) { 42 | valid[validnum++] = all[i]; valid[validnum++] = all[i+1]; 43 | int intime = all[i+1].time - all[i].time; 44 | parktime[all[i].id] += intime; 45 | maxtime = max(maxtime, parktime[all[i].id]); 46 | } 47 | } 48 | sort(valid, valid+validnum, cmpByTime); 49 | int now = 0, numcar = 0; 50 | for (int i = 0; i < k; ++i) { 51 | scanf("%d:%d:%d", &hh, &mm, &ss); 52 | int time = timetoint(hh, mm, ss); 53 | while (now < validnum && valid[now].time <= time) { 54 | if (!strcmp(valid[now].status, "in")) ++numcar; 55 | else --numcar; 56 | ++now; 57 | } 58 | printf("%d\n", numcar); 59 | } 60 | map::iterator it; 61 | for (it = parktime.begin(); it != parktime.end(); ++it) { 62 | if (it->second == maxtime) printf("%s ", it->first.c_str()); 63 | } 64 | printf("%02d:%02d:%02d\n", maxtime / 3600, maxtime % 3600 / 60, maxtime % 60); 65 | return 0; 66 | } 67 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第四章 算法初步/散列/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/merelydust/Data-Structure-and-Algorithm/8e4d7dcd4793d10af9cce5d8714d4ec1a177f0eb/算法笔记讲解/SourceCode/第四章 算法初步/散列/.DS_Store -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第四章 算法初步/散列/A1041 Be Unique.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int main() { 5 | int arr[100001] = {0}; 6 | int hash[10001] = {0}; 7 | int n; scanf("%d", &n); 8 | for (int i = 0; i < n; ++i) { 9 | scanf("%d", &arr[i]); hash[arr[i]]++; 10 | } 11 | int win = 0; 12 | for (int i = 0; i < n; ++i) { 13 | if (hash[arr[i]] == 1) { 14 | win = arr[i]; break; 15 | } 16 | } 17 | if (win) printf("%d\n", win); 18 | else printf("None\n"); 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第四章 算法初步/散列/A1048 Find Coins.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | const int maxn = 1010; 4 | int hashtable[1010] = {0}; // 下标对应面额 5 | 6 | int main() { 7 | int n, m, tmp; scanf("%d %d", &n, &m); 8 | for (int i = 0; i < n; ++i) { 9 | scanf("%d", &tmp); ++hashtable[tmp]; 10 | } 11 | for (int i = 1; i < maxn; ++i) { // 不能<=500 题目的bug 12 | if (hashtable[i] && hashtable[m-i]) { 13 | if (i == m-i && hashtable[i] < 2) continue; 14 | printf("%d %d\n", i, m-i); return 0; 15 | } 16 | } 17 | printf("No Solution\n"); 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第四章 算法初步/散列/A1050 String Subtraction.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | int main() { 6 | string s1, s2; getline(cin, s1); getline(cin, s2); 7 | int hash[128] = {0}; 8 | for (int i = 0, len = s2.length(); i < len; ++i) hash[s2[i]] = 1; 9 | for (int i = 0, len = s1.length(); i < len; ++i) { 10 | if (hash[s1[i]]) continue; 11 | cout << s1[i]; 12 | } 13 | cout << endl; 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第四章 算法初步/散列/A1084 Broken Keyboard.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | int main() { 7 | int hashtable[128] = {0}; // 数组下标为字符ascii码 一共128位 8 | string s1, s2; cin >> s1 >> s2; 9 | int i = 0, j = 0; 10 | int len1 = s1.length(), len2 = s2.length(); 11 | for (; i < len1; ++i) { 12 | s1[i] = toupper(s1[i]); 13 | if (s1[i] != toupper(s2[j])) { 14 | if (!hashtable[s1[i]]) { 15 | cout << s1[i]; hashtable[s1[i]] = 1; 16 | } 17 | } else ++j; 18 | } 19 | cout << endl; 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第四章 算法初步/散列/A1092 To Buy or Not to Buy.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | int main() { 7 | int owner[128] = {0}; 8 | bool enough = true; 9 | int miss = 0, extra = 0; 10 | string s1, s2; cin >> s1 >> s2; 11 | for (int i = 0; i < s1.length(); ++i) owner[s1[i]]++; 12 | for (int i = 0; i < s2.length(); ++i) { 13 | owner[s2[i]]--; 14 | if (owner[s2[i]] < 0) { 15 | enough = false; miss++; 16 | } 17 | } 18 | if (!enough) printf("No %d\n", miss); 19 | else { 20 | for (int i = 0; i < 128; ++i) extra += owner[i]; 21 | printf("Yes %d\n", extra); 22 | } 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第四章 算法初步/散列/B1005 继续(3n+1)猜想.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | int main() { 6 | int n; scanf("%d", &n); 7 | int num, cnt = 0, hashtable[110] = {0}; 8 | set > st; 9 | while (n--) { 10 | scanf("%d", &num); st.insert(num); 11 | do { 12 | num = num % 2 ? (3*num+1)/2 : num/2; 13 | if (num > 100) continue; // 可能会产生大于100的值 14 | hashtable[num] = 1; 15 | } while (num != 1); 16 | } 17 | for (auto it = st.begin(); it != st.end(); ++it) { 18 | if (!hashtable[*it]) ++cnt; // 记录共有几个关键数 19 | } 20 | for (auto it = st.begin(); it != st.end(); ++it) { 21 | if (!hashtable[*it]) { 22 | printf("%d", *it); --cnt; 23 | if (cnt) printf(" "); 24 | } 25 | } 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第四章 算法初步/散列/B1033 旧键盘打字.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | int hashtable[256] = {0}; 7 | 8 | int main() { 9 | string broken, given; getline(cin, broken); getline(cin, given); // 一个小坑 第一行可能是空的 所以不能cin 10 | bool capital = broken.find("+") == string::npos ? true : false; 11 | for (int i = 0, len = broken.length(); i < len; ++i) hashtable[tolower(broken[i])] = 1; 12 | for (int i = 0, len = given.length(); i < len; ++i) { 13 | if (!capital && isupper(given[i])) continue; 14 | if (!hashtable[tolower(given[i])]) cout << given[i]; 15 | } 16 | cout << endl; 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第四章 算法初步/散列/B1038 统计同成绩学生.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int main() { 5 | int score[101] = {0}; 6 | int n; scanf("%d", &n); 7 | for (int i = 0; i < n; ++i) { 8 | int tmp; scanf("%d", &tmp); score[tmp]++; 9 | } 10 | int k; scanf("%d", &k); 11 | for (int i = 0; i < k; ++i) { 12 | int tmp; scanf("%d", &tmp); 13 | if (i) printf(" "); 14 | printf("%d", score[tmp]); 15 | } 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第四章 算法初步/散列/B1042 字符统计.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | int main() { 7 | string s; getline(cin, s); 8 | int hash[129] = {0}; 9 | for (int i = 0, len = s.length(); i < len; ++i) hash[tolower(s[i])]++; 10 | int max = -1; char maxch = 'a'; 11 | for (int i = 97; i <= 122; ++i) { 12 | if (hash[i] > max) { 13 | max = hash[i]; maxch = i; 14 | } 15 | } 16 | cout << maxch << ' ' << max << endl; 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第四章 算法初步/散列/B1043 输出PATest.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | int main() { 7 | string s1, s2 = "PATest"; getline(cin, s1); 8 | map mp; for (int i = 0, len = s1.length(); i < len; ++i) ++mp[s1[i]]; // 记录每个字符出现次数 9 | bool end = false; 10 | while (!end) { 11 | end = true; 12 | for (int i = 0; i < 6; ++i) { 13 | if (mp[s2[i]]) { 14 | cout << s2[i]; --mp[s2[i]]; end = false; 15 | } 16 | } 17 | } 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第四章 算法初步/散列/B1047 编程团体赛 .cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int main() { 5 | int hash[1001] = {0}; 6 | int n; scanf("%d", &n); 7 | while (n--) { 8 | int num, eat, grade; scanf("%d-%d %d", &num, &eat, &grade); 9 | hash[num] += grade; 10 | } 11 | int max = -1, maxindex = 0; 12 | for (int i = 1; i < 1001; ++i) { 13 | if (hash[i] > max) { 14 | max = hash[i]; maxindex = i; 15 | } 16 | } 17 | printf("%d %d\n", maxindex, max); 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第四章 算法初步/贪心/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/merelydust/Data-Structure-and-Algorithm/8e4d7dcd4793d10af9cce5d8714d4ec1a177f0eb/算法笔记讲解/SourceCode/第四章 算法初步/贪心/.DS_Store -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第四章 算法初步/贪心/A1033 To Fill or Not to Fill .cpp: -------------------------------------------------------------------------------- 1 | // 核心思想:尽量在便宜的加油站充钱 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | struct station { 7 | double distance, price; 8 | }stations[510]; 9 | 10 | bool cmp(station a, station b) { 11 | return a.distance < b.distance; 12 | } 13 | 14 | int main() { 15 | double cap, aimDistance, unitRun; int n; 16 | scanf("%lf %lf %lf %d", &cap, &aimDistance, &unitRun, &n); 17 | double FULLRUN = cap * unitRun; 18 | for (int i = 0; i < n; ++i) scanf("%lf %lf", &stations[i].price, &stations[i].distance); 19 | stations[n].distance = aimDistance; stations[n].price = 0; // 把终点也看作一个加油站 20 | sort(stations, stations+n+1, cmp); 21 | if (stations[0].distance) { // 如果出生点没有充钱的地方 22 | printf("The maximum travel distance = 0.00\n"); return 0; 23 | } 24 | int now = 0; // 当前所在加油站编号 25 | double money = 0, gas = 0; 26 | while (now < n) { 27 | int minPriceIndex = -1; double minPrice = 100000; // 每次循环都选择前方加油站里最便宜的加油站 28 | for (int i = now+1; i <= n && stations[i].distance-stations[now].distance <= FULLRUN; ++i) { // within FULLRUN 找到第一个油价低于当前加油站的加油站 如果没有 就高个里挑最矮 29 | if (stations[i].price < minPrice) { 30 | minPrice = stations[i].price; minPriceIndex = i; 31 | if (minPrice < stations[now].price) break; // 比now还便宜 马上去 32 | } 33 | } 34 | if (minPriceIndex == -1) break; // FULLRANK内找不到续命的加油站 退出循环 35 | // 能找到 算钱 36 | double needGas = (stations[minPriceIndex].distance - stations[now].distance) / unitRun; 37 | if (minPrice < stations[now].price) { // 如果下一轮最便宜的比now还便宜 这站充enough的钱就行(涵盖了终点的情况 终点的price是0 是最低的) 38 | if (gas < needGas){ 39 | money += (needGas - gas) * stations[now].price; 40 | gas = 0; // 到达下一站 正好耗尽gas 41 | } else gas -= needGas; 42 | } 43 | else { // 下一轮最便宜的比now贵 now加满油 44 | money += (cap - gas) * stations[now].price; 45 | gas = cap - needGas; // 到达下一站后剩下的油 46 | } 47 | now = minPriceIndex; // 到达下一站 进入下一轮循环 48 | } 49 | if (now == n) printf("%.2lf\n", money); 50 | else printf("The maximum travel distance = %.2lf\n", stations[now].distance + FULLRUN); 51 | return 0; 52 | } 53 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第四章 算法初步/贪心/A1037 Magic Coupon .cpp: -------------------------------------------------------------------------------- 1 | // 思路 让同号最大的两个数相乘 2 | #include 3 | #include 4 | #include 5 | #include 6 | using namespace std; 7 | 8 | int main() { 9 | int nc, np; int tmp; 10 | vector cPositive, cNegative, pPositive, pNegative; 11 | scanf("%d", &nc); 12 | for (int i = 0; i < nc; ++i) { 13 | scanf("%d", &tmp); 14 | if (tmp >= 0) cPositive.push_back(tmp); 15 | else cNegative.push_back(tmp); 16 | } 17 | scanf("%d", &np); 18 | for (int i = 0; i < np; ++i) { 19 | scanf("%d", &tmp); 20 | if (tmp >= 0) pPositive.push_back(tmp); 21 | else pNegative.push_back(tmp); 22 | } 23 | sort(cPositive.begin(), cPositive.end(), greater()); 24 | sort(pPositive.begin(), pPositive.end(), greater()); 25 | sort(cNegative.begin(), cNegative.end()); 26 | sort(pNegative.begin(), pNegative.end()); 27 | long long money = 0; 28 | int size1 = cPositive.size(), size2 = pPositive.size(), size3 = cNegative.size(), size4 = pNegative.size(); 29 | for (int i = 0; i < size1 && i < size2; ++i) money += cPositive[i] * pPositive[i]; 30 | for (int i = 0; i < size3 && i < size4; ++i) money += cNegative[i] * pNegative[i]; 31 | printf("%lld\n", money); 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第四章 算法初步/贪心/A1038 Recover the Smallest Number .cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | bool cmp(string a, string b) { 7 | return a+b < b+a; // "32" "321" -> "321" "32" 8 | } 9 | 10 | int main() { 11 | int n; cin >> n; 12 | string arr[10010]; 13 | for (int i = 0; i < n; ++i) cin >> arr[i]; 14 | sort(arr, arr+n, cmp); 15 | string ans = ""; 16 | for (int i = 0; i < n; ++i) ans += arr[i]; 17 | while (ans.length() > 1 && ans[0] == '0') ans.erase(0, 1); // 答案字符串至少有一位 18 | cout << ans << endl; 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第四章 算法初步/贪心/A1067 Sort with Swap(0, i) .cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | const int maxn = 100010; 6 | int pos[maxn]; // 下标数字对应其所处位置 7 | 8 | int main() { 9 | int n, num, unsort = 0, cnt = 0; scanf("%d", &n); 10 | for (int i = 0; i < n; ++i) { 11 | scanf("%d", &num); pos[num] = i; 12 | if (num && pos[num] != num) ++unsort; // 除了0以外的错乱数字个数 13 | } 14 | int start = 1; // 为防止超时 记录无序子序列的开始位置 15 | while (unsort) { 16 | if (pos[0] == 0) { 17 | while (start < n) { 18 | if (pos[start] != start) break; 19 | ++start; 20 | } 21 | swap(pos[0], pos[start]); ++cnt; // 交换0和找到的第一个不在本位的数字的位置 22 | } 23 | while (pos[0] != 0) { 24 | swap(pos[0], pos[pos[0]]); ++cnt; --unsort; // 把0所占的数字pos[0]的位置还给它 数字pos[0]的位置在pos[pos[0]] 25 | } 26 | } 27 | printf("%d\n", cnt); 28 | } 29 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第四章 算法初步/贪心/B1020 月饼 .cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | struct mooncake { 7 | double amount, total, price; 8 | }; 9 | bool cmp(mooncake a, mooncake b) { 10 | return a.price > b.price; 11 | } 12 | int main() { 13 | int n, d; cin >> n >> d; 14 | mooncake cakes[n]; 15 | for (int i = 0; i < n; i++) cin >> cakes[i].amount; 16 | for (int i = 0; i < n; i++) { 17 | cin >> cakes[i].total; 18 | cakes[i].price = cakes[i].total / cakes[i].amount; 19 | } 20 | sort(cakes, cakes+n, cmp); 21 | double wage = 0.0; 22 | for (int i = 0; i < n && d; i++) { 23 | if (d >= cakes[i].amount) { 24 | wage += cakes[i].total; 25 | d -= cakes[i].amount; 26 | } 27 | else { 28 | wage += cakes[i].price * d; 29 | d = 0; 30 | } 31 | } 32 | cout << fixed << setprecision(2) << wage << endl; 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /算法笔记讲解/SourceCode/第四章 算法初步/贪心/B1023 组个最小数.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int main() { 5 | int arr[10] = {0}; for (int i = 0; i < 10; ++i) scanf("%d", &arr[i]); 6 | for (int i = 1; i < 10; ++i) { 7 | if (arr[i]) { 8 | printf("%d", i); --arr[i]; break; 9 | } 10 | } 11 | for (int i = 0; i < 10; ++i) { 12 | while (arr[i]--) printf("%d", i); 13 | } 14 | return 0; 15 | } 16 | --------------------------------------------------------------------------------