├── AlgorithmNote ├── AlgorithmNote-Code │ ├── 第10章 图算法专题 │ │ ├── A1003-BF.cpp │ │ ├── A1003-SPFA.cpp │ │ ├── A1003.cpp │ │ ├── A1013.cpp │ │ ├── A1018.cpp │ │ ├── A1021.cpp │ │ ├── A1030-dj+dfs.cpp │ │ ├── A1030.cpp │ │ ├── A1034.cpp │ │ ├── A1072.cpp │ │ ├── A1076.cpp │ │ └── A1087.cpp │ ├── 第11章 动态规划专题 │ │ ├── A1007.cpp │ │ ├── A1040.cpp │ │ ├── A1045-LCS.cpp │ │ ├── A1045.cpp │ │ ├── A1068-dp.cpp │ │ └── A1068.cpp │ ├── 第12+13章 字符串+专题扩展 │ │ ├── A1014.cpp │ │ ├── A1017.cpp │ │ ├── A1026.cpp │ │ └── B1050.cpp │ ├── 第3章 入门模拟 │ │ ├── 图形输出 │ │ │ ├── A1031.cpp │ │ │ ├── B1027.cpp │ │ │ └── B1306.cpp │ │ ├── 字符串处理 │ │ │ ├── A1001.cpp │ │ │ ├── A1005.cpp │ │ │ ├── A1035.cpp │ │ │ ├── A1077.cpp │ │ │ ├── A1082.cpp │ │ │ ├── B1002.cpp │ │ │ ├── B1006-1.cpp │ │ │ ├── B1006.cpp │ │ │ ├── B1009.cpp │ │ │ ├── B1014 │ │ │ │ └── A1061.cpp │ │ │ ├── B1021.cpp │ │ │ ├── B1024-A1073.cpp │ │ │ ├── B1031.cpp │ │ │ └── B1048.cpp │ │ ├── 查找元素 │ │ │ ├── A1006.cpp │ │ │ ├── A1011.cpp │ │ │ ├── A1036.cpp │ │ │ ├── B1004.cpp │ │ │ ├── B1004.py │ │ │ ├── B1028.cpp │ │ │ ├── B1028.py │ │ │ ├── B1032.cpp │ │ │ └── B1041.cpp │ │ ├── 简单模拟 │ │ │ ├── 1026.cpp │ │ │ ├── 1046.cpp │ │ │ ├── A1002.cpp │ │ │ ├── A1009.cpp │ │ │ ├── A1042.cpp │ │ │ ├── A1046-2.cpp │ │ │ ├── A1046.cpp │ │ │ ├── A1065.cpp │ │ │ ├── B1001害死人不偿命的(3n+1)猜想.cpp │ │ │ ├── B1008-2.cpp │ │ │ ├── B1008-3.cpp │ │ │ ├── B1008-4.cpp │ │ │ ├── B1010.cpp │ │ │ ├── B1011.cpp │ │ │ ├── B1012.cpp │ │ │ ├── B1016.cpp │ │ │ └── B1018.cpp │ │ └── 进制转换 │ │ │ ├── A1019.cpp │ │ │ ├── A1027.cpp │ │ │ ├── A1058-2.cpp │ │ │ ├── A1058.cpp │ │ │ ├── B1022.cpp │ │ │ └── B1037.cpp │ ├── 第4章 算法初步 │ │ ├── two pointer │ │ │ ├── A1029.cpp │ │ │ ├── A1030.cpp │ │ │ ├── A1048.cpp │ │ │ └── B1035.cpp │ │ ├── 二分 │ │ │ ├── A1010.cpp │ │ │ ├── A1030-2.cpp │ │ │ ├── A1044.cpp │ │ │ ├── A1048.cpp │ │ │ └── B1030.cpp │ │ ├── 其他高效技巧和算法 │ │ │ ├── B1040.cpp │ │ │ └── B1045.cpp │ │ ├── 排序 │ │ │ ├── A1012.cpp │ │ │ ├── A1015.cpp │ │ │ ├── A1016.cpp │ │ │ ├── A1025.cpp │ │ │ ├── A1028.cpp │ │ │ ├── A1055.cpp │ │ │ ├── A1075.cpp │ │ │ ├── A1080.cpp │ │ │ ├── A1083.cpp │ │ │ └── A1095.cpp │ │ ├── 散列 │ │ │ ├── A1041.cpp │ │ │ ├── A1048.cpp │ │ │ ├── A1050.cpp │ │ │ ├── B1005.cpp │ │ │ ├── B1029.cpp │ │ │ ├── B1033.cpp │ │ │ ├── B1038.cpp │ │ │ ├── B1039.cpp │ │ │ ├── B1042.cpp │ │ │ ├── B1043.cpp │ │ │ └── B1047.cpp │ │ └── 贪心 │ │ │ ├── A1033.cpp │ │ │ ├── A1037.cpp │ │ │ ├── A1038.cpp │ │ │ ├── A1067.cpp │ │ │ ├── B1020.cpp │ │ │ └── B1023.cpp │ ├── 第5章 数学问题 │ │ ├── gcd+lcm+分数四则运算+素数 │ │ │ ├── A1015.cpp │ │ │ ├── A1023.cpp │ │ │ ├── A1024.cpp │ │ │ ├── A1059.cpp │ │ │ ├── A1078.cpp │ │ │ ├── A1081.cpp │ │ │ ├── A1088.cpp │ │ │ ├── A1096.cpp │ │ │ ├── B1007.cpp │ │ │ ├── B1008-2.cpp │ │ │ ├── B1008.cpp │ │ │ ├── B1013.cpp │ │ │ └── B1017.cpp │ │ └── 简单数学 │ │ │ ├── A1008.cpp │ │ │ ├── A1049-1.cpp │ │ │ ├── A1049.cpp │ │ │ ├── B1003.cpp │ │ │ ├── B1019.cpp │ │ │ └── B1049.cpp │ ├── 第6章 STL │ │ ├── A1022.cpp │ │ ├── A1039-2.cpp │ │ ├── A1039.cpp │ │ ├── A1047.cpp │ │ ├── A1054-2.cpp │ │ ├── A1054.cpp │ │ ├── A1060.cpp │ │ ├── A1063.cpp │ │ ├── A1071.cpp │ │ └── A1100.cpp │ ├── 第7章 数据结构专题1 │ │ ├── A1032.cpp │ │ ├── A1051.cpp │ │ ├── A1052.cpp │ │ ├── A1056.cpp │ │ ├── A1097.cpp │ │ └── B1025.cpp │ ├── 第8章 搜索专题 │ │ ├── A1091.cpp │ │ ├── A1103.cpp │ │ └── dfs.cpp │ └── 第9章 数据结构专题2 │ │ ├── A1004.cpp │ │ ├── A1020.cpp │ │ ├── A1043.cpp │ │ ├── A1053.cpp │ │ ├── A1064-2.cpp │ │ ├── A1064.cpp │ │ ├── A1066.cpp │ │ ├── A1079-dfs.cpp │ │ ├── A1079.cpp │ │ ├── A1086-2.cpp │ │ ├── A1086.cpp │ │ ├── A1090.cpp │ │ ├── A1094.cpp │ │ ├── A1098.cpp │ │ ├── A1099.cpp │ │ ├── A1102.cpp │ │ ├── A1106.cpp │ │ └── A1107.cpp ├── AlgorithmNote-Note │ ├── PTA错题集.md │ ├── 第10章 图算法专题 │ │ └── 图遍历+最短路.md │ ├── 第11章 动态规划专题 │ │ └── 动态规划·.md │ ├── 第12+13章 字符串+专题扩展 │ │ └── 字符串哈希+分块+树状数组+模拟.md │ ├── 第3章 入门模拟 │ │ ├── 图形输出.md │ │ ├── 字符串处理.md │ │ ├── 查找元素.md │ │ ├── 简单模拟.md │ │ └── 进制转换.md │ ├── 第4章 算法初步 │ │ ├── two pointer.md │ │ ├── 二分.md │ │ ├── 其他高效技巧与算法.md │ │ ├── 排序.md │ │ ├── 散列.md │ │ └── 贪心.md │ ├── 第5章 数学问题 │ │ ├── gcd+lcm+分数四则运算+素数.md │ │ └── 简单数学.md │ ├── 第6章 STL │ │ └── vector+set+map+string.md │ ├── 第7章 数据结构专题1 │ │ └── 栈+队列+链表.md │ ├── 第8章 搜索专题 │ │ └── DFS+BFS.md │ └── 第9章 数据结构专题2 │ │ └── 二叉树+树遍历+BST+AVL+并查集+堆.md └── README.md ├── CCF-CSP ├── CSP-Code │ ├── 第1题 │ │ ├── 201312-1.cpp │ │ ├── 201403-1.cpp │ │ ├── 201409-1.cpp │ │ ├── 201412-1.cpp │ │ ├── 201503-1.cpp │ │ ├── 201509-1.cpp │ │ ├── 201512-1.cpp │ │ ├── 201604-1.cpp │ │ ├── 201609-1.cpp │ │ ├── 201612-1-2-upper.cpp │ │ ├── 201612-1.cpp │ │ ├── 201703-1.cpp │ │ ├── 201709-1.cpp │ │ ├── 201712-1.cpp │ │ ├── 201803-1.cpp │ │ ├── 201809-1.cpp │ │ ├── 201812-1.cpp │ │ └── 201903-1.cpp │ ├── 第2题 │ │ ├── 201703-2.cpp │ │ ├── 201709-2.cpp │ │ ├── 201712-2-queue.cpp │ │ ├── 201712-2.cpp │ │ ├── 201803-2-2.cpp │ │ ├── 201803-2.cpp │ │ ├── 201809-2.cpp │ │ ├── 201812-2.cpp │ │ ├── 201903-2.cpp │ │ ├── ans.txt │ │ ├── output.txt │ │ ├── run.bat │ │ ├── test.cpp │ │ └── test.txt │ ├── 第3题 │ │ ├── 201312-3.cpp │ │ ├── 201403-3.cpp │ │ ├── 201409-3-regex.cpp │ │ ├── 201409-3.cpp │ │ ├── 201412-3.cpp │ │ ├── 201503-3.cpp │ │ ├── 201509-3-find.cpp │ │ ├── 201509-3-regex2.cpp │ │ ├── 201509-3.cpp │ │ ├── 201512-3.cpp │ │ ├── 201604-3-2.cpp │ │ ├── 201604-3.cpp │ │ ├── 201609-3.cpp │ │ ├── 201612-3-opt.cpp │ │ ├── 201612-3.cpp │ │ ├── 201703-3.cpp │ │ ├── 201709-3.cpp │ │ ├── 201712-3.cpp │ │ ├── 201803-3-regex.cpp │ │ ├── 201803-3.cpp │ │ ├── 201809-3.cpp │ │ ├── 201812-3.cpp │ │ ├── 201903-3-1-2.cpp │ │ ├── 201903-3.cpp │ │ ├── 201909-3.cpp │ │ ├── ans.txt │ │ ├── main.cpp │ │ ├── output.txt │ │ ├── run.bat │ │ └── test.txt │ └── 第4题 │ │ ├── 201312-4.cpp │ │ ├── 201403-4.cpp │ │ ├── 201409-4.cpp │ │ ├── 201412-4.cpp │ │ ├── 201503-4.cpp │ │ ├── 201509-4.cpp │ │ ├── 201512-4.cpp │ │ ├── 201604-4.cpp │ │ ├── 201609-4.cpp │ │ ├── 201703-4.cpp │ │ ├── 201709-4.cpp │ │ ├── 201803-4-dfs.cpp │ │ ├── 201812-4-kruskal.cpp │ │ ├── 201812-4.cpp │ │ ├── 201909-3-opt1.cpp │ │ ├── 201909-3.cpp │ │ ├── mycalc.y │ │ └── test.cpp ├── CSP-Note │ ├── CSP历年第1题题解报告-2019 .md │ ├── CSP历年第2题题解报告-2019.md │ ├── CSP历年第3题题解报告-2019.md │ ├── CSP历年第4题题解报告-2019.md │ ├── CSP第3题总结.md │ ├── 技巧归纳.md │ └── 易错点.md └── README.md ├── README.md └── aoapc_uva ├── README.md ├── aoapc-code ├── ch03 │ ├── README.md │ ├── UVa10082.cpp │ ├── UVa10340-1.cpp │ ├── UVa10340-2.cpp │ ├── UVa10340.cpp │ ├── UVa11809.cpp │ ├── UVa1225.cpp │ ├── UVa1368.cpp │ ├── UVa1583.cpp │ ├── UVa1584.cpp │ ├── UVa1585.cpp │ ├── UVa1586.cpp │ ├── UVa1587.cpp │ ├── UVa1587_err.cpp │ ├── UVa1588.cpp │ ├── UVa202.cpp │ ├── UVa202_right.cpp │ ├── UVa227.cpp │ ├── UVa232.cpp │ ├── UVa272.cpp │ ├── UVa272_opt1.cpp │ ├── UVa340.cpp │ ├── UVa401.cpp │ ├── UVa455.cpp │ ├── data.txt │ ├── data2.txt │ ├── out.txt │ ├── outfc.txt │ ├── pdata.cpp │ ├── run.bat │ ├── run1587.bat │ └── test.cpp ├── ch04 │ ├── README.md │ ├── UVA12108.cpp │ ├── UVA12412.cpp │ ├── UVA12412fc.cpp │ ├── UVA12412fc2.cpp │ ├── UVA133.cpp │ ├── UVA1339.cpp │ ├── UVA1589.cpp │ ├── UVA1590.cpp │ ├── UVA1591-2.cpp │ ├── UVA1591.cpp │ ├── UVA201.cpp │ ├── UVA213.cpp │ ├── UVA220.cpp │ ├── UVA253.cpp │ ├── UVA489.cpp │ ├── UVA508.cpp │ ├── UVA509.cpp │ ├── UVA512-2.cpp │ ├── UVA512.cpp │ ├── UVA815.cpp │ └── test.cpp ├── ch05 │ ├── UVA101.cpp │ ├── UVA10391.cpp │ ├── UVA10474.cpp │ ├── UVA10763.cpp │ ├── UVA10815.cpp │ ├── UVA10935.cpp │ ├── UVA12096.cpp │ ├── UVA12100.cpp │ ├── UVA12504.cpp │ ├── UVA136.cpp │ ├── UVA1539.cpp │ ├── UVA156-2.cpp │ ├── UVA156.cpp │ ├── UVA1592.cpp │ ├── UVA1594.cpp │ ├── UVA1595.cpp │ ├── UVA1596.cpp │ ├── UVA1597.cpp │ ├── UVA221.cpp │ ├── UVA230.cpp │ ├── UVA400.cpp │ ├── UVA540.cpp │ ├── UVA814.cpp │ ├── acsdn.txt │ ├── bcsdn │ ├── data.txt │ ├── out.txt │ ├── run.bat │ └── test.cpp └── ch06 │ ├── UVA10129-opt.cpp │ ├── UVA10129.cpp │ ├── UVA10129fc.cpp │ ├── UVA10305.cpp │ ├── UVA10562-opt.cpp │ ├── UVA10562.cpp │ ├── UVA1103-2.cpp │ ├── UVA1103.cpp │ ├── UVA11853.cpp │ ├── UVA11988.cpp │ ├── UVA12171-fc.cpp │ ├── UVA12171.cpp │ ├── UVA122.cpp │ ├── UVA12657.cpp │ ├── UVA1527.cpp │ ├── UVA1527dfs.cpp │ ├── UVA1599.cpp │ ├── UVA210.cpp │ ├── UVA297.cpp │ ├── UVA422.cpp │ ├── UVA506.cpp │ ├── UVA514.cpp │ ├── UVA548.cpp │ ├── UVA572.cpp │ ├── UVA679-2.cpp │ ├── UVA679.cpp │ ├── UVA699.cpp │ ├── UVA816-fc.cpp │ ├── UVA816.cpp │ ├── UVA839-opt.cpp │ ├── UVA839.cpp │ ├── acsdn.txt │ ├── bcsdn │ ├── data │ └── test.cpp └── aoapc-note ├── ch03.md ├── ch04.md ├── ch05.md ├── ch06-例题.md ├── csdn题解目录.md └── 错题集.docx /AlgorithmNote/AlgorithmNote-Code/第10章 图算法专题/A1013.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-08-14 10:58:24 4 | * @LastEditTime: 2019-08-14 11:51:40 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | const int maxn = 1010; 10 | vector Adj[maxn]; // 邻接表,从1开始 11 | bool vis[maxn] = {false}; // 标记结点是否被访问 12 | int N; // 结点个数 13 | void dfs(int v) { 14 | vis[v] = true; 15 | for(auto p : Adj[v]) { 16 | if(!vis[p]) dfs(p); 17 | } 18 | } 19 | int dfsTrave(int delv) { 20 | int cnt = 0; 21 | // fill(vis, vis + N + 1, false); // 初始化,下标从1开始存!!! 22 | fill(vis, vis + maxn, false); // 初始化,下标从1开始存!!! 23 | vis[delv] = true; // 删除delv点 24 | for(int v = 1; v <= N; v ++) { // 遍历所有结点 25 | if(!vis[v]) { 26 | cnt ++; // 无向图连通块个数 27 | dfs(v); 28 | } 29 | } 30 | return cnt; 31 | } 32 | void readData() { 33 | int m, k; 34 | scanf("%d %d %d", &N, &m, &k); 35 | int a, b; 36 | for(int i = 0; i < m; i ++) { 37 | scanf("%d %d", &a, &b); 38 | Adj[a].push_back(b); 39 | Adj[b].push_back(a); 40 | } 41 | int v; 42 | for(int i = 0; i < k; i ++) { 43 | scanf("%d", &v); 44 | printf("%d\n", dfsTrave(v) - 1); 45 | } 46 | } 47 | int main() { 48 | readData(); 49 | return 0; 50 | } -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第11章 动态规划专题/A1007.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-08-23 11:02:37 4 | * @LastEditTime: 2019-08-23 11:22:54 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | const int maxn = 10010; 10 | int a[maxn], start[maxn], dp[maxn]; // 输入序列、以i为结尾的最大序列和的起点、以i为结尾的最大序列和 11 | int main() { 12 | int K; 13 | scanf("%d", &K); 14 | int negNum = 0; // 负数个数 15 | for(int i = 0; i < K; i ++) { 16 | scanf("%d", &a[i]); 17 | if(a[i] < 0) negNum ++; 18 | } 19 | if(negNum == K) { 20 | printf("%d %d %d\n", 0, a[0], a[K - 1]); 21 | } 22 | else { 23 | // 边界初始化 24 | dp[0] = a[0]; 25 | start[0] = 0; 26 | // K-1次迭代 27 | for(int i = 1; i < K; i ++) { 28 | if(dp[i-1] + a[i] >= a[i]) { // 包括0 29 | dp[i] = dp[i-1] + a[i]; 30 | start[i] = start[i-1]; 31 | } 32 | else { 33 | dp[i] = a[i]; 34 | start[i] = i; 35 | } 36 | } 37 | // 找出最大值 38 | int MAX = -0x3fffffff, idx; 39 | for(int i = 0; i < K; i ++) { 40 | if(MAX < dp[i]) { 41 | MAX = dp[i]; 42 | idx = i; 43 | } 44 | } 45 | printf("%d %d %d\n", dp[idx], a[start[idx]], a[idx]); 46 | } 47 | return 0; 48 | } -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第11章 动态规划专题/A1040.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-08-23 19:51:08 4 | * @LastEditTime: 2019-08-23 20:17:32 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | const int maxn = 1010; 10 | int dp[maxn][maxn] = {0}; 11 | int main() { 12 | string s; 13 | getline(cin, s); 14 | // 初始化,长度为1,2的子串 15 | int ans = 1; 16 | for(int i = 0; i < s.size(); i ++) { 17 | dp[i][i] = 1; // 长度为1 18 | if(i < s.size() - 1 && s[i] == s[i + 1]) { 19 | dp[i][i + 1] = 2; // 长度为2 20 | ans = 2; // 选最大值 21 | } 22 | } 23 | // 长度3~N的子串 24 | for(int i = 3; i <= s.size(); i ++) { 25 | for(int j = 0; j < s.size() - i + 1; j ++) { // 起点 26 | int k = j + i - 1; // 终点 27 | if(s[j] == s[k]) { 28 | if(dp[j + 1][k - 1] == 0) continue; // 内部子串为非回文,直接跳过 29 | dp[j][k] = dp[j + 1][k - 1] + 2; // 回文相加,非回文为0 30 | ans = max(ans, dp[j][k]); // 选最大 31 | } 32 | } 33 | } 34 | printf("%d\n", ans); 35 | return 0; 36 | } -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第11章 动态规划专题/A1045-LCS.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-08-23 15:46:51 4 | * @LastEditTime: 2019-08-23 16:02:08 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | const int maxc = 210, maxn = 10010; 10 | int a[maxc], b[maxn], dp[maxc][maxn]; 11 | int main() { 12 | int N, M, L; 13 | scanf("%d %d", &N, &M); 14 | for(int i = 1; i <= M; i ++) scanf("%d", &a[i]); 15 | scanf("%d", &L); 16 | for(int i = 1; i <= L; i ++) scanf("%d", &b[i]); 17 | // 初始化 18 | for(int i = 1; i <= M; i ++) dp[i][0] = 0; 19 | for(int j = 1; j <= L; j ++) dp[0][j] = 0; 20 | for(int i = 1; i <= M; i ++) { 21 | for(int j = 1; j <= L; j ++) { 22 | int MAX = max(dp[i-1][j], dp[i][j-1]); 23 | if(a[i] == b[j]) dp[i][j] = MAX + 1; 24 | else dp[i][j] = MAX; 25 | } 26 | } 27 | printf("%d\n", dp[M][L]); 28 | return 0; 29 | } -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第11章 动态规划专题/A1045.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-08-23 14:38:21 4 | * @LastEditTime: 2019-08-23 15:20:21 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | const int maxn = 10010, INF = 0x7fffffff; 10 | int order[maxn], pos[maxn], a[maxn], dp[maxn]; // 输入期望序列、期望序列对应的下标、输入的颜色序列、以a[i]为结尾的最大序列长度 11 | int main() { 12 | int N, M, L; 13 | scanf("%d %d", &N, &M); 14 | fill(pos, pos + maxn, INF); // 不存在的为无穷大 15 | int t; 16 | for(int i = 1; i <= M; i ++) { 17 | scanf("%d", &order[i]); 18 | pos[order[i]] = i; // 值- >位置 19 | } 20 | scanf("%d", &L); 21 | for(int i = 1; i <= L; i ++) { 22 | scanf("%d", &a[i]); 23 | } 24 | // 动规 25 | for(int i = 1; i <= L; i ++) { 26 | dp[i] = 1; // 初始值 27 | if(pos[a[i]] == INF) continue; // 不存在就不考虑 28 | for(int j = 1; j < i; j ++) { // 选最大值 29 | if(pos[a[j]] <= pos[a[i]] && (dp[i] < dp[j] + 1)) dp[i] = dp[j] + 1; 30 | } 31 | } 32 | // 找最长 33 | int MAX = -1; 34 | for(int i = 1; i <= L; i ++) { 35 | if(dp[i] > MAX) MAX = dp[i]; 36 | } 37 | printf("%d\n", MAX); 38 | return 0; 39 | } -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第11章 动态规划专题/A1068-dp.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-08-24 00:11:31 4 | * @LastEditTime: 2019-08-24 00:32:50 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | const int maxn = 10010, maxv = 110; 10 | int dp[maxn] = {0}, choice[maxn][maxv], flag[maxn] = {false}; 11 | int a[maxn] = {0}; 12 | int main() { 13 | int N, M; 14 | scanf("%d %d", &N, &M); 15 | for(int i = 0; i < N; i ++) scanf("%d", &a[i]); 16 | sort(a, a + maxn, [](int a, int b){return a > b;}); // 降序,便于选择字典序最小 17 | for(int i = 0; i < N; i ++) { // N个物品 18 | for(int v = M; v >= a[i]; v --) { // 滚动数组优化,逆向枚举 19 | if(dp[v] <= dp[v - a[i]] + a[i]) { //选,相等也选,字典序小 20 | dp[v] = dp[v - a[i]] + a[i]; 21 | choice[i][v] = 1; 22 | } 23 | else choice[i][v] = 0; 24 | } 25 | } 26 | if(dp[M] != M) printf("No Solution\n"); 27 | else { 28 | // 找出路径 29 | int k = N - 1, num = 0, v = M; 30 | while(k >= 0) { 31 | if(choice[k][v] == 1) { 32 | flag[k] = true; 33 | num ++; 34 | v -= a[k]; 35 | } 36 | k --; 37 | } 38 | // 输出 39 | for(int i = N - 1; i >= 0; i --) { 40 | if(flag[i]) printf("%d%s", a[i], (--num) == 0 ? "\n" : " "); 41 | } 42 | } 43 | return 0; 44 | } -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第11章 动态规划专题/A1068.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-08-23 21:08:07 4 | * @LastEditTime: 2019-08-23 23:12:31 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | const int maxn = 10010; 10 | int a[maxn] = {0}, N, M; 11 | vector tmp, ans; 12 | void dfs(int idx, int sum) { 13 | if(sum == M) { // 满足条件 14 | ans = tmp; 15 | return; 16 | } 17 | if(idx == N || sum > M || !ans.empty()) return; // 边界+剪枝,找到第一个解就退出 18 | tmp.push_back(idx); 19 | dfs(idx + 1, sum + a[idx]); // 选 20 | tmp.pop_back(); 21 | dfs(idx + 1, sum); // 不选 22 | } 23 | int main() { 24 | scanf("%d %d", &N, &M); 25 | for(int i = 0; i < N; i ++) scanf("%d", &a[i]); 26 | sort(a, a + N); 27 | dfs(0, 0); 28 | if(ans.empty()) printf("No Solution\n"); 29 | else { 30 | for(int i = 0; i < ans.size(); i ++) { 31 | printf("%d%s", a[ans[i]], i == ans.size() - 1 ? "\n" : " "); 32 | } 33 | } 34 | return 0; 35 | } -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第3章 入门模拟/图形输出/A1031.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int main() { 4 | string s; 5 | cin >>s; 6 | int N, n1 = -1, n2; //字符串总长,纵向行数, 横向行数 7 | N = s.length(); 8 | // 计算出满足条件的n1,n2 9 | for(int i = 3; i < N; i++) { 10 | for(int j = i; j >= 0; j--) { 11 | if(i + 2 * j -2 == N) { 12 | if(n1 < j) { 13 | n1 = j; 14 | n2 = i; 15 | } 16 | } 17 | } 18 | } 19 | for(int i = 0; i < n1; i++) { //n1 rows 20 | for(int j = 0; j < n2; j++) { //n2 columns 21 | if(i != n1 - 1) { //last row 22 | if(j == 0) cout < 2 | int main() { 3 | int N, n; //总个数, 倒三角层数 4 | char ch; 5 | scanf("%d %c", &N, &ch); 6 | for(int i = 1; i <= 1001; i++) { //计算层数 7 | n = i - 1; 8 | if(2 * i * i - 1 > N) break; //总个数:2*n*n - 1,(n为倒三角的层数) 9 | } 10 | for(int i = n; i >= 1; i--) { //倒三角:第n -> 1层 11 | for(int j = 0; j < n + i - 1; j++) { //右侧多余空格输出会格式错误 12 | if(j >= n - i && j < n + i - 1) printf("%c", ch); //中间部分 13 | else printf(" "); 14 | } 15 | printf("\n"); 16 | } 17 | for(int i = 2; i <= n; i++) { //正三角: 第2 -> n层 18 | for(int j = 0; j < n + i - 1; j++) { 19 | if(j >= n - i && j < n + i - 1) printf("%c", ch); 20 | else printf(" "); 21 | } 22 | printf("\n"); 23 | } 24 | printf("%d", N - 2 * n * n + 1); //剩余个数 25 | return 0; 26 | } -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第3章 入门模拟/图形输出/B1306.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int main() { 4 | int col, rank; //column, rank 5 | char ch; //input's character 6 | scanf("%d %c", &col, &ch); 7 | rank = (int)((float)col / 2 + 0.5); //四舍五入 8 | for(int i = 0; i < rank; i++) { 9 | for(int j = 0; j < col; j++) { 10 | if(i == 0 || i == rank - 1) printf("%c", ch); //头尾两行 11 | else {//中间 12 | if(j == 0 || j == col - 1) printf("%c", ch); //头尾两列 13 | else printf(" "); 14 | } 15 | } 16 | printf("\n"); 17 | } 18 | return 0; 19 | } -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第3章 入门模拟/字符串处理/A1001.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int main() { 4 | int a, b; 5 | cin >>a >>b; 6 | int sum = a + b; 7 | int sign = 0; 8 | if(sum < 0) { 9 | sign = 1;//1表示负数 10 | sum = -sum;//取绝对值 11 | } 12 | else if(sum == 0) { //0特例单独判断 13 | cout <<0; 14 | return 0; 15 | } 16 | // 从低位到高位依次入栈,若3*i + 1位存在,将逗号入栈,如第4位存在,才先将逗号入栈,在将数字入栈 17 | stack s; //字符存储,便于输出 18 | int cnt = 0; 19 | while(sum != 0) { 20 | if(cnt != 0 && cnt % 3 == 0) { //关键 21 | s.push(','); 22 | } 23 | s.push((sum % 10) + '0'); //数字 -> 字符 24 | cnt ++; 25 | sum /= 10; 26 | } 27 | // 输出 28 | if(sign == 1) cout <<'-'; 29 | while(!s.empty()) { 30 | cout < 2 | using namespace std; 3 | int main() { 4 | string s1; 5 | cin >>s1; 6 | int sum = 0; 7 | // 计算总和 8 | for(int i = 0; i < s1.length(); i++) { 9 | sum += (s1[i] - '0'); 10 | } 11 | // 提取每一位,栈保存,便于输出;do...while无需考虑特例0 12 | stack s; 13 | do { 14 | s.push(sum % 10); 15 | sum /= 10; 16 | }while(sum != 0); 17 | // 输出,转换数组简化代码;输出末尾无需多余空格 18 | string change[10] = {"zero","one","two","three","four","five","six","seven","eight","nine"}; 19 | int len = s.size(); 20 | for(int i = 0; i < len - 1; i++) { 21 | cout < 2 | using namespace std; 3 | int main() { 4 | string s[1000], res; 5 | int N; 6 | cin >>N; 7 | getchar(); //读取一行必须先用它吸收换行 8 | for(int i = 0; i < N; i++) { 9 | getline(cin, s[i]); 10 | } 11 | res = s[0];//初始化为第一句 12 | // 两两取最长公共后缀 13 | for(int i = 1; i < N; i++) { 14 | int index = -1, lres = 0;//公共的后缀下标,长度 15 | int len = min(res.size(), s[i].size()); 16 | for(int j = 0; j < len; j++) { 17 | if(res[res.size() - j - 1] == s[i][s[i].size() - j - 1]) { 18 | index = res.size() - j - 1; 19 | lres ++; 20 | } 21 | else break;//一个不满足,立刻退出 22 | } 23 | if(lres == 0) {//0个相等,必定无公共后缀 24 | cout <<"nai"; 25 | return 0; 26 | } 27 | else { 28 | res = res.substr(index, lres); 29 | } 30 | } 31 | cout < 2 | using namespace std; 3 | int main() { 4 | string py[10] = {"ling", "yi", "er", "san", "si", "wu", "liu", "qi", "ba", "jiu"}; 5 | string s; 6 | cin >>s; 7 | int sum = 0; 8 | // 计算个位数字总和 9 | for(int i = 0; i < s.size(); i++) { 10 | sum += s[i] - '0'; 11 | } 12 | // 低位到高位依次入栈 13 | stack ans; 14 | do { 15 | ans.push(sum % 10); 16 | sum /= 10; 17 | }while(sum != 0); 18 | // 输出:末尾无需多余空格 19 | int cnt = ans.size(); 20 | for(int i = 0; i < cnt - 1; i++) { 21 | cout < 2 | using namespace std; 3 | int main() { 4 | int n; 5 | cin >>n; 6 | int radix[3]; //存放个十百位数字 7 | for(int i = 0; i < 3; i++) { //计算个十百位数字 8 | radix[i] = n % 10; 9 | n /= 10; 10 | } 11 | // 输出:输出个数和相应位数上的数字一样 12 | for(int i = 2; i >= 0; i--) { 13 | for(int j = 0; j < radix[i]; j++) { 14 | if(i == 2) cout <<'B'; 15 | else if(i == 1) cout <<'S'; 16 | else cout < 2 | using namespace std; 3 | int mian() { 4 | int n; 5 | cin >>n; 6 | // int b, s, g; 7 | int radix[3]; 8 | for(int i = 0; i < 3; i++) { 9 | radix[i] = n % 10; 10 | n /= 10; 11 | } 12 | for(int i = 2; i >= 0; i--) { 13 | for(int j = 0; j < radix[i]; j++) { 14 | if(i == 2) cout <<'B'; 15 | else if(i == 1) cout <<'S'; 16 | else cout < 2 | using namespace std; 3 | int main() { 4 | string tmp; 5 | stack s; 6 | getline(cin, tmp);//键盘读入 7 | stringstream input(tmp);//stringstream构造函数 8 | //分割,第三个参数为char型 9 | while(getline(input, tmp, ' ')) { 10 | s.push(tmp); 11 | } 12 | // 输出 13 | int len = s.size(); 14 | for(int i = 0; i < len - 1; i++) { 15 | cout < 2 | using namespace std; 3 | int main() { 4 | string s; 5 | cin >>s; 6 | // cout< 2 | using namespace std; 3 | int main() { 4 | int weight[17] = {7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2}; 5 | char check_code[11] = {'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'}; 6 | int n; 7 | cin >>n; 8 | bool isAllPassed = true; 9 | for(int i = 0; i < n; i++) { 10 | string s; 11 | cin >>s; 12 | int sum = 0; 13 | bool flag = true; 14 | for(int i = 0; i < 17; i++) { 15 | if(s[i] >= '0' && s[i] <= '9') {//前17位全为数字 16 | sum += (s[i] - '0') * weight[i]; //计算权重 17 | } 18 | else { 19 | flag = false; 20 | isAllPassed = false; 21 | break; 22 | } 23 | } 24 | if(flag) { 25 | if(check_code[sum % 11] != s[17]) {//校验位失效 26 | cout < 2 | using namespace std; 3 | int main() { 4 | int n; 5 | cin >>n; 6 | string sit_name, sot_name; //开门、关门名字 7 | string sit = "24:59:59", sot = "00:00:00"; //开门、关门时间 8 | string tname, tit, tot; //从键盘读入 9 | for(int i = 0; i < n; i++) { 10 | cin >>tname >>tit >>tot; 11 | if(sit >= tit) { //最小 12 | sit = tit; 13 | sit_name = tname; 14 | } 15 | if(sot <= tot) { //最大 16 | sot = tot; 17 | sot_name = tname; 18 | } 19 | } 20 | cout < 2 | using namespace std; 3 | int main() { 4 | int res[3] = {-1}; 5 | char name[3] = {'W', 'T', 'L'}; 6 | double tmax, tmp, ans = 1.0; 7 | for(int i = 0; i < 3; i++) {//3组数据 8 | tmax = -1; 9 | for(int j = 0; j < 3; j++) {//选最大 10 | scanf("%lf", &tmp); 11 | if(tmp > tmax) { 12 | tmax = tmp; 13 | res[i] = j;//下标记录,表示W,T,L 14 | } 15 | } 16 | ans *= tmax; 17 | } 18 | ans = (ans * 0.65 - 1) * 2;//最大利润计算公式 19 | // ans = (double)((int)(ans * 100 + 0.5)) / 100;//四舍五入,保留2位小数 20 | for(int i = 0; i < 3; i++) { 21 | printf("%c ", name[res[i]]); 22 | } 23 | printf("%.2lf", ans);//四舍五入,保留2位小数 24 | return 0; 25 | } -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第3章 入门模拟/查找元素/A1036.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int main() { 4 | int n; 5 | cin >>n; 6 | string fname, mname; //female|man's name 7 | string fid, mid; //id 8 | int fgrade = -1, mgrade = 110; //grade 9 | string tname, tgender, tid; 10 | int tgrade; 11 | for(int i = 0; i < n; i++) { 12 | cin >>tname >>tgender >>tid >>tgrade; 13 | if(tgender == "F") { 14 | if(fgrade < tgrade) { 15 | fgrade = tgrade; 16 | fname = tname; 17 | fid = tid; 18 | } 19 | } 20 | else if(tgender == "M") { 21 | if(mgrade > tgrade) { 22 | mgrade = tgrade; 23 | mname = tname; 24 | mid = tid; 25 | } 26 | } 27 | } 28 | if(fgrade == -1) cout <<"Absent" < 2 | using namespace std; 3 | typedef struct { 4 | string name; 5 | string id; 6 | int score; 7 | }student; 8 | bool cmp(student s1, student s2) {//降序排列 9 | if(s1.score > s2.score) return true; 10 | else return false; 11 | } 12 | int main() { 13 | int n; 14 | cin >>n; 15 | student res[n]; 16 | for(int i = 0; i < n; i++) { 17 | cin >>res[i].name >>res[i].id >> res[i].score; 18 | } 19 | sort(res, res + n, cmp); 20 | cout < 2 | using namespace std; 3 | typedef struct { 4 | string name; 5 | int yy, mm, dd; 6 | }Birth; 7 | //比较大小 8 | bool Less(Birth b1, Birth b2) { 9 | bool flag = false; 10 | if(b1.yy < b2.yy) flag = true; 11 | else if(b1.yy > b2.yy) flag = false; 12 | else { 13 | if(b1.mm < b2.mm) flag = true; 14 | else if(b1.mm > b2.mm) flag = false; 15 | else { 16 | if(b1.dd < b2.dd) flag = true; 17 | else if(b1.dd > b2.dd) flag = false; 18 | else flag = true;//最年长和最小不同,相等返回true 19 | } 20 | } 21 | return flag; 22 | } 23 | //判断是否合法 24 | bool isLegal(Birth b) { 25 | Birth bmin = {"", 1814, 9, 6}, bmax = {"", 2014, 9, 6};//起止范围 26 | if(Less(bmin, b) && Less(b, bmax)) return true; 27 | else return false; 28 | } 29 | int main() { 30 | int n; 31 | scanf("%d", &n); 32 | Birth tBirth, bmin = {"", 2014, 9, 6}, bmax = {"", 1814, 9, 6};//出生时间数字最大和最小,对应年龄最小和最大 33 | int cnt = 0; 34 | for(int i = 0; i < n; i++) { 35 | cin >>tBirth.name;//string只能用cin、cout 36 | scanf("%d/%d/%d", &tBirth.yy, &tBirth.mm, &tBirth.dd);//分隔符[/] 37 | if(isLegal(tBirth)) { 38 | cnt++; 39 | if(Less(tBirth, bmin)) bmin = tBirth; 40 | if(Less(bmax, tBirth)) bmax = tBirth; 41 | } 42 | } 43 | cout <= lower and idate <= upper: 13 | cnt += 1 14 | if idate < bmin: 15 | older = name 16 | bmin = idate 17 | if idate > bmax: 18 | young = name 19 | bmax = idate 20 | print(cnt, end='')#不换行 21 | if cnt != 0: 22 | print(" "+older+" "+young)#,会自动输出一个空格 23 | -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第3章 入门模拟/查找元素/B1032.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int main() { 4 | long long res[200000] = {0}; //别开太大 5 | int n; 6 | cin >>n; 7 | long long a, b; 8 | for(int i = 0; i < n; i++) { 9 | cin >>a >>b; 10 | res[a] += b; 11 | } 12 | long long maxa, maxb; 13 | maxa = maxb = -1; 14 | for(int i = 0; i < 200000; i++) { 15 | if(res[i] > maxb) { 16 | maxa = i; 17 | maxb = res[i]; 18 | } 19 | } 20 | cout < 2 | #include 3 | #include 4 | #include 5 | using namespace std; 6 | int main() { 7 | int n,m; 8 | cin >> n; 9 | map mp; 10 | string s, c; 11 | int a; 12 | for(int i = 0; i < n; i++) { 13 | cin >>s >>a >>c; 14 | s = s + " " + c; 15 | mp[a] = s; 16 | } 17 | cin >> m; 18 | for(int i = 0; i < m; i++) { 19 | cin >> a; 20 | cout < 2 | int main() { 3 | int n1; 4 | scanf("%d", &n1); 5 | double res[3000] = {0}, ploy1[3000] = {0}, coff;//结果;系数 6 | int exp;//幂 7 | for(int i = 0; i < n1; i++) {//多项式1读入保存于ploy1 8 | scanf("%d %lf", &exp, &coff); 9 | ploy1[exp] = coff; 10 | } 11 | int n2; 12 | scanf("%d", &n2); 13 | for(int i = 0; i < n2; i++) {//对于多项式2中的每一项,乘以1中的每一项 14 | scanf("%d %lf", &exp, &coff); 15 | for(int j = 0; j < 2001; j++) {//N<=1000,乘法运算相等于幂加法,所以N' <= 2000 16 | if(ploy1[j] != 0) { 17 | res[exp + j] += coff * ploy1[j];//幂相加,系数相乘 18 | } 19 | } 20 | } 21 | 22 | int cnt = 0;//最保险的计算非零项数 23 | for(int i = 0; i < 2001; i++) { 24 | if(res[i] != 0)cnt++; 25 | } 26 | printf("%d", cnt);//可能全部抵消 27 | for(int i = 2001; i >= 0; i--) {//幂次逆序输出 28 | if(res[i] != 0) printf(" %d %.1lf", i, res[i]); 29 | } 30 | return 0; 31 | } -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第3章 入门模拟/简单模拟/A1042.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wyjoutstanding/Algorithm/4d5c99f5a91d4a8dfcededa9d2da4b375080fb4e/AlgorithmNote/AlgorithmNote-Code/第3章 入门模拟/简单模拟/A1042.cpp -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第3章 入门模拟/简单模拟/A1046-2.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wyjoutstanding/Algorithm/4d5c99f5a91d4a8dfcededa9d2da4b375080fb4e/AlgorithmNote/AlgorithmNote-Code/第3章 入门模拟/简单模拟/A1046-2.cpp -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第3章 入门模拟/简单模拟/A1046.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wyjoutstanding/Algorithm/4d5c99f5a91d4a8dfcededa9d2da4b375080fb4e/AlgorithmNote/AlgorithmNote-Code/第3章 入门模拟/简单模拟/A1046.cpp -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第3章 入门模拟/简单模拟/A1065.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wyjoutstanding/Algorithm/4d5c99f5a91d4a8dfcededa9d2da4b375080fb4e/AlgorithmNote/AlgorithmNote-Code/第3章 入门模拟/简单模拟/A1065.cpp -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第3章 入门模拟/简单模拟/B1001害死人不偿命的(3n+1)猜想.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | int main() { 3 | int n, cnt = 0; 4 | scanf("%d",&n); 5 | while(n > 1) { 6 | cnt++; 7 | if(n % 2 == 0) n /= 2; 8 | else n = (3*n + 1) / 2; 9 | } 10 | printf("%d", cnt); 11 | return 0; 12 | } 13 | -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第3章 入门模拟/简单模拟/B1008-2.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wyjoutstanding/Algorithm/4d5c99f5a91d4a8dfcededa9d2da4b375080fb4e/AlgorithmNote/AlgorithmNote-Code/第3章 入门模拟/简单模拟/B1008-2.cpp -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第3章 入门模拟/简单模拟/B1008-3.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wyjoutstanding/Algorithm/4d5c99f5a91d4a8dfcededa9d2da4b375080fb4e/AlgorithmNote/AlgorithmNote-Code/第3章 入门模拟/简单模拟/B1008-3.cpp -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第3章 入门模拟/简单模拟/B1008-4.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wyjoutstanding/Algorithm/4d5c99f5a91d4a8dfcededa9d2da4b375080fb4e/AlgorithmNote/AlgorithmNote-Code/第3章 入门模拟/简单模拟/B1008-4.cpp -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第3章 入门模拟/简单模拟/B1010.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wyjoutstanding/Algorithm/4d5c99f5a91d4a8dfcededa9d2da4b375080fb4e/AlgorithmNote/AlgorithmNote-Code/第3章 入门模拟/简单模拟/B1010.cpp -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第3章 入门模拟/简单模拟/B1011.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wyjoutstanding/Algorithm/4d5c99f5a91d4a8dfcededa9d2da4b375080fb4e/AlgorithmNote/AlgorithmNote-Code/第3章 入门模拟/简单模拟/B1011.cpp -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第3章 入门模拟/简单模拟/B1012.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wyjoutstanding/Algorithm/4d5c99f5a91d4a8dfcededa9d2da4b375080fb4e/AlgorithmNote/AlgorithmNote-Code/第3章 入门模拟/简单模拟/B1012.cpp -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第3章 入门模拟/简单模拟/B1016.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wyjoutstanding/Algorithm/4d5c99f5a91d4a8dfcededa9d2da4b375080fb4e/AlgorithmNote/AlgorithmNote-Code/第3章 入门模拟/简单模拟/B1016.cpp -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第3章 入门模拟/简单模拟/B1018.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wyjoutstanding/Algorithm/4d5c99f5a91d4a8dfcededa9d2da4b375080fb4e/AlgorithmNote/AlgorithmNote-Code/第3章 入门模拟/简单模拟/B1018.cpp -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第3章 入门模拟/进制转换/A1019.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int main() { 4 | int N, b; 5 | cin >>N >>b; 6 | stack s, ans; 7 | queue q; 8 | // 除基取余法:栈和队列保存 9 | do { 10 | int t = N % b; 11 | s.push(t); 12 | q.push(t); 13 | N /= b; 14 | }while(N != 0); 15 | // 回文判断:栈和队列对比 16 | bool flag = true; 17 | ans = s; 18 | while(!s.empty()) { 19 | if(s.top() != q.front()) { 20 | flag = false; 21 | break; 22 | } 23 | s.pop(); 24 | q.pop(); 25 | } 26 | // 输出 27 | if(flag) cout <<"Yes" < 2 | using namespace std; 3 | int main() { 4 | int rgb[3]; //表示r,g,b 5 | cin >>rgb[0] >>rgb[1] >>rgb[2]; 6 | char tag[14] = {'0','1','2','3','4','5','6','7','8','9','A','B','C'}; //统一输出 7 | cout <<"#"; 8 | // 遍历r,g,b 9 | for(int i = 0; i < 3; i++) { 10 | stack s; 11 | // 进制转换 12 | do { 13 | s.push(rgb[i] % 13); 14 | rgb[i] /= 13; 15 | }while(rgb[i] != 0); 16 | // 输出:仅有1位补0 17 | if(s.size() == 1) s.push(0);//补0 18 | while(!s.empty()) { 19 | cout < 2 | using namespace std; 3 | struct money { 4 | int g, s, k; //无需考虑溢出 5 | }a, b, res; 6 | int main() { 7 | scanf("%d.%d.%d", &a.g, &a.s, &a.k); 8 | scanf("%d.%d.%d", &b.g, &b.s, &b.k); 9 | int carry; //进位 10 | res.k = (a.k + b.k) % 29; 11 | carry = (a.k + b.k) / 29; 12 | res.s = (a.s + b.s + carry) % 17; 13 | carry = (a.s + b.s + carry) / 17; 14 | res.g = (a.g + b.g + carry); 15 | printf("%d.%d.%d", res.g, res.s, res.k); 16 | return 0; 17 | } -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第3章 入门模拟/进制转换/A1058.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | struct money { 4 | long long g, s, k; //int会溢出 5 | }a, b, res; 6 | int main() { 7 | scanf("%lld.%lld.%lld", &a.g, &a.s, &a.k); 8 | scanf("%lld.%lld.%lld", &b.g, &b.s, &b.k); 9 | // 换算为最小单位 10 | long long sum; //数据范围 11 | sum = a.g * 17 * 29 + a.s * 29 + a.k; 12 | sum += b.g * 17 * 29 + b.s * 29 + b.k; 13 | // 转换为要求格式 14 | res.k = sum % 29; 15 | sum /= 29; 16 | res.s = sum % 17; 17 | sum /= 17; 18 | res.g = sum; 19 | printf("%lld.%lld.%lld", res.g, res.s, res.k); 20 | return 0; 21 | } -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第3章 入门模拟/进制转换/B1022.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int main() { 4 | int a, b, d, n; 5 | cin >>a >>b >>d; 6 | n = a + b; 7 | if(n == 0) cout <<0; //0直接输出 8 | else { //非零用除基取余法,借用栈结构保存余数 9 | stack res; 10 | while(n != 0) { 11 | res.push(n % d); 12 | n /= d; 13 | } 14 | while(!res.empty()) { //输出 15 | cout < 2 | struct Price { 3 | int g, s, k; 4 | }a, b, ans; 5 | // a<=b:return true 6 | bool isGrater(Price a, Price b) { 7 | if(a.g != b.g) return a.g <= b.g; 8 | if(a.k != b.k) return a.k <= b.k; 9 | else return a.s <= b.s; 10 | } 11 | int main() { 12 | scanf("%d.%d.%d", &a.g, &a.k, &a.s); 13 | scanf("%d.%d.%d", &b.g, &b.k, &b.s); 14 | int sign = 1; 15 | if(!isGrater(a,b)) { //计算正负,保证a <= b 16 | Price t; 17 | t = a; 18 | a = b; 19 | b = t; 20 | sign = -1; 21 | } 22 | if(b.s < a.s) { //s借位 23 | ans.s = b.s - a.s + 29; 24 | b.k -= 1; 25 | } 26 | else ans.s = b.s - a.s; 27 | 28 | if(b.k < a.k) { //k借位 29 | ans.k = b.k - a.k + 17; 30 | b.g -= 1; 31 | } 32 | else ans.k = b.k - a.k; 33 | 34 | ans.g = sign * (b.g - a.g); 35 | printf("%d.%d.%d", ans.g, ans.k, ans.s); 36 | return 0; 37 | } -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第4章 算法初步/two pointer/A1029.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-08-03 19:58:27 4 | * @LastEditTime: 2019-08-03 21:51:28 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | int main() { 10 | int n1, n2; 11 | scanf("%d", &n1); 12 | vector a(n1); 13 | for(int i = 0; i < n1; i++) scanf("%d", &a[i]); 14 | scanf("%d", &n2); 15 | // 避免内存超限,第二个数组边读边计数 16 | int idx; //第idx个输出 17 | if((n1 + n2) % 2 == 0) idx = (n1 + n2 - 1) / 2; //偶数 18 | else idx = (n1 + n2) / 2; //奇数 19 | int t, j = 0, cnt = 0; 20 | for(int i = 0; i < n2; i++) { 21 | scanf("%d", &t); 22 | // a数组找到比t大的数 23 | while(j < n1 && a[j] < t) { 24 | // 满足条件立刻输出 25 | if(idx == cnt) { 26 | printf("%d", a[j]); 27 | return 0; 28 | } 29 | j ++; 30 | cnt ++; 31 | } 32 | // a遍历完或找到比t 大的数 33 | if(idx == cnt) { 34 | printf("%d", t); 35 | return 0; 36 | } 37 | cnt ++; 38 | } 39 | // 第二个数组遍历完依旧不到中位数 40 | while(j < n1) { 41 | if(idx == cnt) { 42 | printf("%d", a[j]); 43 | return 0; 44 | } 45 | cnt ++; 46 | j ++; 47 | } 48 | return 0; 49 | } -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第4章 算法初步/two pointer/A1030.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-08-03 11:20:30 4 | * @LastEditTime: 2019-08-03 11:26:33 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | typedef long long LL; 10 | int main() { 11 | LL N, p; 12 | scanf("%lld %lld", &N, &p); 13 | vector a(N); 14 | for(int i = 0; i < N; i++) scanf("%lld", &a[i]); 15 | sort(a.begin(), a.end()); // 从小到大排序 16 | // two pointer 17 | int cnt = 1, i = 0, j = 0; 18 | while(i < N && j < N) { 19 | while(j < N && a[j] <= p * a[i]) { 20 | cnt = max(cnt, j - i + 1); //最大间距 21 | j ++; 22 | } 23 | i ++; 24 | } 25 | printf("%d\n", cnt); 26 | return 0; 27 | } -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第4章 算法初步/two pointer/A1048.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-08-03 22:16:44 4 | * @LastEditTime: 2019-08-03 22:27:03 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | int main() { 10 | int n, m; 11 | scanf("%d %d", &n, &m); 12 | vector a(n); 13 | for(int i = 0; i < n; i++) scanf("%d", &a[i]); 14 | sort(a.begin(), a.end()); 15 | bool flag = false; 16 | int i = 0, j = n - 1; 17 | while(i < j) { 18 | if(a[i] + a[j] == m) { 19 | flag = true; 20 | printf("%d %d\n", a[i], a[j]); 21 | break; 22 | } 23 | else if(a[i] + a[j] < m) i++; 24 | else j--; 25 | } 26 | if(!flag) printf("No Solution\n"); 27 | return 0; 28 | } -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第4章 算法初步/二分/A1030-2.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-07-31 15:19:25 4 | * @LastEditTime: 2019-07-31 16:06:01 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | 8 | #include 9 | using namespace std; 10 | typedef long long LL; 11 | // [left, right]第一个大于val的下标 12 | // vector不使用&会超时 13 | int binarySearch(vector &a, int left, int right, LL val) { 14 | int mid; 15 | while(left < right) { 16 | mid = left + (right - left) / 2; 17 | if(a[mid] > val) right = mid; 18 | else left = mid + 1; 19 | } 20 | return left; 21 | } 22 | int main() { 23 | LL N, p; 24 | scanf("%lld %lld", &N, &p); 25 | vector res(N); 26 | for(int i = 0; i < N; i++) { 27 | scanf("%lld", &res[i]); 28 | } 29 | sort(res.begin(), res.end()); 30 | int ans = 0, last; 31 | for(int i = 0; i < N; i++) { 32 | last = binarySearch(res, i + 1, N, res[i] * p) - i; 33 | // last = upper_bound(res.begin() + i, res.end(), res[i] * p) - res.begin() - i; 34 | ans = max(ans, last); 35 | } 36 | printf("%d\n", ans); 37 | return 0; 38 | } -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第4章 算法初步/二分/A1044.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-08-02 22:29:28 4 | * @LastEditTime: 2019-08-02 23:07:20 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | int main() { 10 | int N, M; 11 | scanf("%d %d", &N, &M); 12 | int a[N+1], b[N+1] = {0}; 13 | a[0] = 0; 14 | // a[i] = a[1]+...+a[i] -> i-j = a[j] - a[i-1] 15 | for(int i = 1; i <= N; i++) { 16 | scanf("%d", &a[i]); 17 | a[i] += a[i-1]; 18 | } 19 | int minNum = 0x3fffffff; //存放间距超出M的最小值 20 | bool isPrint = false; //记录是否间距为M的i-j 21 | // 枚举N个a[i],查找第一个大于或等于a[i-1]+M的下标 22 | for(int i = 1; i <= N; i++) { 23 | int j = lower_bound(a + i, a + N + 1, a[i-1] + M) - a; 24 | if(a[i-1] + M == a[j]) { 25 | printf("%d-%d\n", i, j); 26 | isPrint = true; 27 | } 28 | else if(j != N + 1){ // =N+1表示为找到满足条件的数 29 | b[i] = j; 30 | if(minNum > a[j] - a[i-1]) minNum = a[j] - a[i - 1]; 31 | } 32 | } 33 | if(!isPrint) { 34 | for(int i = 1; i <= N; i++) { 35 | if(b[i] != 0 && a[b[i]] - a[i - 1] == minNum) printf("%d-%d\n", i, b[i]); 36 | } 37 | } 38 | return 0; 39 | } -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第4章 算法初步/二分/A1048.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-08-02 23:46:40 4 | * @LastEditTime: 2019-08-02 23:58:40 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | const int maxn = 100001; 10 | int a[maxn]; 11 | int binarySearch(int left, int right, int val) { 12 | int mid; 13 | while(left <= right) { 14 | mid = left + (right - left) / 2; 15 | if(a[mid] == val) return mid; 16 | else if(a[mid] < val) left = mid + 1; 17 | else right = mid - 1; 18 | } 19 | return -1; 20 | } 21 | int main() { 22 | int N, M; 23 | scanf("%d %d", &N, &M); 24 | for(int i = 0; i < N; i++) scanf("%d", &a[i]); 25 | sort(a, a + N); 26 | vector ans; 27 | for(int i = 0; i < N; i++) { 28 | int ret = binarySearch(0, N-1, M - a[i]); 29 | if(ret != -1 && ret != i) { 30 | ans.push_back(min(a[i], M - a[i])); 31 | } 32 | } 33 | if(ans.empty()) printf("No Solution\n"); 34 | else { 35 | sort(ans.begin(), ans.end()); 36 | printf("%d %d\n", ans[0], M - ans[0]); 37 | } 38 | return 0; 39 | } -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第4章 算法初步/二分/B1030.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-07-31 09:46:22 4 | * @LastEditTime: 2019-07-31 09:58:06 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | int main() { 10 | int N, p; 11 | scanf("%d %d", &N, &p); 12 | vector res(N); 13 | for(int i = 0; i < N; i++) { 14 | scanf("%d", &res[i]); 15 | } 16 | sort(res.begin(), res.end()); 17 | int left = 0, right = 0; 18 | for(int i = 0; i < N; i++) { 19 | if(res[N-1] <= p * res[i]) { 20 | left = N - i; 21 | break; 22 | } 23 | } 24 | for(int i = N - 1; i >= 0; i--) { 25 | if(res[i] <= p * res[0]) { 26 | right = i + 1; 27 | break; 28 | } 29 | } 30 | printf("%d\n", max(left, right)); 31 | return 0; 32 | } -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第4章 算法初步/其他高效技巧和算法/B1040.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-08-03 23:33:05 4 | * @LastEditTime: 2019-08-03 23:52:25 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | const int maxn = 100005; 10 | const int mod = 1000000007; 11 | int P[maxn] = {0}, T[maxn] = {0}; 12 | int main() { 13 | string s; 14 | cin >>s; 15 | int sum = 0; 16 | // 统计每个数左侧P个数 17 | for(int i = 0; i < s.size(); i++) { 18 | if(s[i] == 'P') P[i] ++; 19 | if(i != 0) P[i] += P[i-1]; 20 | } 21 | // 统计每个数右侧T个数 22 | for(int i = s.size() - 1; i >= 0; i--) { 23 | if(s[i] == 'T') T[i] ++; 24 | if(i != s.size() - 1) T[i] += T[i+1]; 25 | } 26 | // 累加每个A左右P*T的和值 27 | for(int i = 0; i < s.size(); i++) { 28 | if(s[i] == 'A') { 29 | sum += T[i] * P[i]; 30 | sum %= mod; //取模 31 | } 32 | } 33 | printf("%d\n", sum); 34 | return 0; 35 | } -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第4章 算法初步/其他高效技巧和算法/B1045.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-08-04 00:20:15 4 | * @LastEditTime: 2019-08-04 07:21:19 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | const int maxn = 100005, inf = 0x3fffffff; 10 | int leftMax[maxn], rightMin[maxn]; 11 | int main() { 12 | int n; 13 | scanf("%d", &n); 14 | int a[n]; 15 | for(int i = 0; i < n; i++) scanf("%d", &a[i]); 16 | // 找出每个元素左侧最大值 17 | leftMax[0] = -1; 18 | for(int i = 1; i < n; i++) { 19 | if(leftMax[i-1] < a[i-1]) leftMax[i] = a[i-1]; 20 | else leftMax[i] = leftMax[i-1]; 21 | } 22 | // 找出每个元素右侧最小值 23 | rightMin[n-1] = inf; 24 | for(int i = n - 2; i >= 0; i--) { 25 | if(rightMin[i+1] > a[i+1]) rightMin[i] = a[i+1]; 26 | else rightMin[i] = rightMin[i+1]; 27 | } 28 | // 存储符合条件的主元 29 | vector ans; 30 | for(int i = 0; i < n; i++) { 31 | if(a[i] > leftMax[i] && a[i] < rightMin[i]) ans.push_back(a[i]); 32 | } 33 | // 输出 34 | printf("%d\n", ans.size()); 35 | sort(ans.begin(), ans.end()); 36 | for(int i = 0; i < ans.size(); i++) { 37 | if(i == 0) printf("%d", ans[i]); 38 | else printf(" %d", ans[i]); 39 | } 40 | printf("\n"); //不能省略,否则报格式错 41 | return 0; 42 | } -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第4章 算法初步/排序/A1012.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | struct Rank{ 4 | string id; 5 | int score; 6 | }ranks[4][2001]; 7 | struct Info { 8 | char type; 9 | int order; 10 | }; 11 | map res; 12 | bool cmp1(Rank a, Rank b) { 13 | return 14 | } 15 | int main() { 16 | int N, M; 17 | cin >>N >>M; 18 | string id; 19 | int t, sum=0; 20 | Info info; 21 | for(int i = 0; i < N; i++) { 22 | cin >>id; 23 | res[id] = info; 24 | for(int j = 0; j < 4; j++) { 25 | ranks[j][i].id = id; 26 | if(j != 3) { 27 | cin >>t; 28 | sum += t; 29 | ranks[j][i].score = t; 30 | } 31 | else ranks[j][i].score = sum / 3; 32 | } 33 | } 34 | 35 | 36 | return 0; 37 | } -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第4章 算法初步/排序/A1028.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | struct Student { 4 | char info[3][10];//id, name, grade;用cin/cout会超时,所以不可以用string 5 | }student[100005]; 6 | int type;//当前选中的列,简化代码 7 | // 三个字段均用字符串来比较,便于编程 8 | bool cmp(Student a, Student b) { 9 | if(strcmp(a.info[type], b.info[type]) != 0) return strcmp(a.info[type], b.info[type]) < 0; 10 | else return strcmp(a.info[0], b.info[0]) < 0;//id 11 | } 12 | int main() { 13 | int N, C; 14 | cin >>N >>C; 15 | for(int i = 0; i < N; i++) { 16 | scanf("%s %s %s", &student[i].info[0], &student[i].info[1], &student[i].info[2]); 17 | } 18 | type = C - 1; 19 | sort(student, student + N, cmp); 20 | for(int i = 0; i < N; i++) { 21 | printf("%s %s %s\n", student[i].info[0], student[i].info[1], student[i].info[2]); 22 | } 23 | return 0; 24 | } -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第4章 算法初步/排序/A1083.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-07-26 16:14:32 4 | * @LastEditTime: 2019-07-26 16:50:03 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | struct Student { 10 | char name[12], id[12]; 11 | int grade; 12 | }; 13 | bool cmp(Student a, Student b) { 14 | return a.grade > b.grade;//没有相同分数 15 | } 16 | int main() { 17 | int N; 18 | scanf("%d", &N); 19 | Student res[N]; //存放学生记录 20 | for(int i = 0; i < N; i++) { 21 | scanf("%s %s %d", res[i].name, res[i].id, &res[i].grade); 22 | } 23 | // 按成绩降序排列 24 | sort(res, res + N, cmp); 25 | int gradeL, gradeR; 26 | scanf("%d %d", &gradeL, &gradeR); 27 | // 输出指定区间的信息 28 | int validNum = 0; 29 | for(int i = 0; i < N; i++) { 30 | if(res[i].grade <= gradeR) { 31 | if(res[i].grade >= gradeL) { 32 | printf("%s %s\n", res[i].name, res[i].id); 33 | validNum ++; 34 | } 35 | else break; 36 | } 37 | } 38 | if(validNum == 0) printf("NONE\n"); 39 | return 0; 40 | } -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第4章 算法初步/散列/A1041.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-07-28 14:54:15 4 | * @LastEditTime: 2019-07-28 15:05:55 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | struct Info { 10 | int cnt; //出现次数 11 | int times;//最后一次出现的序号 12 | }hashTable[10001]; 13 | int main() { 14 | int N; 15 | scanf("%d", &N); 16 | // 初始化 17 | for(int i = 0; i < 10001; i++) hashTable[i].cnt = 0; 18 | int t; 19 | // 读入N个数并统计每个数的出现次数 20 | for(int i = 0; i < N; i++) { 21 | scanf("%d", &t); 22 | hashTable[t].cnt ++; 23 | hashTable[t].times = i + 1; 24 | } 25 | // 选出出现次数为1且最早出现的 26 | int times = 999999, ans = -1; 27 | for(int i = 1; i < 10001; i++) { 28 | if(hashTable[i].cnt == 1 && times > hashTable[i].times) { 29 | ans = i; 30 | times = hashTable[i].times; 31 | } 32 | } 33 | // 输出 34 | if(ans == -1) printf("None\n"); 35 | else printf("%d\n", ans); 36 | return 0; 37 | } -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第4章 算法初步/散列/A1048.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-07-28 16:31:03 4 | * @LastEditTime: 2019-07-28 16:50:48 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | int main() { 10 | int N, M; 11 | scanf("%d %d", &N, &M); 12 | int a[N]; 13 | int hashTable[501] = {0}; 14 | // 读入N个数并统计出现次数 15 | for(int i = 0; i < N; i++) { 16 | scanf("%d", &a[i]); 17 | hashTable[a[i]] ++; 18 | } 19 | // 遍历每一种可能 20 | vector ans; 21 | for(int i = 0; i < N; i++) { 22 | // 排除两个相等的数,如7,7 23 | // if(M % a[i] == 0 && M / a[i] == 2) hashTable[a[i]] --; 24 | if(M - a[i] == a[i]) hashTable[a[i]] --; //更简单 25 | if(M >= a[i] && M - a[i] <= 500 && hashTable[M - a[i]] != 0) { 26 | hashTable[a[i]] --; //500特殊情况 27 | // 记录较小者 28 | if(M - a[i] < a[i]) ans.push_back(M - a[i]); 29 | else ans.push_back(a[i]); 30 | } 31 | } 32 | // 输出 33 | if(ans.empty()) printf("No Solution\n"); 34 | else { 35 | sort(ans.begin(), ans.end()); 36 | printf("%d %d\n", ans[0], M - ans[0]); //最小 37 | } 38 | return 0; 39 | } -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第4章 算法初步/散列/A1050.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-07-28 15:25:38 4 | * @LastEditTime: 2019-07-28 15:31:03 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | const int maxn = 128; 10 | int main() { 11 | string a, b; 12 | getline(cin, a); 13 | getline(cin, b); 14 | int hashTable[maxn] = {0}; 15 | for(int i = 0; i < b.size(); i++) { 16 | hashTable[b[i]] ++; 17 | } 18 | for(int i = 0; i < a.size(); i++) { 19 | if(hashTable[a[i]] == 0) printf("%c", a[i]); 20 | } 21 | return 0; 22 | } -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第4章 算法初步/散列/B1005.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-07-28 15:51:26 4 | * @LastEditTime: 2019-07-28 16:11:54 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | int main() { 10 | int N, num; 11 | scanf("%d", &N); 12 | int a[N]; 13 | bool hashTable[10000] = {0}; //计算过程会超过100 14 | // 存储每个输入的数并计算它覆盖的数,1直接排除,因为一定会覆盖 15 | for(int i = 0; i < N; i++) { 16 | scanf("%d", &num); 17 | a[i] = num; 18 | int t = num; 19 | // Callatz猜想 20 | while(t != 1) { 21 | if(t % 2 == 0) t /= 2; 22 | else t = (3*t + 1) / 2; 23 | hashTable[t] = true; 24 | } 25 | } 26 | // 存储结果 27 | vector ans; 28 | for(int i = 0; i < N; i++) { 29 | if(!hashTable[a[i]]) ans.push_back(a[i]); 30 | } 31 | // 升序排列 32 | sort(ans.begin(), ans.end()); 33 | // 降序输出 34 | for(int i = ans.size() - 1; i >= 0; i--) { 35 | if(i == ans.size() - 1) printf("%d", ans[i]); 36 | else printf(" %d", ans[i]); 37 | } 38 | return 0; 39 | } -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第4章 算法初步/散列/B1029.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-07-28 06:24:52 4 | * @LastEditTime: 2019-07-28 07:10:26 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | int main() { 10 | string input, output; 11 | cin >>input >>output; 12 | // 记录输出字符串出现的每个字符(小写当大写存) 13 | map mp; 14 | for(int i = 0; i < output.size(); i ++) { 15 | char ch = output[i]; 16 | if(ch >= 'a' && ch <= 'z') ch = ch - ('a' - 'A'); //转换为大写 17 | mp[ch] = 1; 18 | } 19 | // 遍历输入字符串,将小写转为大写,判断输出是否存在相应字符,不在则输出,同时标记为1 20 | for(int i = 0; i < input.size(); i ++) { 21 | char ch = input[i]; 22 | if(ch >= 'a' && ch <= 'z') ch = ch - ('a' - 'A'); //转换为大写 23 | // 非小写字母 && 实际字符串中没有该字符的需要输出 24 | if(mp.count(ch) == 0) { 25 | cout < 8 | using namespace std; 9 | int main() { 10 | string hide, input; 11 | getline(cin, hide); //可能为空行,必须这么读 12 | getline(cin, input); 13 | map mp; 14 | bool flag = false; //是否为上档键 15 | if(hide.size() != 0) { //是否为空行 16 | for(int i = 0; i < hide.size(); i++) { 17 | char t = hide[i]; 18 | // if(t == ',' || t == '.' || t == '-' || t == '+') flag = true; 19 | if(t == '+') flag = true; //只有+是上档键 20 | mp[t] = 1; //表示存在 21 | } 22 | bool isPrint = false; //判断是否有输出 23 | for(int i = 0; i < input.size(); i++) { 24 | char t = input[i]; 25 | if(flag && (t >= 'A' && t <= 'Z')) continue; //上档键损坏大写不输出 26 | if(t >= 'a' && t <= 'z') t = t - ('a' - 'A'); //小写转为大写 27 | if(mp.count(t) == 0) { //可输出 28 | cout < 8 | using namespace std; 9 | int main() { 10 | int N; 11 | scanf("%d", &N); 12 | int hashTable[101] = {0}; //哈希映射 13 | for(int i = 0; i < N; i++) { 14 | int t; 15 | scanf("%d", &t); 16 | hashTable[t] ++;//统计该分数的人数 17 | } 18 | // K次查询 19 | int K; 20 | scanf("%d", &K); 21 | for(int i = 0; i < K; i++) { 22 | int t; 23 | scanf("%d", &t); 24 | if(i == 0) printf("%d", hashTable[t]); 25 | else printf(" %d", hashTable[t]); 26 | } 27 | return 0; 28 | } -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第4章 算法初步/散列/B1039.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-07-28 09:42:11 4 | * @LastEditTime: 2019-07-28 09:48:41 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | int main() { 10 | string a, b; 11 | cin >>a >>b; 12 | // 哈希记录每个字符出现次数 13 | int hashTable[129] = {0}; 14 | for(int i = 0; i < a.size(); i++) { 15 | hashTable[a[i]] ++; 16 | } 17 | int cnt = 0; 18 | for(int i = 0; i < b.size(); i++) { 19 | if(hashTable[b[i]] == 0) cnt ++; //缺失累计 20 | else hashTable[b[i]] --; //匹配成功 21 | } 22 | // 输出 23 | if(cnt == 0) printf("Yes %d", a.size() - b.size()); 24 | else printf("No %d", cnt); 25 | return 0; 26 | } -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第4章 算法初步/散列/B1042.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-07-28 10:17:52 4 | * @LastEditTime: 2019-07-28 10:33:05 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | int main() { 10 | string s; 11 | getline(cin, s); //有空格 12 | int hashTable[128] = {0}; 13 | for(int i = 0; i < s.size(); i++) { 14 | char t = s[i]; 15 | if(t >= 'A' && t <= 'Z') { 16 | t = t + ('a' - 'A'); //大写转为小写 17 | s[i] = t; 18 | } 19 | hashTable[t] ++; 20 | } 21 | // 找字母频率最大,不唯一找字典序最小 22 | char ans = 'z'; //最大的字母 23 | int cnt = -1; //记录最大次数 24 | for(int i = 0; i < s.size(); i++) { 25 | char t = s[i]; 26 | if(t >= 'a' && t <= 'z') { 27 | if((cnt < hashTable[t]) || (cnt == hashTable[t] && ans > t)) { 28 | cnt = hashTable[t]; 29 | ans = t; 30 | } 31 | } 32 | } 33 | cout < 8 | using namespace std; 9 | int main() { 10 | string s; 11 | getline(cin, s); 12 | char change[6] = {'P', 'A', 'T', 'e', 's', 't'}; 13 | int hashTable[128] = {0}; 14 | for(int i = 0; i < s.size(); i++) { 15 | char t = s[i]; 16 | // 仅统计6个字符 17 | for(int j = 0; j < 6; j++) { 18 | if(change[j] == t) { 19 | hashTable[t] ++; 20 | break; 21 | } 22 | } 23 | } 24 | while(true) { 25 | int isPrint = false; 26 | // 6个字符输出为1轮 27 | for(int i = 0; i < 6; i++) { 28 | char t = change[i]; 29 | if(hashTable[t] != 0) { 30 | cout < 8 | using namespace std; 9 | int main() { 10 | int N; 11 | scanf("%d", &N); 12 | int hashTable[1001] = {0}; 13 | int team, id, score; 14 | // 统计每个队伍总分 15 | for(int i = 0; i < N; i++) { 16 | scanf("%d-%d %d", &team, &id, &score); 17 | hashTable[team] += score; 18 | } 19 | // 找出最高分队伍 20 | int winTeam = 1, winScore = hashTable[1]; 21 | for(int i = 2; i < 1001; i++) { 22 | if(winScore < hashTable[i]) { 23 | winTeam = i; 24 | winScore = hashTable[i]; 25 | } 26 | } 27 | printf("%d %d", winTeam, winScore); 28 | return 0; 29 | } -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第4章 算法初步/贪心/A1037.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-07-30 15:13:02 4 | * @LastEditTime: 2019-07-30 15:51:42 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | typedef long long LL; 10 | bool cmp(LL a, LL b) { 11 | if(a < 0 && b < 0) return a < b; //负数升序 12 | else return a > b; //整数,正负数降序 13 | } 14 | int main() { 15 | int n, m; 16 | // 输入 17 | scanf("%d", &n); 18 | vector coupon(n); 19 | for(int i = 0; i < n; i++) scanf("%lld", &coupon[i]); 20 | scanf("%d", &m); 21 | vector product(m); 22 | for(int i = 0; i < m; i++) scanf("%lld", &product[i]); 23 | // 排序 24 | sort(coupon.begin(), coupon.end(), cmp); 25 | sort(product.begin(), product.end(), cmp); 26 | // for(int i = 0; i < n; i++) printf("%d ", coupon[i]); 27 | // printf("\n"); 28 | // for(int i = 0; i < m; i++) printf("%d ", product[i]); 29 | // 计算最大值 30 | LL sum = 0; 31 | int i = 0, j = 0; 32 | while(i < n && j < m) { 33 | // 同号 34 | if((coupon[i] > 0 && product[j] > 0) || (coupon[i] < 0 && product[j] < 0)) { 35 | sum += coupon[i] * product[j]; 36 | i ++; 37 | j ++; 38 | } 39 | // 异号,移动正数 40 | else if(coupon[i] >= 0) i ++; //处理0 41 | else j ++; 42 | } 43 | printf("%lld\n", sum); 44 | return 0; 45 | } -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第4章 算法初步/贪心/A1038.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-07-30 19:54:07 4 | * @LastEditTime: 2019-07-31 09:45:59 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | const int maxn = 10001; 10 | string res[maxn]; 11 | // 结合时小的放在前 12 | bool cmp(string a, string b) { 13 | return a + b < b + a; 14 | } 15 | int main() { 16 | int N; 17 | scanf("%d", &N); 18 | for(int i = 0; i < N; i++) cin >>res[i]; 19 | sort(res, res + N, cmp); 20 | string ans; 21 | // 拼接 22 | for(int i = 0; i < N; i ++) { 23 | ans += res[i]; 24 | } 25 | // 去除前导0 26 | while(ans.size() != 0 && *ans.begin() == '0') { 27 | ans.erase(ans.begin()); 28 | } 29 | // 考虑0的情况 30 | if(ans.size() == 0) printf("0\n"); 31 | else cout < 8 | using namespace std; 9 | const int maxn = 100001; 10 | int a[maxn]; //数值 -> 位置 11 | int main() { 12 | int N; 13 | scanf("%d", &N); 14 | set mySet; 15 | for(int i = 0; i < N; i++) { 16 | int t; 17 | scanf("%d", &t); 18 | a[t] = i; //数值 -> 位置 19 | if(t != i) mySet.insert(t); //将不在正确位置的值存起来 20 | } 21 | int cnt = 0; //交换个数 22 | while(true) { 23 | // 全部归位 24 | if(mySet.empty()) break; 25 | // 0在正确位置,打乱它 26 | if(a[0] == 0) { 27 | int ret = *mySet.begin(); 28 | swap(a[0], a[ret]); 29 | mySet.insert(0); 30 | cnt ++; 31 | } 32 | else { 33 | while(a[0] != 0) { 34 | mySet.erase(a[0]); 35 | swap(a[0], a[a[0]]); 36 | if(a[0] == 0) mySet.erase(0); //考虑依次交换,2个元素正确归位 37 | cnt ++; 38 | } 39 | } 40 | } 41 | printf("%d\n", cnt); 42 | return 0; 43 | } -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第4章 算法初步/贪心/B1020.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-07-29 17:27:16 4 | * @LastEditTime: 2019-07-29 18:49:57 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | // 题目说是正数,并非正整数 10 | struct Moon { 11 | double store; //库存 12 | double price; //价格 13 | double rate; //单价 14 | }; 15 | bool cmp(Moon a, Moon b) { 16 | return a.rate > b.rate; 17 | } 18 | int main() { 19 | int N; 20 | double D; 21 | scanf("%d %lf", &N, &D); 22 | Moon moon[N]; 23 | for(int i = 0; i < N; i++) { 24 | scanf("%lf", &moon[i].store); 25 | } 26 | for(int i = 0; i < N; i++) { 27 | scanf("%lf", &moon[i].price); 28 | moon[i].rate = moon[i].price / moon[i].store; //性价比 29 | } 30 | // 按性价比从高到低排序 31 | sort(moon, moon + N, cmp); 32 | // 尽可能用性价比高的库存 33 | double sum = 0; 34 | for(int i = 0; i < N; i++) { 35 | if(D > moon[i].store) { //库存不足 36 | sum += moon[i].store * moon[i].rate; 37 | D -= moon[i].store; 38 | } 39 | else { 40 | sum += D * moon[i].rate; 41 | break; 42 | } 43 | } 44 | printf("%.2lf", sum); 45 | return 0; 46 | } -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第4章 算法初步/贪心/B1023.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-07-29 14:08:23 4 | * @LastEditTime: 2019-07-29 14:12:48 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | int main() { 10 | int a[10]; 11 | for(int i = 0; i < 10; i++) scanf("%d", &a[i]); 12 | // 找到最小正数作为最高位 13 | for(int i = 1; i < 10; i++) { 14 | if(a[i] != 0) { 15 | printf("%d", i); 16 | a[i] --; 17 | break; 18 | } 19 | } 20 | // 从小依次输出 21 | for(int i = 0; i < 10; i++) { 22 | if(a[i] != 0) { 23 | for(int j = 0; j < a[i]; j++) printf("%d", i); 24 | } 25 | } 26 | return 0; 27 | } -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第5章 数学问题/gcd+lcm+分数四则运算+素数/A1015.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-08-05 19:22:24 4 | * @LastEditTime: 2019-08-05 19:42:14 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | bool isPrime(int n) { 10 | if(n < 2) return false; 11 | for(int i = 2; i <= (int)sqrt(1.0 * n); i++) { //等于号别漏,否则4,10就过不了 12 | if(n % i == 0) return false; 13 | } 14 | return true; 15 | } 16 | bool solve(int n, int d) { 17 | if(!isPrime(n)) return false; //n不是素数直接返回false 18 | // 将10进制的n转为d进制再转为10进制,这里利用其倒序性质同步进行 19 | int sum = 0; 20 | do { 21 | sum = sum * d + n % d; 22 | n /= d; 23 | }while(n != 0); 24 | return isPrime(sum); 25 | } 26 | int main() { 27 | int n, d; 28 | while(true) { 29 | scanf("%d", &n); 30 | if(n < 0) break; 31 | scanf("%d", &d); 32 | printf("%s\n", solve(n, d) ? "Yes" : "No"); 33 | } 34 | return 0; 35 | } -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第5章 数学问题/gcd+lcm+分数四则运算+素数/A1096.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-08-06 15:25:49 4 | * @LastEditTime: 2019-08-06 15:52:41 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | typedef long long LL; 10 | void solve(LL n) { 11 | LL sqrn = (LL)sqrt(1.0*n); 12 | LL ansIdx, ansLen = 0; 13 | for(LL i = 2; i <= sqrn; i++) { 14 | LL product = i, j = i; 15 | // 此处不可限制j <= sqrn,否则6就过不了 16 | while(n % product == 0) { 17 | j ++; 18 | product *= j; 19 | } 20 | // 若使用等于,无法从多对中筛选出最小的 21 | if(j - i > ansLen) { 22 | ansIdx = i; 23 | ansLen = j - i; 24 | } 25 | } 26 | if(ansLen == 0) printf("1\n%d\n", n); 27 | else { 28 | printf("%d\n", ansLen); 29 | for(int i = ansIdx; i < ansIdx + ansLen; i++) { 30 | printf("%d%s", i, i == ansIdx + ansLen - 1? "\n" : "*"); 31 | } 32 | } 33 | } 34 | int main() { 35 | LL n; 36 | scanf("%lld", &n); 37 | solve(n); 38 | return 0; 39 | } -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第5章 数学问题/gcd+lcm+分数四则运算+素数/B1007.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-08-05 16:34:16 4 | * @LastEditTime: 2019-08-05 17:05:54 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | const int maxn = 100010; 10 | int prime[maxn], pNum = 0; //素数表和素数个数 11 | bool p[maxn] = {0}; 12 | // Eratosthenes筛法:O(nloglogn),找出[2,n]的素数 13 | void findPrime(int n) { 14 | for(int i = 2; i <= n; i++) { 15 | if(!p[i]) { 16 | prime[pNum++] = i; 17 | for(int j = i + i; j <= n; j += i) p[j] = true; 18 | } 19 | } 20 | } 21 | // 统计间距为2且不大于n的素数对数 22 | int solve(int n) { 23 | int cnt = 0; 24 | for(int i = 0; i < pNum - 1; i++) { 25 | if(prime[i+1] - prime[i] == 2) cnt ++; 26 | } 27 | return cnt; 28 | } 29 | int main() { 30 | int n; 31 | scanf("%d", &n); 32 | findPrime(n); 33 | printf("%d\n", solve(n)); 34 | return 0; 35 | } -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第5章 数学问题/gcd+lcm+分数四则运算+素数/B1008-2.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-08-05 11:29:29 4 | * @LastEditTime: 2019-08-05 11:37:08 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | void print(int *a, int n) { 10 | for(int i = 0; i < n; i++) { 11 | printf("%d%s", a[i], i + 1 - n ? " " : "\n"); 12 | } 13 | } 14 | int main() { 15 | int n, m; 16 | scanf("%d %d", &n, &m); 17 | int a[n]; 18 | for(int i = 0; i < n; i++) scanf("%d", &a[i]); 19 | m %= n; // m > n 20 | // 3次反转 21 | reverse(a, a + (n - m)); 22 | reverse(a + (n - m), a + n); 23 | reverse(a, a + n); 24 | print(a, n); 25 | return 0; 26 | } -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第5章 数学问题/gcd+lcm+分数四则运算+素数/B1008.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-08-05 10:39:13 4 | * @LastEditTime: 2019-08-05 11:01:17 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | int a[101]; 10 | // 打印 11 | void print(int n) { 12 | for(int i = 0; i < n; i++) { 13 | if(i == 0) printf("%d", a[i]); 14 | else printf(" %d", a[i]); 15 | } 16 | printf("\n"); 17 | } 18 | // 最大公约数 19 | int gcd(int a, int b) { 20 | if(b == 0) return a; 21 | else return gcd(b, a % b); 22 | } 23 | // 模拟循环右移 24 | void solve(int n, int m) { 25 | int d = gcd(n, m); 26 | // 轮换的组数d 27 | for(int i = 0; i < d; i++) { 28 | int j = i; 29 | // 以a[j]为起点,m为间隔的轮换 30 | int cur, next = a[j], to; 31 | do { 32 | cur = next; 33 | j = (j + m) % n; 34 | next = a[j]; 35 | a[j] = cur; 36 | }while(j != i); 37 | } 38 | } 39 | int main() { 40 | int n, m; 41 | scanf("%d %d", &n, &m); 42 | for(int i = 0; i < n; i++) scanf("%d", &a[i]); 43 | m %= n; //m >= n的情况 44 | // m == 0直接输出即可 45 | if(m != 0) solve(n, m); 46 | print(n); 47 | return 0; 48 | } -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第5章 数学问题/gcd+lcm+分数四则运算+素数/B1013.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-08-05 17:13:53 4 | * @LastEditTime: 2019-08-05 17:52:39 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | int prime[maxn], num = 0; //第m~n个素数 10 | // 判断是否为素数,是->true;否->false 11 | bool isPrime(int n) { 12 | if(n < 2) return false; //小于2不可能是素数 13 | int sqr = (int)sqrt(1.0 * n); //要乘1.0变成浮点数 14 | for(int i = 2; i <= sqr; i++) { 15 | if(n % i == 0) return false; 16 | } 17 | return true; 18 | } 19 | // 寻找第[m,n]个素数 20 | void findPrime(int m, int n) { 21 | int pNum = 0, i = 2; 22 | do { 23 | if(isPrime(i)) { 24 | pNum ++; 25 | if(pNum >= m && pNum <= n) prime[num++] = i; 26 | } 27 | i ++; 28 | }while(pNum != n); 29 | } 30 | void print() { 31 | for(int i = 0; i < num; i++) { 32 | printf("%d%s", prime[i], (i % 10 == 9 || i == num - 1) ? "\n" : " "); 33 | } 34 | } 35 | int main() { 36 | int m, n; 37 | scanf("%d %d", &m, &n); 38 | findPrime(m, n); 39 | print(); 40 | return 0; 41 | } -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第5章 数学问题/简单数学/A1008.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-08-04 20:18:17 4 | * @LastEditTime: 2019-08-04 20:27:38 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | typedef long long LL; 10 | int main() { 11 | LL n; 12 | scanf("%lld", &n); 13 | // 分别计算出上楼,下楼,停留的总次数 14 | LL now = 0, pos = 0, neg = 0, t; 15 | for(LL i = 0; i < n; i++) { 16 | scanf("%lld", &t); 17 | LL tmp = t - now; 18 | if(tmp > 0) pos += tmp; 19 | else neg += tmp; 20 | now = t; 21 | } 22 | printf("%lld\n", pos * 6 + (-neg) * 4 + n * 5); 23 | return 0; 24 | } -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第5章 数学问题/简单数学/A1049-1.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-08-05 08:34:10 4 | * @LastEditTime: 2019-08-05 08:41:50 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | typedef long long LL; 10 | int main() { 11 | LL n; 12 | scanf("%lld", &n); 13 | LL a = 1, left, right, now, sum = 0; 14 | while(n / a != 0) { 15 | right = n % a; 16 | now = (n / a) % 10; 17 | left = n / a / 10; 18 | if(now == 0) sum += left * a; 19 | else if(now == 1) sum += left * a + right + 1; 20 | else sum += (left + 1) * a; 21 | a *= 10; 22 | } 23 | printf("%lld\n", sum); 24 | return 0; 25 | } -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第5章 数学问题/简单数学/A1049.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-08-04 21:02:36 4 | * @LastEditTime: 2019-08-04 21:30:06 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | const int inf = (1 << 30) + 1; 10 | struct Number { 11 | int val; 12 | int cnt; 13 | }queryTable[1023]; 14 | void init() { 15 | queryTable[0].val = 1; 16 | queryTable[0].cnt = 1; 17 | int i = 1, radix = 1; 18 | while(i < 1023) { 19 | radix *= 10; 20 | queryTable[i].val = radix; 21 | queryTable[i].cnt = 1; 22 | int j = 0, end = i; 23 | i++; 24 | while(j < end) { 25 | queryTable[i].val = queryTable[end].val + queryTable[j].val; 26 | queryTable[i].cnt = queryTable[end].cnt + queryTable[j].cnt; 27 | i++; 28 | j++; 29 | } 30 | } 31 | } 32 | int main() { 33 | init(); 34 | // for(int i = 0; i < 1023; i++){ 35 | // printf("%d %d\n", queryTable[i].val, queryTable[i].cnt); 36 | // } 37 | int n, sum = 0; 38 | scanf("%d", &n); 39 | for(int i = 0; i < 1023; i++) { 40 | if(queryTable[i].val <= n) { 41 | sum += queryTable[i].cnt; 42 | } 43 | else break; 44 | } 45 | printf("%d\n", sum); 46 | return 0; 47 | } -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第5章 数学问题/简单数学/B1003.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-08-04 12:00:43 4 | * @LastEditTime: 2019-08-04 13:02:30 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | int main() { 10 | string s; 11 | regex pattern("A*PAA*TA*"); // 匹配模式 12 | int N; 13 | scanf("%d", &N); 14 | // N个测试字符串 15 | for(int i = 0; i < N; i++) { 16 | cin >>s; 17 | bool ret = regex_match(s, pattern); //全文匹配成功返回true 18 | if(ret) { //成功 19 | string::iterator itP = find(s.begin(), s.end(), 'P'); //找到P的位置 20 | string::iterator itT = find(s.begin(), s.end(), 'T'); //找到T的位置 21 | // 3个部分A的个数 22 | int a = itP - s.begin(); 23 | int b = itT - itP - 1; 24 | int c = s.end() - itT - 1; 25 | // 满足a * b == c说明符合条件 26 | if(a * b == c) printf("YES\n"); 27 | else printf("NO\n"); 28 | } 29 | else printf("NO\n"); //失败 30 | } 31 | return 0; 32 | } -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第5章 数学问题/简单数学/B1019.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-08-04 13:46:31 4 | * @LastEditTime: 2019-08-04 14:34:04 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | bool cmp(char a, char b) { 10 | return a < b; 11 | } 12 | // 模拟减法:根据val,得到其非降序排列a,非升序排列b 13 | string solve(int val, string &a, string &b) { 14 | char tmp[5]; 15 | sprintf(tmp, "%04d", val); //数字拆分为字符串 16 | a = tmp; 17 | sort(a.begin(), a.end(), cmp); //从小到大排序 18 | b = a; 19 | reverse(b.begin(), b.end()); //逆置 20 | // 将a,b转换为int型 21 | int num1, num2; 22 | sscanf(a.c_str(), "%d", &num1); 23 | sscanf(b.c_str(), "%d", &num2); 24 | // 计算差值后转为字符型 25 | sprintf(tmp, "%04d", num2 - num1); 26 | string ret = tmp; 27 | return ret; 28 | } 29 | int main() { 30 | int n; 31 | string a, b, ret; 32 | scanf("%d", &n); 33 | do { 34 | ret = solve(n, a, b); 35 | if(ret == "0000") { 36 | printf("%s - %s = 0000\n", b.c_str(), a.c_str()); 37 | break; 38 | } 39 | else { 40 | printf("%s - %s = %s\n", b.c_str(), a.c_str(), ret.c_str()); 41 | sscanf(ret.c_str(), "%d", &n); 42 | } 43 | 44 | }while(ret != "6174"); 45 | return 0; 46 | } -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第5章 数学问题/简单数学/B1049.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-08-04 18:40:07 4 | * @LastEditTime: 2019-08-04 19:58:44 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | const int maxn = 100010; 10 | double a[maxn]; //单精度会报错 11 | long long cnt[maxn] = {0}; 12 | int main() { 13 | int n; 14 | scanf("%d", &n); 15 | for(int i = 1; i <= n; i++) scanf("%lf", &a[i]); 16 | // 利用上下、左右的对称性,计算左边一半的列和 17 | for(long long i = 1; i <= n / 2; i++) { 18 | cnt[i] = (i * (i + 1) / 2 + (n / 2 - i) * i) * 2; //这里使用int会溢出 19 | if(n % 2 != 0) cnt[i] += i; //奇数,中间一行 20 | cnt[n - i + 1] = cnt[i]; //左右对称 21 | } 22 | if(n % 2 != 0) cnt[n / 2 + 1] = cnt[n / 2] + 1; //奇数,中间一列 23 | // 计算总和 24 | double sum = 0.0; 25 | for(int i = 1; i <= n; i++) { 26 | sum += a[i] * cnt[i]; 27 | } 28 | printf("%.2lf\n", sum); 29 | return 0; 30 | } -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第6章 STL/A1039.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-08-07 13:32:44 4 | * @LastEditTime: 2019-08-07 14:05:26 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | map > res; 10 | // 将数据建立映射:姓名->课程号列表 11 | int readData() { 12 | int N, K; 13 | scanf("%d %d", &N, &K); 14 | int idx, n; 15 | for(int i = 0; i < K; i ++) { 16 | scanf("%d %d", &idx, &n); 17 | char str[40]; 18 | string name; 19 | for(int i = 0; i < n; i ++) { 20 | scanf("%s", str); //避免超时 21 | name = str; 22 | res[name].push_back(idx); 23 | } 24 | } 25 | return N; //查询个数 26 | } 27 | // 对应的课程列表升序排列 28 | void sortByIdx() { 29 | for(auto& mp : res) { //auto类型推导 30 | sort(mp.second.begin(), mp.second.end()); 31 | } 32 | } 33 | // 根据N名字查询各自的课程号 34 | void queryByName(int N) { 35 | char str[30]; 36 | string name; 37 | for(int i = 0; i < N; i ++) { 38 | scanf("%s", str); //用scanf读入,否则会超时 39 | printf("%s", str); 40 | name =str; 41 | if(res.count(name) == 0) printf(" 0"); 42 | else { 43 | auto vec = res[name]; 44 | printf(" %d", vec.size()); 45 | for(auto p : vec) printf(" %d", p); 46 | } 47 | printf("\n"); 48 | } 49 | 50 | } 51 | int main() { 52 | int N = readData(); 53 | sortByIdx(); 54 | queryByName(N); 55 | return 0; 56 | } -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第6章 STL/A1047.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-08-07 15:20:00 4 | * @LastEditTime: 2019-08-07 15:29:40 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | const int maxn = 2510; 10 | vector hashTable[maxn]; 11 | int readData() { 12 | int N, K; 13 | scanf("%d %d", &N, &K); 14 | char str[20]; 15 | string name; 16 | int n, idx; 17 | for(int i = 0; i < N; i ++) { 18 | scanf("%s%d", str, &n); 19 | name = str; 20 | for(int i = 0; i < n; i ++) { 21 | scanf("%d", &idx); 22 | hashTable[idx].push_back(name); 23 | } 24 | } 25 | return K; 26 | } 27 | bool cmp(string a, string b) { 28 | return a < b; 29 | } 30 | void showResult(int K) { 31 | for(int i = 1; i <= K; i ++) { 32 | sort(hashTable[i].begin(), hashTable[i].end()); 33 | int len = hashTable[i].size(); 34 | printf("%d %d\n", i, len); 35 | for(int j = 0; j < len; j ++) { 36 | printf("%s\n", hashTable[i][j].c_str()); 37 | } 38 | } 39 | } 40 | int main() { 41 | int K = readData(); 42 | showResult(K); 43 | return 0; 44 | } -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第6章 STL/A1054-2.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-08-08 11:55:39 4 | * @LastEditTime: 2019-08-08 11:59:19 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | int main() { 10 | int m, n; 11 | scanf("%d %d", &m, &n); 12 | int ans = -1, cnt = 1, t; 13 | for(int i = 0; i < n; i ++) { 14 | for(int j = 0; j < m; j ++) { 15 | scanf("%d", &t); 16 | // 不等,需抵消 17 | if(ans != t) { 18 | if(cnt == 1) ans = t; //直接更新ans 19 | else cnt --; 20 | } 21 | else cnt ++; //相等 22 | } 23 | } 24 | printf("%d\n", ans); 25 | return 0; 26 | } -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第6章 STL/A1054.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-08-08 11:37:28 4 | * @LastEditTime: 2019-08-08 11:44:50 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | int main() { 10 | int m, n; 11 | scanf("%d %d", &m, &n); 12 | map mp; 13 | int t; 14 | // 统计每个颜色出现次数 15 | for(int i = 0; i < n; i ++) { 16 | for(int j = 0; j < m; j ++) { 17 | scanf("%d", &t); 18 | if(mp.count(t) == 0) mp[t] = 0; //初始化 19 | mp[t] ++; 20 | } 21 | } 22 | // 找出最大值 23 | int ans, maxCnt = 0; 24 | for(auto p : mp) { 25 | if(p.second > maxCnt) { 26 | maxCnt = p.second; 27 | ans = p.first; 28 | } 29 | } 30 | printf("%d\n", ans); 31 | return 0; 32 | } -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第6章 STL/A1063.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-08-07 16:04:30 4 | * @LastEditTime: 2019-08-07 16:27:36 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | const int maxn = 51; 10 | set sets[maxn]; 11 | void initSets() { 12 | int n; 13 | scanf("%d", &n); 14 | int m; 15 | for(int i = 1; i <= n; i ++) { 16 | scanf("%d", &m); 17 | int t; 18 | for(int j = 0; j < m; j ++) { 19 | scanf("%d", &t); 20 | sets[i].insert(t); 21 | } 22 | } 23 | } 24 | // 计算两个集合的交并集的元素个数即可 25 | double getSimilarity(set a, set b) { 26 | int Nc = 0, Nt = 0; 27 | // 交集元素个数 28 | for(auto p : b) { 29 | if(a.count(p) != 0) Nc ++; 30 | } 31 | Nt = a.size() + b.size() - Nc; //并集元素个数 32 | return ((double)Nc / Nt) * 100; 33 | } 34 | void query() { 35 | int n; 36 | scanf("%d", &n); 37 | int a, b; 38 | for(int i = 0; i < n; i ++) { 39 | scanf("%d %d", &a, &b); 40 | printf("%.1lf%\n", getSimilarity(sets[a], sets[b])); 41 | } 42 | } 43 | int main() { 44 | initSets(); 45 | query(); 46 | return 0; 47 | } -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第6章 STL/A1071.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-08-08 13:06:40 4 | * @LastEditTime: 2019-08-08 13:44:19 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | // 判断c是否为数字字母表中的一员 10 | bool judge(char c) { 11 | if(c >= '0' && c <= '9' || c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z') return true; 12 | else return false; 13 | 14 | } 15 | int main() { 16 | string s; 17 | getline(cin, s); 18 | map mp; 19 | string t; 20 | for(int i = 0; i < s.size(); i ++) { 21 | char c = s[i]; 22 | if(judge(c)) { 23 | if(c >= 'A' && c <= 'Z') c = c + ('a' - 'A'); //大写转小写 24 | t.push_back(c); 25 | } 26 | if(!judge(c) || i == s.size() - 1) { //遇到不合法字符||最后一个需处理t 27 | if(t.empty()) continue; //若t为空,继续循环 28 | if(mp.count(t) == 0) mp[t] = 0; //初始化 29 | mp[t] ++; 30 | t.clear(); //清空 31 | } 32 | } 33 | string ans; 34 | int maxCnt = -1; 35 | // map自动有序,找最大值,若有多对也是取字典序小者 36 | for(auto p : mp) { 37 | if(maxCnt < p.second) { 38 | ans = p.first; 39 | maxCnt = p.second; 40 | } 41 | } 42 | cout < 8 | using namespace std; 9 | const int maxn = 100010; 10 | struct LNode { 11 | int addr, next; 12 | char data; 13 | }SLink[maxn], node; 14 | bool hashTable[maxn] = {0}; 15 | void traverseSLink(int head) { 16 | int now = head; 17 | while(now != -1) { 18 | hashTable[now] = true; 19 | now = SLink[now].next; 20 | } 21 | } 22 | int main() { 23 | int head1, head2, n; 24 | scanf("%d %d %d", &head1, &head2, &n); 25 | for(int i = 0; i < n; i ++) { 26 | scanf("%d %c %d", &node.addr, &node.data, &node.next); 27 | SLink[node.addr] = node; 28 | } 29 | // 遍历第一个链表,将其有效节点对应的标记置为true 30 | traverseSLink(head1); 31 | int ans = -1; //答案 32 | int cur = head2; 33 | // 遍历第二条链表 34 | while(cur != -1) { 35 | if(hashTable[cur]) { //找到第一个为true节点,记录答案,立刻退出 36 | ans = SLink[cur].addr; 37 | break; 38 | } 39 | cur = SLink[cur].next; 40 | } 41 | if(ans == -1) printf("-1\n"); 42 | else printf("%05d\n", ans); 43 | return 0; 44 | } -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第7章 数据结构专题1/A1051.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-08-08 19:21:23 4 | * @LastEditTime: 2019-08-08 19:48:04 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | int main() { 10 | int m, n, k; 11 | scanf("%d %d %d", &m, &n, &k); 12 | int t; 13 | for(int i = 0; i < k; i ++) { 14 | stack res; 15 | int idx = 0; //当前最大值 16 | for(int j = 0; j < n; j ++) { 17 | scanf("%d", &t); 18 | if(t > idx) { 19 | // 小于等于t的值必须先入栈 20 | for(int x = idx + 1; x <= t; x ++) { 21 | res.push(x); 22 | } 23 | idx = t; 24 | } 25 | // 不超出栈的范围且与栈顶相同 26 | if(res.size() <= m && t == res.top()) res.pop(); 27 | } 28 | if(res.empty()) printf("YES\n"); 29 | else printf("NO\n"); 30 | } 31 | return 0; 32 | } -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第7章 数据结构专题1/B1025.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-08-09 15:04:56 4 | * @LastEditTime: 2019-08-09 15:52:24 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | const int maxn = 100001; 10 | struct LNode { 11 | int addr, data, next; //地址,数据,下个地址 12 | int order; //编号,第几个节点 13 | // 默认构造函数,初始化 14 | LNode() { 15 | order = maxn; 16 | } 17 | }SLink[maxn], node; //静态链表 18 | bool cmp(LNode a, LNode b) { 19 | return a.order < b.order; //按序号升序排列 20 | } 21 | int main() { 22 | int head, N, K; 23 | scanf("%d %d %d", &head, &N, &K); 24 | // 构造静态链表 25 | for(int i = 0; i < N; i ++) { 26 | scanf("%d %d %d", &node.addr, &node.data, &node.next); 27 | SLink[node.addr] = node; 28 | } 29 | // 遍历链表,给每个节点按顺序编号,可能存在无效点 30 | int now = head, cnt = 0; //cnt计数有效点个数 31 | while(SLink[now].next != -1) { 32 | SLink[now].order = cnt ++; 33 | now = SLink[now].next; 34 | } 35 | SLink[now].order = cnt ++; 36 | // 将有效节点移到数组左端 37 | sort(SLink, SLink + maxn, cmp); 38 | int groupNum = cnt / K; //需要反转的组数 39 | // 分组反转 40 | for(int i = 0; i < groupNum; i ++) { 41 | reverse(SLink + i * K, SLink + (i + 1) * K); 42 | } 43 | // 输出 44 | for(int i = 0; i < cnt; i ++) { 45 | printf("%05d %d ", SLink[i].addr, SLink[i].data); 46 | if(i == cnt - 1) printf("-1\n"); 47 | else printf("%05d\n", SLink[i+1].addr); 48 | } 49 | return 0; 50 | } -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第9章 数据结构专题2/A1004.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-08-12 14:11:40 4 | * @LastEditTime: 2019-08-12 14:29:01 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | const int maxn = 101; 10 | struct STNode { 11 | vector child; 12 | bool isRoot; //判断是否为根 13 | STNode() {isRoot = true;} 14 | }STree[maxn]; 15 | int N, M, maxLayer = -1; //结点个数、非叶子个数、最大层数 16 | int leafs[maxn] = {0}; // 每一层叶子个数 17 | // root:当前结点 depth:当前深度 18 | void dfs(int root, int depth) { 19 | if(STree[root].child.empty()) { 20 | leafs[depth] ++; 21 | if(maxLayer < depth) maxLayer = depth; //最大深度 22 | return; 23 | } 24 | for(auto p : STree[root].child) { 25 | dfs(p, depth + 1); 26 | } 27 | } 28 | void readData() { 29 | scanf("%d %d", &N, &M); 30 | int id, k, idx; 31 | for(int i = 0; i < M; i ++) { 32 | scanf("%d %d", &id, &k); 33 | for(int j = 0; j < k; j ++) { 34 | scanf("%d", &idx); 35 | STree[id].child.push_back(idx); 36 | STree[idx].isRoot = false; //不是根 37 | } 38 | } 39 | } 40 | // 从1开始找 41 | int findRoot() { 42 | for(int i = 1; i < N; i ++) { 43 | if(STree[i].isRoot) return i; 44 | } 45 | } 46 | int main() { 47 | readData(); 48 | int root = findRoot(); 49 | dfs(root, 1); 50 | for(int i = 1; i <= maxLayer; i ++) { 51 | printf("%d%s", leafs[i], i == maxLayer ? "\n" : " "); 52 | } 53 | return 0; 54 | } -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第9章 数据结构专题2/A1064.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-08-12 23:32:22 4 | * @LastEditTime: 2019-08-12 23:42:13 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | const int maxn = 1010; 10 | int CBST[maxn], in[maxn]; //完全二叉排序树、中序遍历序列 11 | int N, idx = 0; //结点数 12 | // 中序遍历将in的值依次填入相应结点 13 | void inorderTravesal(int root) { 14 | if(root > N) return; 15 | inorderTravesal(2 * root); 16 | CBST[root] = in[idx ++]; //填入相应值 17 | inorderTravesal(2 * root + 1); 18 | } 19 | int main() { 20 | scanf("%d", &N); 21 | for(int i = 0; i < N; i ++) { 22 | scanf("%d", &in[i]); 23 | } 24 | sort(in, in + N); //BST中序必为升序 25 | inorderTravesal(1); 26 | // 数组存放顺序即为层序遍历,从1开始存 27 | for(int i = 1; i <= N; i ++) { 28 | printf("%d%s", CBST[i], i == N ? "\n" : " "); 29 | } 30 | return 0; 31 | } -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第9章 数据结构专题2/A1086.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-08-11 16:47:03 4 | * @LastEditTime: 2019-08-11 17:19:26 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | struct TNode { 10 | int data; 11 | TNode *lchild, *rchild; 12 | }; 13 | vector op, post; //操作序列、后序遍历结果 14 | int N, cnt = 0; //结点总数、当前操作下标 15 | // 遍历操作数组,idx为全局变量cnt的引用,表示当前的操作 16 | TNode* createTree(int &idx) { 17 | // 遍历完所有操作或pop直接返回空 18 | if(idx == 2 * N || op[idx] == -1) return NULL; 19 | TNode* root = new TNode; 20 | root->data = op[idx]; 21 | root->lchild = createTree(++idx); //左子树优先 22 | root->rchild = createTree(++idx); 23 | return root; 24 | } 25 | // 后序遍历 26 | void postTraverse(TNode* root) { 27 | if(root == NULL) return; 28 | postTraverse(root->lchild); 29 | postTraverse(root->rchild); 30 | post.push_back(root->data); 31 | } 32 | // 打印结果 33 | void showResult() { 34 | for(int i = 0; i < N; i ++) { 35 | printf("%d%s", post[i], i == N - 1 ? "\n" : " "); 36 | } 37 | } 38 | int main() { 39 | scanf("%d", &N); 40 | string s; 41 | int t; 42 | for(int i = 0; i < 2 * N; i ++) { 43 | cin >>s; 44 | if(s == "Push") { //push存放输入的数据 45 | scanf("%d", &t); 46 | op.push_back(t); 47 | } 48 | else op.push_back(-1); //pop用-1表示 49 | } 50 | postTraverse(createTree(cnt)); 51 | showResult(); 52 | return 0; 53 | } -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第9章 数据结构专题2/A1090.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-08-12 10:35:31 4 | * @LastEditTime: 2019-08-12 10:54:34 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | const int maxn = 100010; 10 | struct STNode { 11 | vector child; 12 | }STree[maxn]; 13 | double P, r, maxPrice = -1; //root单价,增加比率,最大单价 14 | int tot = 0; // 最大单价的个数 15 | // 找到单价最高的叶子个数及其最大值 16 | void dfs(int root, double price) { 17 | // 叶子,retailers 18 | if(STree[root].child.empty()) { 19 | if(maxPrice < price) { 20 | maxPrice = price; 21 | tot = 1; //重新找到最大值 22 | } 23 | else if(maxPrice == price) tot ++; //最大值个数 24 | return; 25 | } 26 | // 遍历所有子结点 27 | for(auto p : STree[root].child) { 28 | dfs(p, price * (1 + r / 100)); 29 | } 30 | } 31 | int readData() { 32 | int n; 33 | scanf("%d %lf %lf", &n, &P, &r); 34 | int t, root; 35 | for(int i = 0; i < n; i ++) { 36 | scanf("%d", &t); 37 | if(t != -1) { 38 | STree[t].child.push_back(i); 39 | } 40 | else root = i; // 根节点 41 | } 42 | return root; 43 | } 44 | int main() { 45 | int root = readData(); 46 | dfs(root, P); 47 | printf("%.2lf %d\n", maxPrice, tot); 48 | return 0; 49 | } -------------------------------------------------------------------------------- /AlgorithmNote/AlgorithmNote-Code/第9章 数据结构专题2/A1094.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-08-12 11:31:15 4 | * @LastEditTime: 2019-08-12 12:01:12 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | const int maxn = 101; 10 | struct STNode { 11 | int layer; 12 | vector child; 13 | }STree[maxn]; 14 | int cnt[maxn] = {0}; 15 | void layerTraversal(int root) { 16 | queue q; 17 | STree[root].layer = 1; 18 | q.push(root); 19 | while(!q.empty()) { 20 | int now = q.front(); 21 | q.pop(); 22 | cnt[STree[now].layer] ++; // 层号出现次数计算 23 | for(auto p : STree[now].child) { 24 | STree[p].layer = STree[now].layer + 1; 25 | q.push(p); 26 | } 27 | } 28 | } 29 | void readData() { 30 | int N, M; 31 | scanf("%d %d", &N, &M); 32 | int cur, n, idx; 33 | for(int i = 0; i < M; i++) { 34 | scanf("%d %d", &cur, &n); 35 | for(int j = 0; j < n; j ++) { 36 | scanf("%d", &idx); 37 | STree[cur].child.push_back(idx); 38 | } 39 | } 40 | } 41 | int main() { 42 | readData(); 43 | layerTraversal(1); 44 | int maxCnt = -1, ans; 45 | for(int i = 0; i < maxn; i ++) { 46 | if(maxCnt < cnt[i]) { 47 | maxCnt = cnt[i]; 48 | ans = i; 49 | } 50 | } 51 | printf("%d %d\n", maxCnt, ans); 52 | return 0; 53 | } -------------------------------------------------------------------------------- /AlgorithmNote/README.md: -------------------------------------------------------------------------------- 1 | # 《算法笔记上机训练实战指南》题解目录 2 | 3 | > [个人博客](https://wyjoutstanding.github.io/) 4 | > 5 | > [github](https://github.com/wyjoutstanding?tab=repositories) 6 | > 7 | > [CSDN博客](https://blog.csdn.net/qq_40738840) 8 | 9 | ### 目录结构 10 | 11 | + code:所有题目源码(包括优化后的代码) 12 | + note:所有题目的分析笔记,题型总结归纳 13 | 14 | --- 15 | 16 | 按照章节划分题目,每个章节也是一个专题,可挑着看 17 | 18 | 题目比较基础,适合考研,保研,PAT,CCF-CSP机考基础训练阶段 19 | 20 | 欢迎指教、star~ -------------------------------------------------------------------------------- /CCF-CSP/CSP-Code/第1题/201312-1.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-09-13 16:13:53 4 | * @LastEditTime: 2019-09-13 16:19:47 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | const int maxn = 10100; 10 | int n, a[maxn] = {0}, t, ans = 0, MAX = -1; 11 | int main() { 12 | scanf("%d", &n); 13 | for(int i = 0; i < n; i ++) { // 统计每个值出现次数 14 | scanf("%d", &t); 15 | a[t] ++; 16 | } 17 | for(int i = 0; i < maxn; i ++) { // 找出现次数最多的数,存在多个取最小 18 | if(MAX < a[i]) { 19 | MAX = a[i]; 20 | ans = i; 21 | } 22 | } 23 | printf("%d\n", ans); 24 | return 0; 25 | } -------------------------------------------------------------------------------- /CCF-CSP/CSP-Code/第1题/201403-1.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-09-13 16:05:06 4 | * @LastEditTime: 2019-09-13 16:07:01 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | int n, cnt[1010] = {0}, t, ans = 0; 10 | int main() { 11 | scanf("%d", &n); 12 | for(int i = 0; i < n; i ++) { 13 | scanf("%d", &t); 14 | if(cnt[abs(t)] == 0) cnt[abs(t)] = 1; 15 | else ans ++; 16 | } 17 | printf("%d\n", ans); 18 | return 0; 19 | } -------------------------------------------------------------------------------- /CCF-CSP/CSP-Code/第1题/201409-1.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-09-13 15:55:39 4 | * @LastEditTime: 2019-09-13 15:57:43 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | int n, a[1010], ans = 0; 10 | int main() { 11 | scanf("%d", &n); 12 | for(int i = 0; i < n; i ++) scanf("%d", &a[i]); 13 | sort(a, a + n); 14 | for(int i = 1; i < n; i ++) { 15 | if(a[i] - a[i-1] == 1) ans ++; 16 | } 17 | printf("%d\n", ans); 18 | return 0; 19 | } -------------------------------------------------------------------------------- /CCF-CSP/CSP-Code/第1题/201412-1.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-09-13 15:50:07 4 | * @LastEditTime: 2019-09-13 15:51:08 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | int n, cnt[1010] = {0}, t; 10 | int main() { 11 | scanf("%d", &n); 12 | for(int i = 0; i < n; i ++) { 13 | scanf("%d", &t); 14 | cnt[t] ++; 15 | printf("%d ", cnt[t]); 16 | } 17 | return 0; 18 | } -------------------------------------------------------------------------------- /CCF-CSP/CSP-Code/第1题/201503-1.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-09-13 15:39:52 4 | * @LastEditTime: 2019-09-13 15:41:54 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | int n, m, a[1001][1001]; 10 | int main() { 11 | scanf("%d %d", &n, &m); 12 | for(int i = 0; i < n; i ++) { 13 | for(int j = 0; j < m; j ++) scanf("%d", &a[i][j]); 14 | } 15 | for(int i = 0; i < m; i ++) { 16 | for(int j = 0; j < n; j ++) printf("%d ", a[j][m-1-i]); 17 | printf("\n"); 18 | } 19 | return 0; 20 | } -------------------------------------------------------------------------------- /CCF-CSP/CSP-Code/第1题/201509-1.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-09-13 15:21:09 4 | * @LastEditTime: 2019-09-13 15:22:23 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | int main() { 10 | int n, t, ans = 0, pre = -1; 11 | scanf("%d", &n); 12 | for(int i = 0; i < n; i ++) { 13 | scanf("%d", &t); 14 | if(pre != t) { 15 | ans ++; 16 | pre = t; 17 | } 18 | } 19 | printf("%d\n", ans); 20 | return 0; 21 | } -------------------------------------------------------------------------------- /CCF-CSP/CSP-Code/第1题/201512-1.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-09-13 15:14:04 4 | * @LastEditTime: 2019-09-13 15:15:03 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | int main() { 10 | string s; 11 | int ans = 0; 12 | cin >>s; 13 | for(auto& p : s) ans += (p - '0'); 14 | printf("%d\n", ans); 15 | return 0; 16 | } -------------------------------------------------------------------------------- /CCF-CSP/CSP-Code/第1题/201604-1.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-09-13 15:01:19 4 | * @LastEditTime: 2019-09-13 15:06:28 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | int n, a[1010], ans = 0; 10 | int main() { 11 | scanf("%d", &n); 12 | for(int i = 0; i < n; i ++) scanf("%d", &a[i]); 13 | for(int i = 1; i < n - 1; i ++) { 14 | if((a[i] - a[i-1]) * (a[i+1] - a[i]) < 0) ans ++; // 折点:斜率相乘为负 15 | } 16 | printf("%d\n", ans); 17 | return 0; 18 | } -------------------------------------------------------------------------------- /CCF-CSP/CSP-Code/第1题/201609-1.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-09-13 14:49:18 4 | * @LastEditTime: 2019-09-13 14:51:44 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | int n, a[1010], ans = -1; 10 | int main() { 11 | scanf("%d", &n); 12 | for(int i = 0; i < n; i ++) scanf("%d", &a[i]); 13 | for(int i = 1; i < n; i ++) ans = max(ans, abs(a[i] - a[i - 1])); //找相邻差值最大者 14 | printf("%d\n", ans); 15 | return 0; 16 | } -------------------------------------------------------------------------------- /CCF-CSP/CSP-Code/第1题/201612-1-2-upper.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-09-13 14:35:26 4 | * @LastEditTime: 2019-09-13 14:40:12 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | int n, a[1010], ans = -1; 10 | int main() { 11 | scanf("%d", &n); 12 | for(int i = 0; i < n; i ++) scanf("%d", &a[i]); 13 | sort(a, a + n); 14 | int p1 = lower_bound(a, a + n, a[n / 2]) - a; // 第一个大于等于x的下标 15 | int p2 = upper_bound(a, a + n, a[n / 2]) - a; // 第一个大于x的下标 16 | if(p1 == n - p2) ans = a[n / 2]; 17 | printf("%d\n", ans); 18 | return 0; 19 | } -------------------------------------------------------------------------------- /CCF-CSP/CSP-Code/第1题/201612-1.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-09-13 14:00:54 4 | * @LastEditTime: 2019-09-13 14:18:14 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | int n, a[1010], small[1010] = {0}, big[1010] = {0}, ans = -1; 10 | int main() { 11 | scanf("%d", &n); 12 | for(int i = 0; i < n; i ++) scanf("%d", &a[i]); 13 | sort(a, a + n); 14 | for(int i = 1; i < n; i ++) { 15 | if(a[i] > a[i - 1]) small[i] = i; // 小于a[i]的个数 16 | else small[i] = small[i - 1]; 17 | if(a[n - 1 - i] < a[n - i]) big[n - 1 - i] = i; // 大于a[i]的个数 18 | else big[n - 1- i] = big[n - i]; 19 | } 20 | for(int i = 0; i < n; i ++) { // 查找中间数 21 | if(small[i] == big[i]) { 22 | ans = a[i]; 23 | break; 24 | } 25 | } 26 | printf("%d\n", ans); 27 | return 0; 28 | } -------------------------------------------------------------------------------- /CCF-CSP/CSP-Code/第1题/201703-1.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-09-13 13:42:28 4 | * @LastEditTime: 2019-09-13 13:49:57 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | int main() { 10 | int n, k, ans = 0, sum = 0, t; 11 | scanf("%d %d", &n, &k); 12 | for(int i = 0; i < n; i ++) { 13 | scanf("%d", &t); 14 | sum += t; 15 | if(sum >= k) { // 下一个人 16 | ans ++; 17 | sum = 0; 18 | } 19 | } 20 | printf("%d\n", ans += (sum == 0) ? 0 : 1); // 最后未分满K的需处理 21 | return 0; 22 | } -------------------------------------------------------------------------------- /CCF-CSP/CSP-Code/第1题/201709-1.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-09-13 13:25:19 4 | * @LastEditTime: 2019-09-13 13:27:51 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | int main() { 10 | int n; 11 | scanf("%d", &n); 12 | n = n / 10; 13 | printf("%d\n", (n / 5) * 7 + ((n % 5) / 3) * 4 + (n % 5 % 3)); 14 | return 0; 15 | } -------------------------------------------------------------------------------- /CCF-CSP/CSP-Code/第1题/201712-1.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-09-13 13:15:53 4 | * @LastEditTime: 2019-09-13 13:18:56 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | int n, a[10010], ans = 0x3fffffff; 10 | int main() { 11 | scanf("%d", &n); 12 | for(int i = 0; i < n; i ++) scanf("%d", &a[i]); 13 | sort(a, a + n); // 升序排列 14 | for(int i = 0; i < n - 1; i ++) ans = min(ans, a[i+1] - a[i]); // 相邻两点最小差值 15 | printf("%d\n", ans); 16 | return 0; 17 | } -------------------------------------------------------------------------------- /CCF-CSP/CSP-Code/第1题/201803-1.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-09-13 12:58:30 4 | * @LastEditTime: 2019-09-13 13:03:25 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | int main() { 10 | int t, pre = 1, sum = 0; 11 | while(scanf("%d", &t)) { 12 | if(t == 0) break; 13 | if(t == 1) { 14 | pre = 1; 15 | sum += 1; 16 | } 17 | else if(t == 2) { 18 | if(pre == 1) pre = 2; 19 | else pre += 2; 20 | sum += pre; 21 | } 22 | } 23 | printf("%d\n", sum); 24 | return 0; 25 | } -------------------------------------------------------------------------------- /CCF-CSP/CSP-Code/第1题/201809-1.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-09-13 11:00:37 4 | * @LastEditTime: 2019-09-13 11:03:45 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | int n, a[1010]; 10 | int main() { 11 | scanf("%d", &n); 12 | for(int i = 0; i < n; i ++) scanf("%d", &a[i]); 13 | for(int i = 0; i < n; i ++) { 14 | if(i == 0) printf("%d ", (a[0] + a[1]) / 2); 15 | else if(i == n - 1) printf("%d ", (a[n - 2] + a[n - 1]) / 2); 16 | else printf("%d ", (a[i-1] + a[i] + a[i+1]) / 3); 17 | } 18 | return 0; 19 | } -------------------------------------------------------------------------------- /CCF-CSP/CSP-Code/第1题/201812-1.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-09-13 10:49:17 4 | * @LastEditTime: 2019-09-13 10:53:16 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | int main() { 10 | int r, y, g, n, sum = 0, type, t; 11 | scanf("%d %d %d %d", &r, &y, &g, &n); 12 | for(int i = 0; i < n; i ++) { 13 | scanf("%d %d", &type, &t); 14 | if(type == 0 || type == 1) sum += t; // 路段/红灯 15 | else if(type == 2) sum += (t + r); // 黄灯 16 | } 17 | printf("%d\n", sum); 18 | return 0; 19 | } -------------------------------------------------------------------------------- /CCF-CSP/CSP-Code/第1题/201903-1.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-09-13 09:49:10 4 | * @LastEditTime: 2019-09-13 10:07:39 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | int n, a[100010]; 10 | vector > ans; // 值->类型(0:整数,1:浮点数) 11 | int main() { 12 | scanf("%d", &n); 13 | for(int i = 1; i <= n; i ++) scanf("%d", &a[i]); 14 | ans.push_back({a[1] * 2, 0}); // 两端的最大/最小值 15 | ans.push_back({a[n] * 2, 0}); 16 | if(n % 2 != 0) ans.push_back({a[(n + 1) / 2] * 2, 0}); // 中位数 17 | else { 18 | int tmp = a[n / 2] + a[n / 2 + 1]; 19 | if(tmp % 2 == 0) ans.push_back({tmp, 0}); 20 | else ans.push_back({tmp, 1}); 21 | } 22 | sort(ans.begin(), ans.end(), [](pair a, pair b) {return a.first > b.first;}); // 从大到小排序 23 | for(auto& p : ans) { // 输出 24 | if(p.second == 0) printf("%d ", p.first / 2); 25 | else printf("%.1lf ", (double)p.first / 2); 26 | } 27 | printf("\n"); 28 | return 0; 29 | } -------------------------------------------------------------------------------- /CCF-CSP/CSP-Code/第2题/201703-2.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Create time: 2019-09-27 23:30:07 4 | * @Last Modified time: 2019-09-27 23:30:07 5 | * @Gitub: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | vector a(1010); 10 | int main() { 11 | int n, m; 12 | scanf("%d %d", &n, &m); 13 | a[0]= 0; 14 | for(int i = 1; i <= n; i ++) a[i] = i; 15 | int id, disp; 16 | for(int i = 0; i < m; i ++) { 17 | scanf("%d %d", &id, &disp); 18 | auto p = find(a.begin(), a.end(), id); 19 | p = a.erase(p); // 删除会改变之后的迭代器值 20 | auto ip = p + disp; 21 | if(ip >= a.end()) a.push_back(id); // 处理尾部 22 | else a.insert(ip, id); 23 | } 24 | for(int i = 1; i <= n; i ++) printf("%d ", a[i]); 25 | return 0; 26 | } -------------------------------------------------------------------------------- /CCF-CSP/CSP-Code/第2题/201709-2.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-09-14 20:37:46 4 | * @LastEditTime: 2019-09-15 00:09:20 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | struct Action { 10 | int keyId, type, time; // 钥匙编号,动作类型(0:借,1:还),动作发生时间 11 | }a[2010]; // 借还动作 12 | int N, K, key[1010]; // 钥匙盒1~N 13 | bool cmp(Action& a, Action& b) { 14 | if(a.time != b.time) return a.time < b.time; // 动作时间小者优先 15 | else if(a.type != b.type) return a.type > b.type; // 动作还优先,字母打错了!!!! 16 | else return a.keyId < b.keyId; // 多个还id小者优先 17 | } 18 | int main() { 19 | scanf("%d %d", &N, &K); 20 | int k, s, c; 21 | for(int i = 0; i < 2*K; i += 2) { // 拆分借还动作 22 | scanf("%d %d %d", &k, &s, &c); 23 | a[i].keyId = a[i+1].keyId = k; 24 | a[i].type = 0; a[i+1].type = 1; 25 | a[i].time = s; a[i+1].time = s + c; // 借还时间 26 | } 27 | sort(a, a + 2*K, cmp); // 动作排序 28 | for(int i = 0; i <= N; i ++) key[i] = i; // 初始化钥匙盒 29 | for(int i = 0; i < 2*K; i ++) { // 2*K个事件模拟 30 | if(a[i].type == 0) key[find(key+1, key+N+1, a[i].keyId) - key] = -1; // 取钥匙,置为-1 31 | else key[find(key+1, key+N+1, -1) - key] = a[i].keyId; // 还钥匙,从左开始找到第一个空位 32 | } 33 | for(int i = 1; i <= N; i ++) printf("%d ", key[i]); 34 | return 0; 35 | } -------------------------------------------------------------------------------- /CCF-CSP/CSP-Code/第2题/201712-2-queue.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int n, k, cnt = 0; 4 | queue q; 5 | int main() { 6 | scanf("%d %d", &n, &k); 7 | for(int i = 1; i <= n; i ++) q.push(i); 8 | while(q.size() > 1) { 9 | int now = q.front(); // 当前报数的人的编号 10 | q.pop(); 11 | cnt ++; // 报数 12 | if(cnt % k != 0 && cnt % 10 != k) q.push(now); // 没死继续加入队列 13 | } 14 | printf("%d\n", q.front()); 15 | return 0; 16 | } -------------------------------------------------------------------------------- /CCF-CSP/CSP-Code/第2题/201712-2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int n, k; 4 | set a; // 存储人0~n-1 5 | int main() { 6 | scanf("%d %d", &n, &k); 7 | for(int i = 0; i < n; i ++) a.insert(i); // 标号0~n-1的参与者 8 | int i = 0, cnt = 0; // 当前的人的编号、报数的值 9 | while(true) { 10 | if(a.size() == 1) { // 最后一个人直接输出,结束 11 | printf("%d\n", *a.begin() + 1); 12 | break; 13 | } 14 | if(a.count(i) != 0) { // 没死 15 | cnt ++; // 报数 16 | if(cnt % k == 0 || cnt % 10 == k) a.erase(i); // 满足条件,杀死 17 | } 18 | i = (i + 1) % n; // 更新下一个人 19 | } 20 | return 0; 21 | } -------------------------------------------------------------------------------- /CCF-CSP/CSP-Code/第2题/201803-2-2.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-09-14 19:46:37 4 | * @LastEditTime: 2019-09-14 19:54:15 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | const int maxn = 110; 10 | struct Pos { 11 | int id, x; // 输入顺序, 位置 12 | }a[maxn]; 13 | int N, L, T, order[maxn]; 14 | int main() { 15 | scanf("%d %d %d", &N, &L, &T); 16 | for(int i = 0; i < N; i ++) { 17 | scanf("%d", &a[i].x); 18 | a[i].id = i; // 输入顺序 19 | } 20 | sort(a, a + N, [](Pos& a, Pos& b) {return a.x < b.x;}); // 按距离从小到达排序 21 | for(int i = 0; i < N; i ++) order[a[i].id] = i; // 记录每个输入位置对应的实际位置 22 | for(int i = 0; i < N; i ++) { // N个点更新位置 23 | int tmp = (a[i].x + T) % (2*L); // 2L为一周期 24 | if(tmp > L) a[i].x = L - (tmp % L); // 大于L,等于从最右边往回走 25 | else a[i].x = tmp; 26 | } 27 | sort(a, a + N, [](Pos& a, Pos& b) {return a.x < b.x;}); // 按距离从小到达排序,相对位置一致 28 | for(int i = 0; i < N; i ++) printf("%d ", a[order[i]].x); // 输出 29 | return 0; 30 | } -------------------------------------------------------------------------------- /CCF-CSP/CSP-Code/第2题/201803-2.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-09-14 18:56:32 4 | * @LastEditTime: 2019-09-14 19:26:48 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | const int maxn = 110; 10 | struct Pos { 11 | int id, x, dist; // 输入顺序, 位置, 方向:-1左,1右 12 | }a[maxn]; 13 | int N, L, T, order[maxn]; 14 | int main() { 15 | scanf("%d %d %d", &N, &L, &T); 16 | for(int i = 0; i < N; i ++) { 17 | scanf("%d", &a[i].x); 18 | a[i].id = i; // 输入顺序 19 | a[i].dist = 1; // 方向向右 20 | } 21 | sort(a, a + N, [](Pos& a, Pos& b) {return a.x < b.x;}); // 按距离从小到达排序 22 | for(int i = 0; i < N; i ++) order[a[i].id] = i; // 记录每个输入位置对应的实际位置 23 | for(int i = 0; i < T; i ++) { // T次更新 24 | int j = 0; 25 | while(j < N) { 26 | a[j].x += a[j].dist; 27 | if(a[j].x == 0 || a[j].x == L) a[j].dist = -a[j].dist; // 边界反转 28 | else if(j < N - 1 && a[j].x == (a[j+1].x + a[j+1].dist)) { // 两球碰撞 29 | a[j].dist = -a[j].dist; // 更新方向 30 | a[j+1].x += a[j+1].dist; // 先更新位置 31 | a[j+1].dist = -a[j+1].dist; 32 | j ++; // 后移一位 33 | } 34 | j ++; 35 | } 36 | } 37 | for(int i = 0; i < N; i ++) printf("%d ", a[order[i]].x); // 输出 38 | return 0; 39 | } -------------------------------------------------------------------------------- /CCF-CSP/CSP-Code/第2题/201809-2.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-09-14 15:04:22 4 | * @LastEditTime: 2019-09-14 15:31:43 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | const int maxn = 1000010; 10 | struct Pos { 11 | int l, r; // 左右区间 12 | }H[maxn], W[maxn]; 13 | int n, l, r, ans = 0; 14 | void solve() { 15 | int i = 0, j = 0; 16 | while(i < n && j < n) { 17 | if(H[i].l <= W[j].r && H[i].r >= W[j].l) { // 存在交集 18 | ans += min(H[i].r, W[j].r) - max(H[i].l, W[j].l); // 区间 19 | } 20 | if(H[i].r == W[j].r) { // 相等,两个同时后移 21 | i ++; 22 | j ++; 23 | } 24 | else if(H[i].r < W[j].r) i ++; // 右侧小者后移 25 | else j ++; 26 | } 27 | printf("%d\n", ans); 28 | } 29 | int main() { 30 | scanf("%d", &n); 31 | for(int i = 0; i < n; i ++) scanf("%d %d", &H[i].l, &H[i].r); 32 | for(int i = 0; i < n; i ++) scanf("%d %d", &W[i].l, &W[i].r); 33 | solve(); 34 | return 0; 35 | } -------------------------------------------------------------------------------- /CCF-CSP/CSP-Code/第2题/201812-2.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-09-14 09:59:37 4 | * @LastEditTime: 2019-09-14 10:29:57 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | typedef long long LL; 10 | LL n, r, y, g, t[4] = {0}, ans = 0; // int存储4个测试点会溢出 11 | void init() { // 构造循环时钟0~t1~t3~t2分别对应红->绿->黄 12 | t[1] = r; 13 | t[3] = r + g; 14 | t[2] = r + g + y; 15 | } 16 | LL getWaitTime(LL type, LL leftTime) { // 根据出发时灯类型和剩余时间返回当前需等待时间 17 | LL cur = (t[type] - leftTime + ans) % (r + g + y); // 计算当前状态 18 | if(cur >=0 && cur < t[1]) return t[1] - cur; // 红灯 19 | if(cur >= t[1] && cur < t[3]) return 0; // 绿灯 20 | if(cur >= t[3] && cur < t[2]) return t[2] - cur + r; // 黄灯 21 | } 22 | void solve() { 23 | scanf("%lld %lld %lld %lld", &r, &y, &g, &n); 24 | init(); 25 | LL type, lt; 26 | while(n --) { 27 | scanf("%lld %lld", &type, <); 28 | if(type == 0) ans += lt; // 路 29 | else ans += getWaitTime(type, lt); // 灯 30 | } 31 | printf("%lld\n", ans); 32 | } 33 | int main() { 34 | solve(); 35 | return 0; 36 | } -------------------------------------------------------------------------------- /CCF-CSP/CSP-Code/第2题/output.txt: -------------------------------------------------------------------------------- 1 | Yes 2 | No 3 | No 4 | No 5 | Yes 6 | No 7 | No 8 | No 9 | No 10 | No 11 | -------------------------------------------------------------------------------- /CCF-CSP/CSP-Code/第2题/run.bat: -------------------------------------------------------------------------------- 1 | 201903-2.exe < test.txt > output.txt -------------------------------------------------------------------------------- /CCF-CSP/CSP-Code/第2题/test.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Create time: 2019-10-09 21:14:14 4 | * @Last Modified time: 2019-10-09 21:14:14 5 | * @Gitub: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | int main() { 10 | // int a, b, c; 11 | fstream f, fout; 12 | f.open("test.txt", ios::in); 13 | fout.open("ans.txt", ios::out); 14 | string str; 15 | // fgets(str, 1000, f); 16 | while(getline(f, str)) { 17 | if(!str.empty()) { 18 | fout < 8 | using namespace std; 9 | int n, a[1100]; 10 | int main() { 11 | scanf("%d", &n); 12 | for(int i = 0; i < n; i ++) scanf("%d", &a[i]); 13 | int MAX = *max_element(a, a + n); // 选出最大高度 14 | int ans = -1; // 保存结果 15 | for(int h = 1; h <= MAX; h ++) { // 遍历所有高度 16 | int sum = 0; 17 | for(int j = 0; j < n; j ++) { // 计算连续的矩形面积 18 | if(a[j] >= h) sum += h; 19 | else { // 产生间断的矩形 20 | ans = max(ans, sum); 21 | sum = 0; 22 | } 23 | } 24 | ans = max(ans, sum); // 无间断的矩形 25 | } 26 | printf("%d\n", ans); 27 | return 0; 28 | } -------------------------------------------------------------------------------- /CCF-CSP/CSP-Code/第3题/201403-3.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-09-08 09:23:46 4 | * @LastEditTime: 2019-09-08 10:27:46 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | unordered_map opt; // 接受选项->带参数与否 ,0:不带,1:带 10 | int main() { 11 | string s; 12 | cin >>s; 13 | int i = 0; 14 | while(i < s.size()) { 15 | string tmp = "-"; 16 | tmp.push_back(s[i]); 17 | if(i < s.size() - 1 && s[i+1] == ':') { 18 | opt[tmp] = 1; 19 | i ++; 20 | } 21 | else opt[tmp] = 0; 22 | i ++; 23 | } 24 | int n; 25 | string tmp, arg; 26 | scanf("%d", &n); 27 | getchar(); 28 | for(int i = 1; i <= n; i ++) { 29 | getline(cin, s); 30 | stringstream input(s); 31 | getline(input, tmp, ' '); 32 | map ans; // 存放选项和参数结果 33 | while(getline(input, tmp, ' ')) { 34 | if(tmp[0] != '-' || opt.count(tmp) == 0) break; // 不是命令选项或没有此命令选项 35 | if(opt[tmp] == 0) ans[tmp] = ""; // 不带参数 36 | if(opt[tmp] == 1) { // 带参数 37 | if(getline(input, arg, ' ')) ans[tmp] = arg; // 更新参数 38 | else break; // 不存在参数 39 | } 40 | } 41 | printf("Case %d:", i); // 打印 42 | for(auto& p : ans) { 43 | printf(" %s", p.first.c_str()); 44 | if(!p.second.empty()) printf(" %s", p.second.c_str()); 45 | } 46 | printf("\n"); 47 | } 48 | return 0; 49 | } -------------------------------------------------------------------------------- /CCF-CSP/CSP-Code/第3题/201409-3-regex.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-09-07 22:03:51 4 | * @LastEditTime: 2019-09-07 22:56:28 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | int main() { 10 | string dist, tmp, s; 11 | int flag, n; 12 | cin >>dist >>flag >>n; 13 | while(n --) { 14 | cin >>s; 15 | // if(flag == 0 && regex_match(s, regex("[[:alpha:]]*"+dist+"[[:alpha:]]*", regex::icase))) puts(s.c_str()); 16 | // if(flag == 1 && regex_match(s, regex("[[:alpha:]]*"+dist+"[[:alpha:]]*"))) puts(s.c_str()); 17 | // if(flag == 0 && regex_search(s, regex("[[:alpha:]]*"+dist+"[[:alpha:]]*", regex::icase))) puts(s.c_str()); 18 | // if(flag == 1 && regex_search(s, regex("[[:alpha:]]*"+dist+"[[:alpha:]]*"))) puts(s.c_str()); 19 | if(flag == 0 && regex_search(s, regex(dist, regex::icase))) puts(s.c_str()); 20 | if(flag == 1 && regex_search(s, regex(dist))) puts(s.c_str()); 21 | 22 | } 23 | return 0; 24 | } 25 | // [a-zA-Z]*Hello[a-zA-Z]* -------------------------------------------------------------------------------- /CCF-CSP/CSP-Code/第3题/201409-3.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-09-07 21:37:04 4 | * @LastEditTime: 2019-09-07 23:17:37 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | int main() { 10 | string dist, tmp, s; 11 | int flag, n; 12 | cin >>dist >>flag >>n; 13 | // if(flag == 0) transform(dist.begin(), dist.end(), dist.begin(), [](char c) {return tolower(c);}); //转为小写 14 | if(flag == 0) transform(dist.begin(), dist.end(), dist.begin(), ::tolower); //转为小写 15 | while(n --) { 16 | cin >>s; 17 | tmp = s; 18 | if(flag == 0) transform(tmp.begin(), tmp.end(), tmp.begin(), [](char c) {return tolower(c);}); //转为小写 19 | if(tmp.find(dist) != string::npos) printf("%s\n", s.c_str()); 20 | } 21 | return 0; 22 | } -------------------------------------------------------------------------------- /CCF-CSP/CSP-Code/第3题/201509-3-find.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-09-06 20:56:55 4 | * @LastEditTime: 2019-09-06 21:16:04 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | map mp; // 变量 -> 值 10 | string s, var, val, ans, tmp; 11 | int main() { 12 | int m, n; 13 | scanf("%d %d", &m, &n); 14 | getchar(); 15 | char str[1000]; 16 | while(m --) { 17 | fgets(str, 1000, stdin); 18 | s += (string)str; 19 | } 20 | while(n --) { 21 | scanf("%s ", str); 22 | var = str; 23 | getline(cin, val); 24 | val = val.substr(1, val.size() - 2); 25 | mp.insert({var, val}); 26 | } 27 | auto i = 0; 28 | do { 29 | auto j = s.find("{{", i), k = s.find("}}", i); // 从i开始找到第一个{{和}} 30 | if(j != string::npos && k != string::npos) { // 变量存在 31 | for(; i < j; i ++) printf("%c", s[i]); // 输出从i开始的匹配的变量间字符 32 | tmp = s.substr(j + 3, k - j - 4); // 变量名 33 | if(mp.count(tmp) != 0) printf("%s", mp[tmp].c_str()); // 变量名的值存在,直接输出 34 | i = k + 2; // 更新下标 35 | } 36 | else for(; i < s.size(); i ++) printf("%c", s[i]); // 匹配结束,输出剩余字符 37 | }while(i < s.size()); 38 | return 0; 39 | } -------------------------------------------------------------------------------- /CCF-CSP/CSP-Code/第3题/201509-3-regex2.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-09-06 20:29:29 4 | * @LastEditTime: 2019-09-06 20:56:20 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | map mp; // 变量 -> 值 10 | string s, var, val, ans, tmp; 11 | int main() { 12 | int m, n; 13 | scanf("%d %d", &m, &n); 14 | getchar(); 15 | char str[1000]; 16 | while(m --) { 17 | fgets(str, 1000, stdin); 18 | s += (string)str; 19 | } 20 | while(n --) { 21 | scanf("%s ", str); 22 | var = str; 23 | getline(cin, val); 24 | val = val.substr(1, val.size() - 2); 25 | mp.insert({var, val}); 26 | } 27 | auto i = s.cbegin(); // regex_search需要const_iterator类型变量 28 | smatch res; 29 | while(regex_search(i, s.cend(), res, regex("\\{\\{ ([^ ]+) \\}\\}"))) { // 搜索匹配变量 30 | for(; i != res[0].first; i ++) printf("%c", *i); // 输出匹配前的字符 31 | if(mp.count(res[1]) != 0) printf("%s", mp[res[1]].c_str()); // 若存在变量,直接输出 32 | i = res[0].second; // 更换下标,下一次搜索 33 | } 34 | for(; i != s.cend(); i ++) printf("%c", *i); // 输出剩余字符 35 | return 0; 36 | } -------------------------------------------------------------------------------- /CCF-CSP/CSP-Code/第3题/201509-3.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-09-06 18:58:19 4 | * @LastEditTime: 2019-09-06 20:10:55 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | map mp; // 变量 -> 值 10 | string s, var, val, ans, tmp; 11 | int main() { 12 | int m, n; 13 | scanf("%d %d", &m, &n); 14 | getchar(); 15 | char str[1000]; 16 | while(m --) { 17 | fgets(str, 1000, stdin); 18 | s += (string)str; 19 | } 20 | while(n --) { 21 | scanf("%s ", str); 22 | var = str; 23 | getline(cin, val); 24 | val = val.substr(1, val.size() - 2); 25 | mp.insert({var, val}); 26 | } 27 | s = regex_replace(s, regex("(\\{\\{)"), "`{{"); 28 | s = regex_replace(s, regex("(\\}\\})"), "}}`"); 29 | stringstream input(s); 30 | while(getline(input, tmp, '`')) { 31 | smatch res; 32 | if(regex_match(tmp, res, regex("^\\{\\{ ([^ ]+) \\}\\}$"))) { 33 | if(mp.count(res.str(1)) != 0) { 34 | ans += mp[res.str(1)]; 35 | } 36 | } 37 | else ans += tmp; 38 | } 39 | cout < 8 | using namespace std; 9 | string nowPath; 10 | int main() { 11 | int n; 12 | cin >>n >>nowPath; 13 | getchar(); 14 | string s, tmp; 15 | while(n --) { 16 | getline(cin, s); 17 | if(s.empty()) printf("%s\n", nowPath.c_str()); // 空串输出当前路径 18 | else { 19 | vector ans; 20 | if(s[0] != '/') s = nowPath + "/" + s; // 非绝对路径直接加上当前路径 21 | s = regex_replace(s, regex("(//+)"), "/"); // 正则将//+替换为/ 22 | stringstream input(s.substr(1)); 23 | while(getline(input, tmp, '/')) { // 分割路径 24 | if(tmp == ".") continue; 25 | else if(tmp == "..") { 26 | if(!ans.empty()) ans.pop_back(); 27 | } 28 | else ans.push_back(tmp); 29 | } 30 | printf("/"); 31 | for(int i = 0; i < ans.size(); i ++) 32 | printf("%s%s", ans[i].c_str(), i == ans.size() - 1 ? "\n" : "/"); 33 | if(ans.size() == 0) printf("\n"); // 根目录特判 34 | } 35 | } 36 | return 0; 37 | } -------------------------------------------------------------------------------- /CCF-CSP/CSP-Code/第3题/201909-3.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wyjoutstanding/Algorithm/4d5c99f5a91d4a8dfcededa9d2da4b375080fb4e/CCF-CSP/CSP-Code/第3题/201909-3.cpp -------------------------------------------------------------------------------- /CCF-CSP/CSP-Code/第3题/ans.txt: -------------------------------------------------------------------------------- 1 | Case 1: -a -l 2 | Case 2: 3 | Case 3: -w 15 -x 4 | Case 4: -a -b -------------------------------------------------------------------------------- /CCF-CSP/CSP-Code/第3题/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | /* run this program using the console pauser or add your own getch, system("pause") or input loop */ 4 | 5 | //int main(int argc, char** argv) { 6 | // return 0; 7 | //} 8 | -------------------------------------------------------------------------------- /CCF-CSP/CSP-Code/第3题/output.txt: -------------------------------------------------------------------------------- 1 | Case 1: -a -l 2 | Case 2: 3 | Case 3: -w 15 -x 4 | Case 4: -a -b 5 | -------------------------------------------------------------------------------- /CCF-CSP/CSP-Code/第3题/run.bat: -------------------------------------------------------------------------------- 1 | 201403-3.exeoutput.txt 2 | fc ans.txt output.txt -------------------------------------------------------------------------------- /CCF-CSP/CSP-Code/第3题/test.txt: -------------------------------------------------------------------------------- 1 | albw:x 2 | 4 3 | ls -a -l -a documents -b 4 | ls 5 | ls -w 10 -x -w 15 6 | ls -a -b -c -d -e -l 7 | -------------------------------------------------------------------------------- /CCF-CSP/CSP-Code/第4题/201312-4.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Create time: 2019-09-26 17:15:43 4 | * @Last Modified time: 2019-09-26 17:15:43 5 | * @Gitub: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | typedef long long LL; 10 | LL mod = 1000000007, n, dp[1002][6] = {0}; // 6个状态:{2},{02},{23},{012},{023},{0123} 11 | int main() { 12 | scanf("%lld", &n); 13 | for(int i = 1; i <= n; i ++) { // n次迭代,填表 14 | dp[i][0] = 1; // 2 15 | dp[i][1] = (dp[i-1][0] + dp[i-1][1] * 2) % mod; // 02 16 | dp[i][2] = (dp[i-1][0] + dp[i-1][2]) % mod; // 23 17 | dp[i][3] = (dp[i-1][1] + dp[i-1][3] * 2) % mod; // 012 18 | dp[i][4] = (dp[i-1][1] + dp[i-1][2] + dp[i-1][4] * 2) % mod; // 023 19 | dp[i][5] = (dp[i-1][3] + dp[i-1][4] + dp[i-1][5] * 2) % mod; // 0123 20 | } 21 | printf("%lld\n", dp[n][5]); 22 | return 0; 23 | } -------------------------------------------------------------------------------- /CCF-CSP/CSP-Code/第4题/201412-4.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Create time: 2019-09-21 00:18:28 4 | * @Last Modified time: 2019-09-21 00:18:28 5 | * @Gitub: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | const int maxn = 1010; 10 | struct Edge { 11 | int u, v, d; // 边的起止点,边权 12 | }; 13 | vector edge; 14 | int n, m; 15 | int father[maxn]; 16 | int findFather(int x) { // 并查集递归找根节点&&压缩路径 17 | return x == father[x] ? x : father[x] = findFather(father[x]); 18 | } 19 | void kruskal() { 20 | for(int i = 0; i < maxn; i ++) father[i] = i; // 初始化 21 | sort(edge.begin(), edge.end(), [](Edge& a, Edge& b) {return a.d < b.d;}); // 按边权从小到大排序 22 | int cnt = 0, ans = 0; // 已选边数,边权之和 23 | for(auto& p : edge) {// 遍历所有边 24 | int fu = findFather(p.u); 25 | int fv = findFather(p.v); 26 | if(fu != fv) { // 两点不通 27 | // father[p.u] = p.v; // 合并 28 | father[fu] = fv; // 父节点合并 29 | cnt ++; 30 | ans += p.d; 31 | } 32 | if(cnt == n - 1) break; // 找到生成树 33 | } 34 | printf("%d\n", ans); 35 | } 36 | int main() { 37 | scanf("%d %d", &n, &m); 38 | int u, v, d; 39 | for(int i = 0; i < m; i ++) { 40 | scanf("%d %d %d", &u, &v, &d); 41 | edge.push_back(Edge{u, v, d}); 42 | } 43 | kruskal(); 44 | return 0; 45 | } -------------------------------------------------------------------------------- /CCF-CSP/CSP-Code/第4题/201503-4.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Create time: 2019-09-19 20:52:15 4 | * @Last Modified time: 2019-09-19 20:52:15 5 | * @Gitub: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | const int maxn = 20010; // n+m 10 | vector adj[maxn]; // 邻接矩阵 11 | int MAX = 0, firstV = 1, vis[maxn] = {0}; // 最大步数,第一个最远点,访问数组 12 | void dfs(int u, int cnt) { // u:当前点;cnt:经过的边数 13 | vis[u] = true; 14 | for(auto& v : adj[u]) { // 遍历所有相邻边 15 | if(!vis[v]) dfs(v, cnt + 1); 16 | } 17 | if(MAX < cnt) { // 取最长的一条 18 | MAX = cnt; 19 | firstV = u; 20 | } 21 | } 22 | int main() { 23 | int n, m, t; 24 | scanf("%d %d", &n, &m); 25 | for(int i = 2; i <= n + m; i ++) { // 电脑从n个交换机后编号 26 | scanf("%d", &t); 27 | adj[t].push_back(i); // 无向图 28 | adj[i].push_back(t); 29 | } 30 | dfs(1, 0); // 第一次dfs得到一个点 31 | fill(vis, vis + maxn, 0); // 初始化访问数组 32 | dfs(firstV, 0); // 第二次dfs得到结果MAX 33 | printf("%d\n", MAX); 34 | return 0; 35 | } -------------------------------------------------------------------------------- /CCF-CSP/CSP-Code/第4题/201604-4.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-09-18 18:42:25 4 | * @LastEditTime: 2019-09-18 19:16:41 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | bool inq[102][102][302] = {false}; // inq[x][y][t]=true表示坐标为(x,y)的点在t时刻无法被访问 10 | struct Pos { 11 | int x, y, t; // 点坐标及其被访问的时刻 12 | }; 13 | int direct[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}}; // 控制方向 14 | int n, m, t; 15 | int bfs() { 16 | queue q; 17 | q.push(Pos{1, 1, 0}); 18 | inq[1][1][0] = true; // 起点(1,1)入队立刻标记为true 19 | while(!q.empty()) { 20 | Pos cur = q.front(); q.pop(); 21 | if(cur.x == n && cur.y == m) return cur.t; // 到达终点(n,m) 22 | for(int i = 0; i < 4; i ++) { // 4个方向 23 | int x = cur.x + direct[i][0]; 24 | int y = cur.y + direct[i][1]; 25 | if(x >= 1 && x <= n && y >= 1 && y <= m && !inq[x][y][cur.t + 1]) { // x,y合法且(x,y)在t时刻可访问 26 | q.push(Pos{x, y, cur.t + 1}); 27 | inq[x][y][cur.t + 1] = true; 28 | } 29 | } 30 | } 31 | } 32 | int main() { 33 | scanf("%d %d %d", &n, &m, &t); 34 | int r, c, a, b; 35 | for(int i = 0; i < t; i ++) { 36 | scanf("%d %d %d %d", &r, &c, &a, &b); 37 | for(int j = a; j <= b; j ++) inq[r][c][j] = true; // 时间段赋值 38 | } 39 | printf("%d\n", bfs()); 40 | return 0; 41 | } -------------------------------------------------------------------------------- /CCF-CSP/CSP-Code/第4题/201703-4.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-09-11 19:43:13 4 | * @LastEditTime: 2019-09-11 20:14:38 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | const int maxn = 100010; 10 | struct GNode { 11 | int v, d; 12 | GNode(int _v, int _d) : v(_v), d(_d) {} 13 | }; 14 | vector adj[maxn]; 15 | bool vis[maxn] = {false}; 16 | int n, m, MAX = -1, ans = 0x3fffffff; 17 | void dfs(int pre, int cur, int c, int MAX) { // 路径的前一个点,当前点,二者距离(时间),当前路径的最大边 18 | if(c > ans) return; // 剪枝 19 | vis[cur] = true; 20 | MAX = max(MAX, c); // 路径中的最大值 21 | if(cur == n) { // 找到一条合适路径 22 | ans = min(ans, MAX); // 找最小值 23 | return; 24 | } 25 | for(auto p : adj[cur]) { // 访问邻边 26 | if(!vis[p.v]) { 27 | dfs(cur, p.v, p.d, MAX); 28 | vis[p.v] = false; // 回溯 29 | } 30 | } 31 | } 32 | int main() { 33 | scanf("%d %d", &n, &m); 34 | int a, b, c; 35 | for(int i = 0; i < m; i ++) { 36 | scanf("%d %d %d", &a, &b, &c); 37 | adj[a].push_back(GNode(b, c)); // 无向图 38 | adj[b].push_back(GNode(a, c)); 39 | } 40 | dfs(1, 1, 0, -1); 41 | printf("%d\n", ans); 42 | return 0; 43 | } -------------------------------------------------------------------------------- /CCF-CSP/CSP-Code/第4题/201709-4.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-09-11 09:45:43 4 | * @LastEditTime: 2019-09-11 15:57:17 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | const int maxn = 1010; 10 | struct GNode { 11 | int v; 12 | GNode(int _v) : v(_v) {} 13 | }; 14 | vector adj[maxn]; // 邻接表,图 15 | int n, m, now, vis[maxn]; 16 | int cnt[maxn][maxn] = {false}; // 记录两个点间是否存在通路,用set会超时 17 | void dfs(int u) { 18 | vis[u] = true; 19 | cnt[now][u] = cnt[u][now] = true; 20 | for(auto p : adj[u]) { 21 | if(!vis[p.v]) { 22 | dfs(p.v); 23 | } 24 | } 25 | } 26 | int main() { 27 | scanf("%d %d", &n, &m); 28 | int u, v, ans = 0; 29 | for(int i = 0; i < m; i ++) { 30 | scanf("%d %d", &u, &v); 31 | adj[u].push_back(GNode(v)); // 有向边 32 | } 33 | for(int u = 1; u <= n; u ++) { 34 | fill(vis, vis + maxn, false); 35 | now = u; 36 | dfs(u); 37 | } 38 | for(int i = 1; i <= n; i ++) { 39 | if(count(cnt[i] + 1, cnt[i] + n + 1, true) == n) ans ++; 40 | } 41 | printf("%d\n", ans); 42 | return 0; 43 | } -------------------------------------------------------------------------------- /CCF-CSP/CSP-Code/第4题/201812-4-kruskal.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: wuyangjun 3 | * @Date: 2019-09-09 08:55:33 4 | * @LastEditTime: 2019-09-09 09:13:28 5 | * @Github: https://github.com/wyjoutstanding 6 | */ 7 | #include 8 | using namespace std; 9 | const int maxn = 50010; 10 | struct Edge { 11 | int u, v, d; 12 | Edge(int _u, int _v, int _d) : u(_u), v(_v), d(_d) {} 13 | friend bool operator < (const Edge& a, const Edge& b) {return a.d > b.d;} 14 | }; 15 | priority_queue edge; // 优先队列边 16 | int n, m, root, father[maxn]; 17 | int findFather(int x) { // 递归找到根节点并路径压缩 18 | if(x == father[x]) return x; 19 | int tmp = findFather(father[x]); 20 | father[x] = tmp; // 路径压缩 21 | return tmp; 22 | } 23 | void kruskal() { 24 | for(int i = 0; i < maxn; i ++) father[i] = i; // 初始化 25 | int ans = 0, cnt = 0; // MST最大边,边数 26 | while(!edge.empty()) { // 优先队列非空 27 | auto e = edge.top(); 28 | edge.pop(); 29 | int fa = findFather(e.u), fb = findFather(e.v); 30 | if(fa != fb) { // 不在同一集合 31 | father[fa] = fb; // 合并 32 | cnt ++; 33 | ans = e.d; // 更新最大边 34 | if(cnt == n - 1) break; // n-1条边结束 35 | } 36 | } 37 | printf("%d\n", ans); 38 | } 39 | int main() { 40 | scanf("%d %d %d", &n, &m, &root); 41 | int u, v, d; 42 | while(m --) { 43 | scanf("%d %d %d", &u, &v, &d); 44 | edge.push(Edge(u, v, d)); 45 | } 46 | kruskal(); 47 | return 0; 48 | } -------------------------------------------------------------------------------- /CCF-CSP/CSP-Code/第4题/mycalc.y: -------------------------------------------------------------------------------- 1 | %{ 2 | #include 3 | #include 4 | #define YYDEBUG 1 5 | %} 6 | %union { 7 | int int_value; 8 | double double_value; 9 | } 10 | %token DOUBLE_LITERAL 11 | %token ADD SUB MUL DIV CR 12 | %type expression term primary_expression 13 | %% 14 | line_list 15 | : line 16 | | line_list line 17 | ; 18 | line 19 | : expression CR 20 | { 21 | printf(">>%lf\n", $1); 22 | } 23 | expression 24 | : term 25 | | expression ADD term 26 | { 27 | $$ = $1 + $3; 28 | } 29 | | expression SUB term 30 | { 31 | $$ = $1 - $3; 32 | } 33 | ; 34 | term 35 | : primary_expression 36 | | term MUL primary_expression 37 | { 38 | $$ = $1 * $3; 39 | } 40 | | term DIV primary_expression 41 | { 42 | $$ = $1 / $3; 43 | } 44 | ; 45 | primary_expression 46 | : DOUBLE_LITERAL 47 | ; 48 | %% 49 | int 50 | yyerror(char const *str) 51 | { 52 | extern char *yytext; 53 | fprintf(stderr, "parser error near %s\n", yytext); 54 | return 0; 55 | } 56 | 57 | int main(void) 58 | { 59 | extern int yyparse(void); 60 | extern FILE *yyin; 61 | 62 | yyin = stdin; 63 | if (yyparse()) { 64 | fprintf(stderr, "Error ! Error ! Error !\n"); 65 | exit(1); 66 | } 67 | } -------------------------------------------------------------------------------- /CCF-CSP/CSP-Code/第4题/test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int main() { 4 | map mp; 5 | mp.insert({1,10}); 6 | for (auto _mp : mp) { 7 | printf("%d %d\n", _mp.first, _mp.second); 8 | } 9 | return 0; 10 | } -------------------------------------------------------------------------------- /CCF-CSP/CSP-Note/CSP第3题总结.md: -------------------------------------------------------------------------------- 1 | # CSP第3题总结 2 | 3 | 字符串处理涉及的技术较多,其余四种题型,只要灵活运用合适容器和基本的字符串处理即可。 4 | 5 | ## 字符串处理 6 | 7 | string类丰富的字符串处理函数与正则表达式是字符串处理的基础,前者效率高,后者使用简单,通常将二者结合使用,发挥各自优点。 8 | 9 | ### 实例 10 | 11 | - 201812-3 CIDR合并(算法给定) 12 | - 201809-3 元素选择器(栈模拟建树) 13 | - 201803-3 URL映射(正则) 14 | - 201709-3 JSON查询(栈模拟建树) 15 | - 201703-3 Markdown(正则) 16 | - 201604-3 路径解析(栈模拟) 17 | - 201509-3 模板生成系统(正则/find) 18 | - 201409-3 字符串匹配(正则/find) 19 | - 201403-3 命令行选项(分割匹配) 20 | 21 | ### 技术 22 | 23 | - string类 24 | 25 | - 分割 26 | 27 | - stringstream 28 | - find+substr 29 | 30 | - 查找(字符/字符串) 31 | 32 | - find 33 | 34 | - 类型转换 35 | 36 | - stox 37 | 38 | - stoi(int) 39 | - stod(double) 40 | - stoll(longlong) 41 | 42 | - sscanf/sprintf(先转为char*) 43 | 44 | - 正则表达式 45 | 46 | - 全文匹配regex_macth 47 | - 子串搜索regex_search 48 | - 子串替换regex_replace 49 | 50 | - 栈模拟建树 51 | 52 | - vector模拟 53 | - stack 54 | 55 | - STL运用 56 | - 字符串读写 57 | 58 | - fgets/fputs最快 59 | 60 | ## 图形模拟 61 | 62 | ### 201903-3 损坏的RAID5(二维数组) 63 | 64 | ### 201512-3 画图(二维数组+BFS) 65 | 66 | ## 流程模拟 67 | 68 | ### 201612-3 权限查询(unordered_map嵌套) 69 | 70 | ### 201609-3 炉石传说(游戏规则) 71 | 72 | ## 日期处理 73 | 74 | ### 201712-3 Crontab(星期推算+构造验证) 75 | 76 | ### 201503-3 节日(星期推算) 77 | 78 | ## 数学规律 79 | 80 | ### 201412-3 集合竞价(买单选定价) 81 | 82 | ### 201312-3 最大的矩形(暴力枚举) 83 | 84 | *XMind: ZEN - Trial Version* 85 | 86 | -------------------------------------------------------------------------------- /CCF-CSP/README.md: -------------------------------------------------------------------------------- 1 | # CCF-CSP历年真题--题解目录 2 | 3 | > [个人博客](https://wyjoutstanding.github.io/) 4 | > 5 | > [github](https://github.com/wyjoutstanding?tab=repositories) 6 | > 7 | > [CSDN博客](https://blog.csdn.net/qq_40738840) 8 | 9 | ### 目录结构 10 | 11 | + code:历年题目源码(包括优化后的代码) 12 | + note:历年题目的分析笔记,题型总结归纳 13 | 14 | --- 15 | 16 | 主要包括1-4题,按照题号分类,分别总结1-4题的常见题型、解决思路和易错点,其中1,2为简答题,3,4比较难,主要涉及图论,复杂字符串处理,复杂模拟 17 | 18 | 每类题按照年份排列,难度基本呈逐年增加趋势 19 | 20 | 题目略有难度,34题可做为考研,保研提升训练阶段 21 | 22 | 欢迎指教、star~ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 算法训练题解系列 2 | 3 | [个人博客](https://wyjoutstanding.github.io/) 4 | 5 | [github](https://github.com/wyjoutstanding?tab=repositories) 6 | 7 | [CSDN博客](https://blog.csdn.net/qq_40738840) 8 | 9 | ## 目录结构 10 | 11 | ``` 12 | AlgorithmNote:《算法笔记上机训练实战指南》题解(代码和分析笔记)--初级训练 13 | CCF-CSP: CSP历年真题分类题解系列 --中级训练 14 | aoapc-uva: 《算法竞赛入门经典第2版》题解系列 --中高级训练 15 | ``` 16 | 17 | -------------------------------------------------------------------------------- /aoapc_uva/README.md: -------------------------------------------------------------------------------- 1 | # 《算法竞赛入门经典第2版》题解目录 2 | 3 | > [个人博客](https://wyjoutstanding.github.io/) 4 | > 5 | > [github](https://github.com/wyjoutstanding?tab=repositories) 6 | > 7 | > [CSDN博客](https://blog.csdn.net/qq_40738840/article/details/104175021) 8 | 9 | ### 目录结构 10 | 11 | + code:所有例题,习题源码(包括优化后的代码) 12 | + note:所有例题,习题的分析笔记,题型总结归纳 13 | 14 | --- 15 | 16 | 按照章节划分题目,每个章节也是一个专题,可挑着看 17 | 18 | 题目比较略有难度,适合ACM,考研,保研,PAT,CCF-CSP机考中高级训练阶段 19 | 20 | 欢迎指教、star~ 21 | 22 | -------------------------------------------------------------------------------- /aoapc_uva/aoapc-code/ch03/UVa10082.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | string keyboard = "`1234567890-=QWERTYUIOP[]\\ASDFGHJKL;'ZXCVBNM,./", s; 4 | int main() { 5 | while(getline(cin, s) && !s.empty()) { 6 | for (char ch : s) { 7 | if (ch == ' ') printf(" "); 8 | else printf("%c", keyboard[keyboard.find(ch)-1]); 9 | } 10 | printf("\n"); // 换行记录 11 | } 12 | return 0; 13 | } -------------------------------------------------------------------------------- /aoapc_uva/aoapc-code/ch03/UVa10340-1.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | string s, t; 4 | int main() { 5 | while(cin >>s >>t) { 6 | int i = 0; 7 | for (auto ch : t) { // 以t为参照,依次比较 8 | if (ch == s[i]) i ++; 9 | } 10 | printf("%s\n", (i == s.size()) ? "Yes" : "No"); 11 | } 12 | return 0; 13 | } -------------------------------------------------------------------------------- /aoapc_uva/aoapc-code/ch03/UVa10340-2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | string s, t; 4 | int main() { 5 | while(cin >>s && cin >>t) { 6 | bool isSub = false; // 记录是否为子序列 7 | int i = 0, j = 0; // 双指针 8 | while (i < s.size() && j < t.size()) { // 以s为参照,遍历s,t 9 | if (s[i] == t[j]) { // 找到相等 10 | if (i == s.size() - 1) { 11 | isSub = true; 12 | break; 13 | } 14 | i ++; j ++; 15 | } 16 | while (j < t.size() && s[i] != t[j]) j ++; 17 | } 18 | printf("%s\n", isSub ? "Yes" : "No"); 19 | } 20 | return 0; 21 | } -------------------------------------------------------------------------------- /aoapc_uva/aoapc-code/ch03/UVa10340.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | map> mp; // 存储每个字符所在位置 4 | string s,t; 5 | int main() { 6 | while(cin>>s && cin >>t) { 7 | mp.clear(); // 初始化 8 | int dp[s.size()+1] = {1,0}; // dp计数 9 | for (int i = 0; i < s.size(); i ++) { // 统计每个字符所在位置,从1开始算 10 | if (mp.find(s[i]) == mp.end()) { // 未存在 11 | mp.insert({s[i], {i+1}}); 12 | } 13 | else mp[s[i]].push_back(i+1); // 已存在,存入 14 | } 15 | for (int i = 0; i < t.size(); i++) { // 遍历字符串t 16 | if (mp.find(t[i]) != mp.end()) { // 字符出现在s中 17 | for (int k = mp[t[i]].size() - 1; k >= 0; k --) { // 逆序遍历字符所在s中位置,滚动数组优化 18 | dp[mp[t[i]][k]] += dp[mp[t[i]][k]-1]; // dp[j]=dp[j]+dp[j-1] 19 | } 20 | } 21 | } 22 | printf("%s\n", dp[s.size()] == 0 ? "No" : "Yes"); // 最后一个为总序列个数 23 | } 24 | return 0; 25 | } -------------------------------------------------------------------------------- /aoapc_uva/aoapc-code/ch03/UVa11809.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | #define epison 1e-5 // 精度设置,1e-6也行 4 | #define log10_2 log10(2) 5 | double A, AP[11][31]; // A实际值,预测值 6 | long long B, BP[11][31]; // B实际值,预测值 7 | string s; 8 | void init() { // 打表,将所有可能的值记录下来 9 | for (int i = 0; i < 10; i ++) { 10 | for (int j = 1; j < 31; j ++) { 11 | double t = log10(1-pow(2,-i-1)) + (pow(2,j)-1)*log10_2; // 等式左侧:lg(1-(1/2)^(M+1)) + lg(2^(2^E-1)) 12 | BP[i][j] = t; // 取整数部分,也就是B的值 13 | AP[i][j] = pow(10, t-BP[i][j]); // A = 10^(t-B) 14 | } 15 | } 16 | } 17 | int main() { 18 | init(); 19 | while(cin >>s && s != "0e0") { 20 | s[s.find('e')] = ' '; // e替换为空格 21 | stringstream input(s); 22 | input >>A >>B; 23 | while(A < 1) A *= 10, B --; // 转换为科学计数法 24 | for (int i = 0; i < 10; i ++) { // 查表 25 | for (int j = 1; j < 31; j ++) { 26 | if (B == BP[i][j] && fabs(AP[i][j]-A) < epison) { 27 | printf("%d %d\n", i, j); 28 | } 29 | } 30 | } 31 | } 32 | return 0; 33 | } -------------------------------------------------------------------------------- /aoapc_uva/aoapc-code/ch03/UVa1225.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int num[10] = {0}; 4 | int main() { 5 | int T, n; 6 | string s; 7 | scanf("%d", &T); 8 | while(T --) { 9 | scanf("%d", &n); 10 | fill(num, num + 10, 0); 11 | for (int i = 1; i <= n; i ++) { 12 | s = to_string(i); 13 | for (auto ch : s) num[ch - '0'] ++; 14 | } 15 | for (int i = 0; i < 10; i ++) { 16 | printf("%d%s", num[i], (i == 9) ? "\n" : " "); 17 | } 18 | } 19 | return 0; 20 | } -------------------------------------------------------------------------------- /aoapc_uva/aoapc-code/ch03/UVa1368.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | map mp{{'A',0}, {'C',1}, {'G',2}, {'T',3}}; // 便于循环处理 4 | char itc[4] = {'A', 'C', 'G', 'T'}; // [0,4)->[A,C,G,T] 5 | int T, m, n, num[1010][4] = {0}; // ATGC出现次数 6 | string s; 7 | int main() { 8 | scanf("%d", &T); 9 | while(T --) { 10 | scanf("%d %d", &m, &n); 11 | fill(num[0], num[0] + 4040, 0); // 初始化二维数组 12 | for (int i = 0; i < m; i ++) { // 统计每一列中每个子符出现次数 13 | cin >>s; 14 | for (int j = 0; j < n; j ++) num[j][mp[s[j]]] ++; 15 | } 16 | int errNum = 0, idx = 0, MAX = -1; 17 | for (int i = 0; i < n; i ++) { // 遍历每一列 18 | idx = 0, MAX = -1; // 初始化 19 | for (int j = 0; j < 4; j ++) { // ACGT 20 | if (MAX < num[i][j]) { // 找最大值 21 | idx = j; 22 | MAX = num[i][j]; 23 | } 24 | } 25 | errNum += (m - MAX); // 不同的个数 26 | printf("%c", itc[idx]); 27 | } 28 | printf("\n%d\n", errNum); 29 | } 30 | return 0; 31 | } 32 | // 00251889168765743073047858942065491183879093198992 -------------------------------------------------------------------------------- /aoapc_uva/aoapc-code/ch03/UVa1583.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int T, n, len, sum = 0; 4 | string s; 5 | int main() { 6 | scanf("%d", &T); 7 | for (int i = 0; i < T; i ++) { 8 | scanf("%d", &n); 9 | len = to_string(n).size(); // n的位数,数位之和最大为9*len(n) 10 | for (int j = n - len*9; j <= n; j ++) { // 确定枚举范围[n-len*9, n] 11 | sum = j; 12 | s = to_string(j); 13 | for (auto ch : s) sum += (ch - '0'); // 数位之和累加 14 | if (sum == n) { 15 | printf("%d\n", j); 16 | break; 17 | } 18 | if (j == n) printf("0\n"); 19 | } 20 | } 21 | return 0; 22 | } -------------------------------------------------------------------------------- /aoapc_uva/aoapc-code/ch03/UVa1584.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int main() { 4 | string str, ans, s; 5 | int n; 6 | cin >>n; 7 | while(n --) { 8 | cin >>str; 9 | ans = str; 10 | for (int i = 1; i < str.size(); i ++) { // 遍历每一种情况,i表示开始下标 11 | s = str.substr(i) + str.substr(0, i); // 拼接循环字符串 12 | ans = min(ans, s); // 取小,string类对<重载 13 | } 14 | cout < 2 | using namespace std; 3 | int main() { 4 | int n, ans, cnt; 5 | string s; 6 | scanf("%d", &n); 7 | while(n --) { 8 | cin >>s; 9 | ans = cnt = 0; 10 | for (auto ch : s) { 11 | if (ch == 'X') cnt = 0; 12 | else { 13 | cnt ++; 14 | ans += cnt; 15 | } 16 | } 17 | printf("%d\n", ans); 18 | 19 | } 20 | return 0; 21 | } -------------------------------------------------------------------------------- /aoapc_uva/aoapc-code/ch03/UVa1586.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | map mp{{'C',0}, {'H',1}, {'O',2}, {'N',3}}; // 便于循环处理 4 | double mass[4] = {12.01, 1.008, 16.00, 14.01}, ans = 0; 5 | int n, num[4] = {0}; // 统计个数 6 | string str, s; 7 | char pre; // 记录有明确数量的前置符号 8 | int main() { 9 | scanf("%d", &n); 10 | while(n --) { 11 | cin >>str; 12 | fill(num, num+4, 0); // 初始化 13 | pre = str[0]; // 记录前一个元素 14 | int i = 0; 15 | while(i < str.size()) { 16 | s.clear(); 17 | while (i < str.size() && isdigit(str[i])) s += str[i++]; // 计算数值 18 | if (!s.empty()) { 19 | num[mp[pre]] += stoi(s); 20 | i --; // 数值计算多后移一位 21 | } 22 | else { 23 | if (i + 1 == str.size() || !isdigit(str[i+1])) { // 符号后无明确数值 24 | num[mp[str[i]]] += 1; 25 | } 26 | else pre = str[i]; 27 | } 28 | i ++; // 移动标签 29 | } 30 | ans = 0; 31 | for (int i = 0; i < 4; i ++) { // 计算结果 32 | ans += (double)num[i] * mass[i]; 33 | } 34 | printf("%.3lf\n", ans); 35 | } 36 | return 0; 37 | } -------------------------------------------------------------------------------- /aoapc_uva/aoapc-code/ch03/UVa1587.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | map, int> box; 4 | map edge; 5 | int a, b; 6 | int main() { 7 | while(cin >>a >> b) { 8 | bool isBox = false, flag = true, flag2 = true; 9 | box.clear(); edge.clear(); 10 | for (int i = 0; i < 6; i ++) { 11 | if (i != 0) cin >>a >>b; 12 | box[{a,b}] ++; 13 | edge[a] ++; 14 | edge[b] ++; 15 | } 16 | for (auto p : box) { // 每个面出现次数为2,4,6 17 | if (p.second % 2 != 0) { 18 | flag = false; break; 19 | } 20 | } 21 | for (auto p : edge) { // 每条边出现次数为4,8,12 22 | if (p.second % 4 != 0) { 23 | flag2 = false; break; 24 | } 25 | } 26 | if (flag && flag2) isBox = true; // 满足两个条件可构造长方体 27 | printf("%s\n", isBox ? "POSSIBLE" : "IMPOSSIBLE"); 28 | } 29 | return 0; 30 | } -------------------------------------------------------------------------------- /aoapc_uva/aoapc-code/ch03/UVa1588.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | string a, b; 4 | int getMin(string a, string b) { // 获取a和b最小的组合长度 5 | if (a.size() > b.size()) swap(a,b); // a为短者 6 | int MIN = a.size() + b.size(); 7 | for (int i = a.size(); i > 0; i --) { // a的长度;a在b左侧 8 | int j; 9 | for (j = 0; j < i; j ++) { 10 | if (a[a.size()-i+j] == '2' && b[j] == '2') break; 11 | } 12 | if (j == i) { // 找到第一个符合 13 | MIN -= i; 14 | break; 15 | } 16 | } 17 | for (int i = 0; i <= b.size()-a.size(); i ++) { // b的起始位置;a包含于b 18 | int j; 19 | for (j = 0; j < a.size(); j ++) { 20 | if (a[j] == '2' && b[i+j] == '2') break; 21 | } 22 | if (j == a.size()) { 23 | MIN = b.size(); 24 | break; 25 | } 26 | } 27 | for (int i = a.size()-1; i > 0; i --) { // a的长度;a在b右侧 28 | int j; 29 | for (j = 0; j < i; j ++) { 30 | if (a[j] == '2' && b[b.size()-i+j] == '2') break; 31 | } 32 | if (j == i) { 33 | MIN = min(MIN, (int)(a.size()+b.size()-i)); 34 | break; 35 | } 36 | } 37 | return MIN; 38 | } 39 | int main() { 40 | while(cin >>a >>b) { 41 | printf("%d\n", getMin(a,b)); 42 | } 43 | return 0; 44 | } -------------------------------------------------------------------------------- /aoapc_uva/aoapc-code/ch03/UVa202_right.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int a, b, begIdx=-1; 4 | string si, sd; 5 | int main() { 6 | while(cin >>a >>b) { 7 | vector> d; 8 | si = to_string(a / b); 9 | printf("%d/%d = %s.", a, b, si.c_str()); 10 | a = (a % b)*10; // 第一个必须舍弃 11 | begIdx = -1; 12 | while(begIdx == -1) { // 除法模拟 13 | d.push_back({a, a/b}); 14 | a = (a%b)*10; 15 | for (int i = 0; i < d.size(); i ++) { 16 | if (d[i].first == a) { 17 | begIdx = i; // 循环节开始 18 | break; 19 | } 20 | } 21 | } 22 | for (int i = 0; i < begIdx; i ++) printf("%d", d[i].second); 23 | printf("("); 24 | for (int i = begIdx; i < ((d.size() > 50) ? 50 : d.size()); i ++) printf("%d", d[i].second); 25 | printf("%s", d.size() > 50 ? "...)" : ")"); 26 | printf("\n %d = number of digits in repeating cycle\n\n", d.size()-begIdx); // 诡异输出,每个输出后均两个换行 27 | } 28 | return 0; 29 | } -------------------------------------------------------------------------------- /aoapc_uva/aoapc-code/ch03/UVa272.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int main() { 4 | char ch; 5 | int cnt = 0; // 控制左右括号 (:0 ):1 6 | while(scanf("%c", &ch) != EOF) { // 两种输入均可 7 | // while((ch = getchar()) != EOF) { 8 | if (ch == '"') { 9 | if (cnt == 0) { 10 | printf("``"); 11 | cnt = 1; 12 | } 13 | else { 14 | printf("''"); 15 | cnt = 0; 16 | } 17 | } 18 | else printf("%c", ch); 19 | } 20 | return 0; 21 | } -------------------------------------------------------------------------------- /aoapc_uva/aoapc-code/ch03/UVa272_opt1.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int main() { 4 | char ch; 5 | int cnt = 0; 6 | while(scanf("%c", &ch) != EOF) { // EOF = -1,不等于0 7 | if (ch == '"') { 8 | printf("%s", (cnt == 0) ? "``" : "''"); // ?:简洁代码 9 | cnt = !cnt; // 完成0和1转换 10 | } 11 | else printf("%c", ch); 12 | } 13 | return 0; 14 | } -------------------------------------------------------------------------------- /aoapc_uva/aoapc-code/ch03/UVa340.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int n, cnta = 0, cntb = 0, num = 0; 4 | vector l1(1010), l2(1010), vl1(10), vl2(10); 5 | int main() { 6 | while(scanf("%d", &n) == 1 && n != 0) { 7 | for (int i = 0; i < n; i ++) scanf("%d", &l1[i]); // 原答案序列 8 | printf("Game %d:\n", ++num); 9 | while (true) { 10 | for (int i = 0; i < n; i ++) scanf("%d", &l2[i]); // 猜测序列 11 | if (l2[0] == 0) break; // 读到0开头结束 12 | cnta = cntb = 0; // 初始化 13 | fill(vl1.begin(), vl1.end(), 0); 14 | fill(vl2.begin(), vl2.end(), 0); 15 | for (int i = 0; i < n; i ++) { // 第一次扫描 16 | if (l1[i] == l2[i]) cnta ++; // 统计同位置个数 17 | else { // 非同位置出现次数,哈希表实现 18 | vl1[l1[i]] ++; 19 | vl2[l2[i]] ++; 20 | } 21 | } 22 | for (int i = 0; i < 10; i ++) { // 非同位置取小者 23 | cntb += min(vl1[i], vl2[i]); 24 | } 25 | printf(" (%d,%d)\n", cnta, cntb); // 4个空格/Tab 26 | } 27 | } 28 | return 0; 29 | } -------------------------------------------------------------------------------- /aoapc_uva/aoapc-code/ch03/UVa401.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | string rev = "A 3 HIL JM O 2TUVWXY51SE Z 8 ", s; // 镜像哈希串 4 | char *msg[] = {" -- is not a palindrome.", " -- is a regular palindrome.", " -- is a mirrored string.", " -- is a mirrored palindrome."}; 5 | char toRev(char ch) { 6 | if (isalpha(ch)) return rev[ch - 'A']; 7 | else return rev[ch - '1' + 26]; 8 | } 9 | int main() { 10 | int p, m; 11 | while(getline(cin, s) && !s.empty()) { 12 | p = 1; m = 1; // 分别表示回文和镜像串 13 | for (int i = 0; i <= s.size() / 2; i ++) { 14 | if (s[i] != s[s.size() - i - 1]) p = 0; // 回文判断 15 | if (toRev(s[i]) != s[s.size() - i -1]) m = 0; // 镜像为空直接不符合!!! 16 | } 17 | printf("%s%s\n\n", s.c_str(), msg[m*2+p]); // 多一个空行!!! 18 | } 19 | return 0; 20 | } -------------------------------------------------------------------------------- /aoapc_uva/aoapc-code/ch03/UVa455.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int n, ans; 4 | bool flag = true, flag2 = false; 5 | string s; 6 | int main() { 7 | scanf("%d", &n); 8 | getchar(); 9 | while(n --) { 10 | cin >>s; 11 | ans = s.size(); // 默认结果 12 | flag2 = false; 13 | for (int i = 1; i <= s.size() / 2; i ++) { // 枚举所有可能长度 14 | if (s.size() % i == 0) { 15 | flag = true; 16 | for (int j = i; j <= s.size() - i; j += i) { // 比较长度为i的所有子串是否相同 17 | if (s.substr(0, i) != s.substr(j, i)) { 18 | flag = false; 19 | break; 20 | } 21 | } 22 | if (flag) { // 找到符合的周期串长度 23 | ans = i; 24 | flag2 = true; 25 | } 26 | } 27 | if (flag2) break; 28 | } 29 | printf("%d%s", ans, (n == 0) ? "\n" : "\n\n"); // 相邻两个输出间需输出空行,最后一行不用 30 | } 31 | return 0; 32 | } -------------------------------------------------------------------------------- /aoapc_uva/aoapc-code/ch03/data.txt: -------------------------------------------------------------------------------- 1 | 1345 2584 2 | 2584 683 3 | 2584 1345 4 | 683 1345 5 | 683 1345 6 | 2584 683 7 | 1234 4567 8 | 1234 4567 9 | 4567 4321 10 | 4322 4567 11 | 4321 1234 12 | 4321 1234 13 | 1 1 14 | 1 1 15 | 1 1 16 | 1 1 17 | 1 1 18 | 1 1 19 | 1 2 20 | 2 1 21 | 1 2 22 | 2 1 23 | 2 2 24 | 2 2 25 | 1 2 26 | 2 1 27 | 1 2 28 | 2 1 29 | 1 1 30 | 1 1 31 | 1 2 32 | 2 1 33 | 1 2 34 | 2 1 35 | 1 2 36 | 1 1 37 | 1 2 38 | 2 1 39 | 3 2 40 | 2 3 41 | 1 2 42 | 1 1 43 | 1 2 44 | 2 1 45 | 3 2 46 | 2 3 47 | 1 3 48 | 1 3 49 | 1 2 50 | 2 1 51 | 3 2 52 | 2 3 53 | 1 2 54 | 1 3 55 | 56 | -------------------------------------------------------------------------------- /aoapc_uva/aoapc-code/ch03/pdata.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int main() { 4 | srand(time(0)); 5 | for (int j = 0; j < 0x3fff; j ++) { 6 | for (int i = 0; i < 6; i ++) { 7 | printf("%d %d\n", rand() % 10000, rand() % 10000); 8 | } 9 | } 10 | return 0; 11 | } -------------------------------------------------------------------------------- /aoapc_uva/aoapc-code/ch03/run.bat: -------------------------------------------------------------------------------- 1 | test.exe > out.txt -------------------------------------------------------------------------------- /aoapc_uva/aoapc-code/ch03/run1587.bat: -------------------------------------------------------------------------------- 1 | :again 2 | pdata > data2.txt 3 | UVa1587_fc.exe < data2.txt > outfc.txt 4 | UVa1587.exe < data2.txt > out.txt 5 | fc outfc.txt out.txt 6 | if not errorlevel 1 goto again -------------------------------------------------------------------------------- /aoapc_uva/aoapc-code/ch04/UVA12108.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int n, a, b, c, num=0; 4 | int main() { 5 | while (cin >>n && n != 0) { 6 | set > _set; // 死循环判重 7 | vector stat, tmp, as, bs; // 当前状态,中间变量,清醒持续时间,睡眠持续时间 8 | for (int i = 0; i < n; i ++) { 9 | cin >>a >>b >>c; 10 | as.push_back(a); bs.push_back(b); // 存储左右区间 11 | stat.push_back(c); // 第一轮状态 12 | _set.insert(stat); // 保存状态序列 13 | } 14 | int cnt = 1, ans = -1; 15 | while (true) { 16 | int wknum = 0; // 清醒人数 17 | for (int i = 0; i < n; i ++) { // 计算清醒人数 18 | if (1 <= stat[i] && stat[i] <= as[i]) wknum ++; 19 | } 20 | if (wknum == n) { // 全部清醒 21 | ans = cnt; 22 | break; // 直接结束 23 | } 24 | cnt ++; 25 | tmp = stat; // 开始模拟 26 | for (int i = 0; i < n; i ++) { // n个人 27 | if (tmp[i] == as[i]) { // 准备睡觉 28 | if (wknum * 2 < n) stat[i] = as[i]+1; // 睡觉人数大于清醒 29 | else stat[i] = 1; // 继续清醒 30 | } 31 | else stat[i] = (stat[i] == as[i]+bs[i]) ? 1 : stat[i]+1; // 下一个状态 32 | } 33 | if (_set.find(stat) == _set.end()) _set.insert(stat); 34 | else break; // 出现重复,死循环 35 | } 36 | printf("Case %d: %d\n", ++num, ans); 37 | } 38 | return 0; 39 | } -------------------------------------------------------------------------------- /aoapc_uva/aoapc-code/ch04/UVA133.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int n, k, m; 4 | int main() { 5 | while(scanf("%d %d %d", &n, &k, &m) == 3 && n != 0) { 6 | vector a(n); 7 | int ki=0, mi = n-1, cnt = 0, cntk=0, cntm=0; 8 | while(cnt < n) { 9 | while (true) { 10 | if (a[ki] != -1) cntk ++; // 统计数过的人 11 | if (cntk == k) break; 12 | ki = (ki+1) % n; // 逆时针 13 | } 14 | while (true) { 15 | if (a[mi] != -1) cntm ++; 16 | if (cntm == m) break; 17 | mi = (mi+(n-1)) % n; // 顺时针,用加替代减 18 | } 19 | if (ki == mi) { // 指向同一个人 20 | a[ki] = -1; 21 | cnt ++; // 计算死亡人数,控制循环和末尾, 22 | printf("%3d%s", ki+1, cnt == n ? "" : ","); // 对齐宽度3!!! 23 | } 24 | else { // 指向不同人 25 | a[ki] = -1; a[mi] = -1; 26 | cnt += 2; 27 | printf("%3d%3d%s", ki+1, mi+1, cnt == n ? "" : ","); 28 | } 29 | cntk = cntm = 0; 30 | } 31 | printf("\n"); // 别漏 32 | } 33 | return 0; 34 | } -------------------------------------------------------------------------------- /aoapc_uva/aoapc-code/ch04/UVA1339.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int main() { 4 | string sa, sb; 5 | vector cnta(26), cntb(26); // 统计个数 6 | while(cin >>sa >>sb) { 7 | fill(cnta.begin(), cnta.end(), 0); // 初始化 8 | fill(cntb.begin(), cntb.end(), 0); 9 | for (auto ch : sa) cnta[ch-'A'] ++; // 统计字符出现次数 10 | for (auto ch : sb) cntb[ch-'A'] ++; 11 | sort(cnta.begin(), cnta.end()); // 排序 12 | sort(cntb.begin(), cntb.end()); 13 | printf("%s\n", (cnta == cntb) ? "YES" : "NO"); 14 | } 15 | return 0; 16 | } -------------------------------------------------------------------------------- /aoapc_uva/aoapc-code/ch04/UVA1590.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | void binstrToIP(string s) { // 二进制字符串转为IP形式 4 | for (int i = 0; i < 4; i ++) { 5 | bitset<8> bt(s.substr(i*8,8)); 6 | printf("%u%s", bt.to_ulong(), i == 3 ? "\n" : "."); 7 | } 8 | } 9 | int main() { 10 | int n; 11 | while (cin >>n) { 12 | string smax, smin, smask, s, st; 13 | unsigned umin=UINT32_MAX, umax = 0; 14 | while (n --) { 15 | cin >>s; 16 | stringstream input(s); 17 | unsigned uint = 0; 18 | while (getline(input, st, '.')) { // 分割每个部分 19 | uint = (uint << 8) + (unsigned)stoi(st); // 256进制 20 | } 21 | if (umin >= uint) umin = uint, smin = s; // 最小值 22 | if (umax <= uint) umax = uint, smax = s; // 最大值 23 | } 24 | bitset<32> bmin(umin), bmax(umax), bmask(0xffffffffu); 25 | smin = bmin.to_string(); smax = bmax.to_string(); // 转为2进制字符串 26 | int cnt = 0; 27 | for (int i = 0; i < 32; i ++) { // 统计从头开始的公共子串长度 28 | if (smin[i] == smax[i]) cnt ++; 29 | else break; 30 | } 31 | for (int i = 0; i < 32-cnt; i ++) { // 设置IP地址和掩码低32-cnt位为0 32 | bmin.reset(i); bmask.reset(i); // 注意bitset逆序存储 33 | } 34 | binstrToIP(bmin.to_string()); binstrToIP(bmask.to_string()); 35 | } 36 | return 0; 37 | } -------------------------------------------------------------------------------- /aoapc_uva/aoapc-code/ch04/UVA1591-2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | typedef long long LL; // 避免移位溢出 4 | int main() { 5 | LL n, Sp, Sq; 6 | while (cin >>n >>Sp >>Sq) { 7 | LL K=LONG_LONG_MAX, A, B; 8 | for (int i = 0; i < 32; i ++) { // A 9 | for (int j = 0; j < 32; j ++) { // B 10 | if (((Sp + (Sp << i)) >= (Sq << j)) && (K > ((Sp*(n-1)+((Sp*(n-1))<>j)+Sq)) { // 公差大于Sq且k更大 11 | K = ((Sp*(n-1)+((Sp*(n-1))<>j)+Sq; // 更新KAB 12 | A = i; B = j; 13 | } 14 | } 15 | } 16 | printf("%lld %lld %lld\n", K, A, B); // 第一个即符合条件 17 | } 18 | return 0; 19 | } -------------------------------------------------------------------------------- /aoapc_uva/aoapc-code/ch04/UVA1591.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | typedef long long LL; // 避免移位溢出 4 | typedef struct KAB { 5 | LL K, A, B; 6 | KAB(LL _k, LL _A, LL _B) : K(_k), A(_A), B(_B){} // 默认构造 7 | }KAB; 8 | bool cmp(const KAB& a, const KAB& b) { // 按KAB顺序取字典序小者 9 | if (a.K != b.K) return a.K < b.K; // 取K小 10 | else if (a.A != b.A) return a.A < b.A; // 取A小 11 | else return a.B < b.B; // 取B小 12 | } 13 | LL n, Sp, Sq; 14 | int main() { 15 | while (cin >>n >>Sp >>Sq) { 16 | vector kab; // 存储所有可能值 17 | for (int i = 0; i < 32; i ++) { // A 18 | for (int j = 0; j < 32; j ++) { // B 19 | if ((Sp + (Sp << i)) >= (Sq << j)) { // 公差大于Sq 20 | kab.push_back({((Sp*(n-1)+((Sp*(n-1))<>j)+Sq, i, j}); // 移位优先级低于=-*/ 21 | } 22 | } 23 | } 24 | sort(kab.begin(), kab.end(), cmp); // 排序 25 | printf("%lld %lld %lld\n", kab[0].K, kab[0].A, kab[0].B); // 第一个即符合条件 26 | } 27 | return 0; 28 | } -------------------------------------------------------------------------------- /aoapc_uva/aoapc-code/ch04/UVA201.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int n, m, cnt = 0, a, b; 4 | char ch; 5 | int main() { 6 | while (cin >>n >>m) { 7 | int h[10][10]={0}, v[10][10]={0}; // 存储水平和垂直连线 8 | while (m --) { // 输入 9 | cin >>ch >>a >>b; 10 | if (ch == 'H') h[a][b] = b+1; 11 | else v[b][a] = b+1; // 注意顺序 12 | } 13 | int right[10][10]={0}, down[10][10]={0}, num[10]={0}; // 向右/下最远可达距离,每种长度正方形计数 14 | for (int i = 1; i <= n; i ++) { // 每一行列 15 | for (int j = n-1; j >= 1; j --) { 16 | right[i][j] = (h[i][j] == j+1) ? right[i][j+1]+1 : 0; // 行:左->右 17 | down[j][i] = (v[j][i] == j+1) ? down[j+1][i]+1 : 0; // 列:上->下 18 | } 19 | } 20 | for (int l = 1; l <= n; l ++) { // 遍历每个正方形长度:l:[1,n] 21 | for (int i = 1; i <= n - l; i ++) { // x:[1,n-l] 22 | for (int j = 1; j <= n - l; j ++) { // y:[1,n-l] 23 | if (right[i][j] >= l && down[i][j] >= l && down[i][j+l] >= l && right[i+l][j] >= l) num[l] ++, num[0] = 1; // num[0]标记存在解 24 | } 25 | } 26 | } 27 | if (cnt != 0) printf("\n**********************************\n\n"); // 以下为输出 28 | printf("Problem #%d\n\n", ++cnt); 29 | for (int i = 1; i <= n; i ++) 30 | if (num[i] != 0) printf("%d square (s) of size %d\n", num[i], i); 31 | if (num[0] == 0) printf("No completed squares can be found.\n"); 32 | } 33 | return 0; 34 | } -------------------------------------------------------------------------------- /aoapc_uva/aoapc-code/ch04/UVA253.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int a[3][4] = {{2,4,5,3}, {2,6,5,1}, {1,4,6,3}}; // 3个旋转轴对应改变的轮换序列 4 | string sa, sb, st; 5 | void rotate(string& sr, int i, int j) { // sr绕i轴旋转j*90度 6 | string s = sr; 7 | for (int k = 0; k <= 3; k ++) { // 轮换:模拟旋转 8 | sr[a[i][k]-1] = s[a[i][(j+k)%4]-1]; // 从0开始存储,正方体标号从1开始 9 | } 10 | } 11 | int main() { 12 | while (cin >>st) { 13 | sa = st.substr(0,6); sb = st.substr(6); 14 | bool isSame = false; // 判断是否存在一样的情况 15 | for (int i = 0; i < 4 && !isSame; i ++) { // x轴4种转动角度 16 | for (int j = 0; j < 4 && !isSame; j ++) { // y轴 17 | for (int k = 0; k < 4 && !isSame; k ++) { // z轴 18 | st = sb; // 更新 19 | rotate(st, 0, i); // x轴转i*90角度 20 | rotate(st, 1, j); // y轴转j*90角度 21 | rotate(st, 2, k); // z轴转k*90角度 22 | if (st == sa) isSame = true; 23 | } 24 | } 25 | } 26 | printf("%s\n", isSame ? "TRUE" : "FALSE"); 27 | } 28 | return 0; 29 | } -------------------------------------------------------------------------------- /aoapc_uva/aoapc-code/ch04/UVA489.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | set ans, hit; // 答案序列,命中序列 4 | string a,b; 5 | int id, cnt; // round,错误次数 6 | int main() { 7 | while (scanf("%d", &id) && id != -1) { 8 | cin >>a >>b; 9 | ans.clear(); hit.clear(); cnt = 0; // 初始化 10 | for (auto ch : a) ans.insert(ch); 11 | for (auto ch : b) { // 遍历猜测序列 12 | if (cnt == 7 || ans.size() == hit.size()) break; // 错误7次|完全猜中 13 | if (ans.find(ch) != ans.end()) hit.insert(ch); // 猜中 14 | else cnt ++; // 未猜中 15 | } 16 | printf("Round %d\n", id); 17 | if (cnt == 7) printf("You lose.\n"); 18 | else if (ans.size() == hit.size()) printf("You win.\n"); 19 | else printf("You chickened out.\n"); 20 | } 21 | return 0; 22 | } -------------------------------------------------------------------------------- /aoapc_uva/aoapc-code/ch04/UVA508.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | string codetbl[200], code, s; 4 | char ch; 5 | // map > ctxt; // 上下文,字典序排列 6 | map > ctxt; // 上下文,输入顺序排列 7 | int main() { 8 | while (cin >>ch && ch != '*') { 9 | cin >>code; codetbl[ch] = code; 10 | } 11 | while (cin >>s && s != "*") { 12 | string st; 13 | for (auto c : s) st += codetbl[c]; 14 | // ctxt[st].insert(s); // 字典序排列 15 | ctxt[st].push_back(s); 16 | } 17 | while (cin >>s && s != "*") { 18 | if (ctxt.find(s) != ctxt.end()) { // 存在 19 | cout <<*ctxt[s].begin(); 20 | if (ctxt[s].size() > 1) cout <<"!"; 21 | } 22 | else { // 不存在 23 | int minlen = 0x3ffff; string ans; 24 | for (auto p : ctxt) { 25 | if (s == p.first.substr(0,s.size()) || p.first == s.substr(0,p.first.size())) { // 前缀 26 | int i = abs((long)p.first.size()-(long)s.size()); 27 | if (minlen >= i) { 28 | minlen = i; 29 | ans = *p.second.begin(); 30 | } 31 | } 32 | } 33 | cout < 2 | using namespace std; 3 | int m, n, cubic, num = 0; 4 | int main() { 5 | while (cin >>m >>n && m != 0) { 6 | vector a(m*n+2); a[m*n+1] = 0x7ffff; // 太大会溢出 7 | for (int i = 1; i <= m*n; i ++) cin >>a[i]; 8 | cin >>cubic; // 体积 9 | sort(a.begin()+1, a.end()); // 从小到大排序 10 | for (int i = 2; i <= m*n; i ++) a[i] += a[i-1]; // a[i]表示前i个长度和 11 | double ans1, ans2; 12 | for (int i = 1; i <= m*n; i ++) { 13 | if (((i+1)*(a[i+1]-a[i]) - a[i+1])*100 >= cubic) { // 必须用乘法,除法会产生误差 14 | ans1 = (double)(cubic + a[i]*100) / (i*100); // 高度,先乘后除 15 | ans2 = (double)i / (m*n); // 百分比 16 | break; 17 | } 18 | } 19 | printf("Region %d\nWater level is %.2lf meters.\n", ++num, round(ans1*100)/100); 20 | printf("%.2lf percent of the region is under water.\n\n", round(ans2*10000)/100); 21 | } 22 | return 0; 23 | } -------------------------------------------------------------------------------- /aoapc_uva/aoapc-code/ch05/UVA10391.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | string s; 4 | set _set; // 查询 5 | int main() { 6 | while (cin >>s) _set.insert(s); 7 | for (auto p : _set) { 8 | bool isCpdword = false; 9 | for (int i = 0; i < p.size()-1 && !isCpdword; i ++) { // 遍历所有左右组合 10 | if (_set.find(p.substr(0,i+1)) != _set.end() && _set.find(p.substr(i+1)) != _set.end()) // 左右字符串均存在 11 | isCpdword = true; 12 | } 13 | if(isCpdword) printf("%s\n", p.c_str()); 14 | } 15 | return 0; 16 | } -------------------------------------------------------------------------------- /aoapc_uva/aoapc-code/ch05/UVA10474.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int n, m, a[100010], q, *p, num=0; 4 | int main() { 5 | while (cin >>n >>m && (n != 0 && m != 0)) { 6 | for (int i = 0; i < n; i ++) cin >>a[i]; 7 | sort(a, a+n); // 升序排列 8 | printf("CASE# %d:\n", ++num); 9 | while (m --) { 10 | cin >>q; 11 | p = lower_bound(a, a+n, q); // 找到>=q的第一个数 12 | if (p - a != n && *p == q) printf("%d found at %d\n", q, p-a+1); // 存在且为q 13 | else printf("%d not found\n", q); 14 | } 15 | } 16 | return 0; 17 | } -------------------------------------------------------------------------------- /aoapc_uva/aoapc-code/ch05/UVA10763.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int n, a, b; 4 | int main() { 5 | while (cin >>n && n != 0) { 6 | map cnt; // 每个学校对应的人数增减变化量 7 | for (int i = 0; i < n; i ++) { 8 | scanf("%d %d", &a, &b); 9 | cnt[a] --; // 出去- 10 | cnt[b] ++; // 进来+ 11 | } 12 | bool isWork = true; // 标记是否可行 13 | for (auto p : cnt) { 14 | if (p.second != 0) { // 出现非0,说明有人不匹配 15 | isWork = false; 16 | break; 17 | } 18 | } 19 | printf("%s\n", isWork ? "YES" : "NO"); 20 | } 21 | return 0; 22 | } -------------------------------------------------------------------------------- /aoapc_uva/aoapc-code/ch05/UVA10815.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | string text, s; 4 | set dict; // 词典 5 | int main() { 6 | while (getline(cin, s)) { 7 | for (auto& ch : s) { 8 | if (isalpha(ch)) ch = tolower(ch); // 替换小写 9 | else ch = ' '; // 替换空格 10 | } 11 | text += " "+s; // 拼接文本,注意空格,避免两行尾首直接相连 12 | } 13 | stringstream input(text); // 按空格分割 14 | while (input >>s) dict.insert(s); // 插入去重 15 | for (auto p : dict) cout <

2 | using namespace std; 3 | int n; 4 | int main() { 5 | while (cin >>n && n != 0) { 6 | printf("Discarded cards:"); 7 | queue q; 8 | for (int i = 1; i <= n; i ++) q.push(i); 9 | while (q.size() != 1) { 10 | printf("%s%d", q.front() == 1 ? " " : ", ", q.front()); // 第一个退出无输出, 11 | q.pop(); 12 | q.push(q.front()); q.pop(); // 头入队后删除 13 | } 14 | printf("\nRemaining card: %d\n", q.front()); 15 | } 16 | return 0; 17 | } -------------------------------------------------------------------------------- /aoapc_uva/aoapc-code/ch05/UVA12096.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | vector > setCache; // 哈希表:集合id->集合 4 | map, int> setToId; // 映射:集合->id 5 | int T, n; 6 | string cmd; 7 | int getSetId(const set& _set) { // 获取set对应id,不存在则新分配一个 8 | if (setToId.find(_set) != setToId.end()) return setToId[_set]; // 存在 9 | setCache.push_back(_set); // 不存在则分配 10 | return setToId[_set] = setCache.size() - 1; // id/位置标号 11 | } 12 | int main() { 13 | cin >>T; 14 | while (T --) { 15 | cin >>n; 16 | stack stk; setCache.clear(); setToId.clear(); // 初始化 17 | while (n --) { 18 | cin >>cmd; 19 | if (cmd == "PUSH") stk.push(getSetId(set())); // 空 20 | else if (cmd == "DUP") stk.push(stk.top()); // 重复 21 | else { 22 | set t, a, b; 23 | a = setCache[stk.top()]; stk.pop(); 24 | b = setCache[stk.top()]; stk.pop(); 25 | if (cmd == "UNION") set_union(a.begin(),a.end(),b.begin(),b.end(),inserter(t,t.begin())); 26 | if (cmd == "INTERSECT") set_intersection(a.begin(),a.end(),b.begin(),b.end(),inserter(t,t.begin())); 27 | if (cmd == "ADD") t = b, t.insert(setToId[a]); 28 | stk.push(getSetId(t)); 29 | } 30 | printf("%d\n", setCache[stk.top()].size()); 31 | } 32 | puts("***"); 33 | } 34 | return 0; 35 | } -------------------------------------------------------------------------------- /aoapc_uva/aoapc-code/ch05/UVA12100.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | struct Job { 4 | int pos, pty; // 位置,优先级 5 | }job; 6 | int T, n, m; 7 | int main() { 8 | scanf("%d", &T); 9 | while (T --) { 10 | scanf("%d %d", &n, &m); 11 | queue q; 12 | map mp; // 每个优先级对应的人数 13 | for (int i = 0; i < n; i ++) { 14 | scanf("%d", &job.pty); 15 | job.pos = i; // 位置,0开始 16 | q.push(job); 17 | mp[job.pty] ++; // 计算该优先级人数 18 | } 19 | int num = 0; 20 | while (!q.empty()) { 21 | if (q.front().pty < mp.rbegin()->first) q.push(q.front()), q.pop(); // 有优先级高者,后移 22 | else if (q.front().pos == m) break; // 目标位置可输出 23 | else { // 非目标位置 24 | if (mp[q.front().pty] == 1) mp.erase(q.front().pty); // 维护mp 25 | else mp[q.front().pty] --; 26 | q.pop(); num ++; 27 | } 28 | } 29 | printf("%d\n", num+1); 30 | } 31 | return 0; 32 | } -------------------------------------------------------------------------------- /aoapc_uva/aoapc-code/ch05/UVA12504.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int T; 4 | string sa, sb; 5 | void getDict(map& mp, string s) { // 分割得到字典 6 | for (auto& ch : s) // 将{},:替换为空格 7 | if (ch == '{' || ch == '}' || ch == ',' || ch == ':') ch = ' '; 8 | stringstream input(s); 9 | string sk, sv; 10 | while (input >>sk >>sv ) mp[sk] = sv; // stringstream以空格分割 11 | } 12 | void print(char mess, const set& _set) { // 打印结果 13 | if (_set.empty()) return; // 空立刻返回 14 | cout <>T; 19 | for (int i = 0; i < T; i ++) { 20 | cin >>sa >>sb; 21 | map mpa, mpb; // 旧新字典 22 | getDict(mpa, sa); getDict(mpb, sb); 23 | set del, chg, inc; // 删除,改变,增加 24 | for (auto p : mpa) { // 遍历旧字典 25 | if (mpb.find(p.first) == mpb.end()) del.insert(p.first); // 删除 26 | else { // 存在 27 | if (mpa[p.first] != mpb[p.first]) chg.insert(p.first); // 改变 28 | mpb.erase(p.first); // 删除mpa中存在的 29 | } 30 | } 31 | for (auto p : mpb) inc.insert(p.first); // 未被删除的就是增加的 32 | print('+', inc); print('-', del); print('*', chg); // 输出结果 33 | if (inc.empty() && del.empty() && chg.empty()) puts("No changes"); 34 | puts(""); // 空行 35 | } 36 | return 0; 37 | } -------------------------------------------------------------------------------- /aoapc_uva/aoapc-code/ch05/UVA136.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | typedef long long LL; 4 | int main() { 5 | LL a[3] = {2,3,5}, t, num=0; 6 | priority_queue, greater > pq; // 优先队列 7 | set _set; // 判重 8 | pq.push(1L); _set.insert(1L); // 第一轮 9 | while (true) { 10 | t = pq.top(); pq.pop(); num ++; 11 | if (num == 1500) break; 12 | for (int i = 0; i < 3; i ++) // x,2x,3x,5x构造丑数 13 | if (_set.find(t*a[i]) == _set.end()) { 14 | pq.push(t*a[i]); 15 | _set.insert(t*a[i]); 16 | } 17 | } 18 | printf("The 1500'th ugly number is %lld.\n", t); 19 | return 0; 20 | } -------------------------------------------------------------------------------- /aoapc_uva/aoapc-code/ch05/UVA1539.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | string s, st; 4 | vector lines[1010]; // 每一行的单词 5 | int row=0, maxcol[1010] = {0}; // 行号,每列单词最长值 6 | int main() { 7 | while (getline(cin ,s)) { 8 | stringstream input(s); 9 | while (input >>st) { // 空格分割 10 | maxcol[lines[row].size()] = max(maxcol[lines[row].size()], (int)st.size()); // 取最大值 11 | lines[row].push_back(st); // 保存单词 12 | } 13 | row ++; // 行号 14 | } 15 | for (int i = 0; i < row; i ++) { // 按行遍历输出 16 | for (int j = 0; j < lines[i].size(); j ++) { 17 | st = lines[i][j]; 18 | if (j != lines[i].size()-1) st += string(maxcol[j]-st.size()+1, ' '); // 补空格 19 | printf("%s", st.c_str()); 20 | } 21 | puts(""); 22 | } 23 | return 0; 24 | } -------------------------------------------------------------------------------- /aoapc_uva/aoapc-code/ch05/UVA156-2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | map dict; // 标准化单词->出现次数 4 | map trans; // 单词字母出现次数->原单词 5 | set ans; // 存储输出结果,按字典序排列 6 | string s, st; 7 | int main() { 8 | while (cin >>s && s!= "#") { 9 | st = s; 10 | for (auto& ch : st) // 转为小写 11 | if (ch >= 'A' && ch <= 'Z') ch = tolower(ch); // 转为小写 12 | sort(st.begin(), st.end()); // 升序排列,顺序无关 13 | dict[st]++; // 统计次数 14 | trans[st] = s; // 记录原单词 15 | } 16 | for (auto p : dict) if (p.second == 1) ans.insert(trans[p.first]); // 出现次数1表示非重排单词 17 | for (auto& p : ans) cout <

2 | using namespace std; 3 | map, int>dict; // 每个单词的字母出现次数->出现次数 4 | map, string> trans; // 单词字母出现次数->原单词 5 | set ans; // 存储输出结果,按字典序排列 6 | string s, st; 7 | int main() { 8 | while (cin >>s && s!= "#") { 9 | st = s; 10 | map mp; 11 | for (auto& ch : st) { 12 | if (ch >= 'A' && ch <= 'Z') ch = tolower(ch); // 转为小写 13 | mp[ch] ++; // 统计每个字符出现次数 14 | } 15 | dict[mp]++; // 统计次数 16 | trans[mp] = s; // 记录原单词 17 | } 18 | for (auto p : dict) if (p.second == 1) ans.insert(trans[p.first]); // 出现次数1表示非重排单词 19 | for (auto& p : ans) cout <

2 | using namespace std; 3 | int n, m; 4 | string s, st; 5 | map idmp; // 字符串->id 6 | int getId(string s) { // 获取字符串id,若已存在,直接返回,否则分配id 7 | if (idmp.find(s) == idmp.end()) idmp.insert({s, idmp.size()}); // 不存在 8 | return idmp[s]; 9 | } 10 | int main() { 11 | while (cin >>n >>m) { 12 | getchar(); vector table[n+1]; idmp.clear(); // 初始化!!! 13 | for (int i = 0; i < n; i ++) { 14 | getline(cin, s); stringstream input(s); 15 | while (getline(input, st, ',')) table[i].push_back(getId(st)); 16 | } 17 | bool isPNF = true; // 标记是否为PNF 18 | for (int i = 0; i < m-1 && isPNF; i ++) { // 遍历任意两列 19 | for (int j = i+1; j < m && isPNF; j ++) { 20 | map, int> pos; // 两列对应字符串标号->行 21 | for (int k = 0; k < n && isPNF; k ++) { // 每一行 22 | if (pos.find({table[k][i],table[k][j]}) == pos.end()) { 23 | pos[{table[k][i],table[k][j]}] = k; 24 | } 25 | else { 26 | printf("NO\n%d %d\n%d %d\n", pos[{table[k][i],table[k][j]}]+1, k+1, i+1, j+1); 27 | isPNF = false; 28 | } 29 | } 30 | } 31 | } 32 | if (isPNF) printf("YES\n"); 33 | } 34 | return 0; 35 | } -------------------------------------------------------------------------------- /aoapc_uva/aoapc-code/ch05/UVA1594.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int T, n, t; 4 | int main() { 5 | scanf("%d", &T); 6 | while (T--) { 7 | scanf("%d", &n); 8 | vector a, b(n), zero(n, 0); 9 | for (int i = 0; i < n; i ++) { // 输入n元组 10 | scanf("%d", &t); 11 | a.push_back(t); 12 | } 13 | set > _set; // 集合判重 14 | int flag = 0; // 标记结果 15 | while (flag == 0) { 16 | if (a == zero) flag = 1; // 全0 17 | else if (_set.find(a) != _set.end()) flag = 2; // 重复 18 | else { 19 | _set.insert(a); 20 | for (int i = 0; i < n; i ++) b[i] = abs(a[i] - a[(i+1)%n]); // ducci下一个序列 21 | a = b; 22 | } 23 | } 24 | printf("%s\n", flag == 1 ? "ZERO" : "LOOP"); 25 | } 26 | return 0; 27 | } -------------------------------------------------------------------------------- /aoapc_uva/aoapc-code/ch05/UVA1595.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int T, n, x, y; 4 | int main() { 5 | cin >>T; 6 | while (T --) { 7 | cin >>n; 8 | map > mp; // y->x坐标 9 | for (int i = 0; i < n; i ++) { 10 | scanf("%d %d", &x, &y); 11 | mp[y].push_back(x); 12 | } 13 | set _set; // 最终大小为1表示左右对称 14 | for (auto p : mp) { 15 | sort(p.second.begin(), p.second.end()); // x坐标升序排列 16 | int right = (p.second.size() % 2 == 0) ? p.second.size()/2 : p.second.size()/2+1; 17 | for (int i = 0; i < right; i ++) 18 | _set.insert(p.second[i]+p.second[p.second.size()-i-1]); // 两侧点之和 19 | } 20 | printf("%s\n", _set.size() == 1 ? "YES" : "NO"); 21 | } 22 | return 0; 23 | } -------------------------------------------------------------------------------- /aoapc_uva/aoapc-code/ch05/UVA400.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int n; 4 | string s, format; 5 | int main() { 6 | while (cin >>n) { 7 | int maxlen=-1, len, colNum=1, rowNum; 8 | set _set; 9 | for (int i = 0; i < n; i ++) { 10 | cin >>s; _set.insert(s); 11 | maxlen = max(maxlen, (int)s.size()); // 最长长度 12 | } 13 | while ((maxlen+2)*colNum-2 <= 60) colNum++; // 列数 14 | colNum --; rowNum = (int)ceil((float)n / colNum); // 行数 15 | vector fnames; 16 | fnames.insert(fnames.begin(), _set.begin(), _set.end()); // set转为vector 17 | printf("%s\n", string(60,'-').c_str()); // 60个- 18 | for (int i = 0; i < rowNum; i ++) { // 遍历输出 19 | for (int j = 0; j < colNum && j*rowNum+i < n; j ++) { 20 | len = (j == colNum-1) ? maxlen : maxlen+2; // 最后一列对其宽度为maxlen 21 | format = "%-"+to_string(len)+"s"; // 输出格式 22 | printf(format.c_str(), fnames[j*rowNum+i].c_str()); 23 | } 24 | puts(""); 25 | } 26 | } 27 | return 0; 28 | } -------------------------------------------------------------------------------- /aoapc_uva/aoapc-code/ch05/UVA540.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int t, n, x, num=0; 4 | string cmd; 5 | int main() { 6 | while (cin >>t && t != 0) { 7 | map team; // 编号x->组别编号 8 | for (int i = 0; i < t; i ++) { // 组别编号 9 | cin >>n; 10 | for (int j = 0; j < n; j ++) { // 每一组 11 | cin >>x; 12 | team[x] = i; 13 | } 14 | } 15 | printf("Scenario #%d\n", ++num); // 输出测试用例编号 16 | queue q1, q2[1010]; // 总团队队列,组内部队列 17 | while (cin >>cmd && cmd[0] != 'S') { 18 | if (cmd[0] == 'E') { // 入队 19 | cin >>x; 20 | if (q2[team[x]].empty()) { // 组内不存在队员 21 | q1.push(team[x]); // 进入总队列 22 | } 23 | q2[team[x]].push(x); // 组内不存在队员,加入总队列最后 24 | } 25 | else if (cmd[0] == 'D') { // 出队 26 | printf("%d\n", q2[q1.front()].front()); 27 | q2[q1.front()].pop(); 28 | if (q2[q1.front()].empty()) q1.pop(); // 维护总队列 29 | } 30 | } 31 | puts(""); 32 | } 33 | return 0; 34 | } -------------------------------------------------------------------------------- /aoapc_uva/aoapc-code/ch05/acsdn.txt: -------------------------------------------------------------------------------- 1 | ## 紫书刷题进行中,题解系列【[GitHub](https://github.com/wyjoutstanding/Algorithm/tree/master/aoapc_uva)|[CSDN](https://blog.csdn.net/qq_40738840/article/details/104175021)】 -------------------------------------------------------------------------------- /aoapc_uva/aoapc-code/ch05/bcsdn: -------------------------------------------------------------------------------- 1 | 5-1: https://blog.csdn.net/qq_40738840/article/details/104180332 2 | 5-2: https://blog.csdn.net/qq_40738840/article/details/104190346 3 | 5-3: https://blog.csdn.net/qq_40738840/article/details/104190613 4 | 5-4: https://blog.csdn.net/qq_40738840/article/details/104192559 5 | 5-5: https://blog.csdn.net/qq_40738840/article/details/104196214 6 | 5-6: https://blog.csdn.net/qq_40738840/article/details/104199736 7 | 5-7: https://blog.csdn.net/qq_40738840/article/details/104200997 8 | 5-8: https://blog.csdn.net/qq_40738840/article/details/104204295 9 | 5-9: https://blog.csdn.net/qq_40738840/article/details/104208507 10 | 5-11: https://blog.csdn.net/qq_40738840/article/details/104215096 11 | 5-12: https://blog.csdn.net/qq_40738840/article/details/104217617 12 | 习题 13 | 5-1: https://blog.csdn.net/qq_40738840/article/details/104219607 14 | 5-2: https://blog.csdn.net/qq_40738840/article/details/104220596 15 | 5-3: https://blog.csdn.net/qq_40738840/article/details/104221467 16 | 5-4: https://blog.csdn.net/qq_40738840/article/details/104221156 17 | 5-5: https://blog.csdn.net/qq_40738840/article/details/104221957 18 | 5-6: https://blog.csdn.net/qq_40738840/article/details/104222609 19 | 5-7: https://blog.csdn.net/qq_40738840/article/details/104224057 20 | 5-8: https://blog.csdn.net/qq_40738840/article/details/104227213 21 | 5-9: https://blog.csdn.net/qq_40738840/article/details/104233634 22 | 5-10: https://blog.csdn.net/qq_40738840/article/details/104238925 23 | 5-11: https://blog.csdn.net/qq_40738840/article/details/104239625 -------------------------------------------------------------------------------- /aoapc_uva/aoapc-code/ch05/data.txt: -------------------------------------------------------------------------------- 1 | 5 2 | {a:3,b:4,c:10,f:6} 3 | {a:3,c:5,d:10,ee:4} 4 | {x:1,xyz:123456789123456789123456789} 5 | {xyz:123456789123456789123456789,x:1} 6 | {first:1,second:2,third:3} 7 | {third:3,second:2} 8 | {a:1,b:2,c:3q3r1234,cdad:123414324,d:12} 9 | {c:1,d:14} 10 | {} 11 | {} -------------------------------------------------------------------------------- /aoapc_uva/aoapc-code/ch05/run.bat: -------------------------------------------------------------------------------- 1 | test.exe < tmp.md > out.txt -------------------------------------------------------------------------------- /aoapc_uva/aoapc-code/ch06/UVA10129-opt.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int T, n; 4 | int findFather(int a, vector& father) { // 并查集找父结点 5 | return father[a] = (father[a] == a) ? a : findFather(father[a], father); 6 | } 7 | int main() { 8 | scanf("%d", &T); 9 | string s; 10 | while (T --) { 11 | scanf("%d", &n); 12 | vector degree(26,0), father(26); // 26个字母对应的入度表,父结点 13 | for (int i = 0; i < 26; i ++) father[i] = i; // 初始化并查集父结点 14 | set _set; // 存储出现的字符个数(去重) 15 | for (int i = 0; i < n; i ++) { 16 | cin >>s; 17 | _set.insert(s[0]); _set.insert(s.back()); // 头尾插入集合 18 | degree[s[0]-'a'] --; degree[s.back()-'a'] ++; // 出度和入度计算 19 | father[s[0]-'a'] = findFather(s.back()-'a', father); // 并查集计算 20 | } 21 | int even=0, sp=-1, ep=-1; // 偶度顶点 22 | for (int i=0; i < 26; i ++) { 23 | if (degree[i] == 0) even ++; 24 | else if (degree[i] == 1) sp = 1; // 奇度顶点,且出度-入度=1 25 | else if (degree[i] == -1) ep = 1; // 奇度顶点,且出度-入度=-1 26 | } 27 | for (int i=0; i < 26; i ++) father[i] = findFather(i, father); // 最后来一遍,防止有些顶点没被更新 28 | int num=0; 29 | for (int i=0; i < 26; i ++) if (father[i] == i) num ++; // 不同的集合个数 30 | if ((even == 26-2 && (sp==1&&ep==1) || even == 26) && num == 1+26-_set.size()) printf("Ordering is possible.\n"); 31 | else printf("The door cannot be opened.\n"); 32 | } 33 | return 0; 34 | } -------------------------------------------------------------------------------- /aoapc_uva/aoapc-code/ch06/UVA10305.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int n, m, a, b; 4 | void update(vector& indegree, queue& q) { // 更新队列 5 | for (int i = 1; i <= n; i ++) { 6 | if (indegree[i] == 0) { // 入度为0 7 | q.push(i); // 入队 8 | indegree[i] = -1; // 标记为已访问 9 | } 10 | } 11 | } 12 | int main() { 13 | while (cin >>n >>m && (n != 0 || m != 0)) { // 仅m=0是合法的,如n=5,m=0 14 | vector > adj(n+1); // 邻接矩阵 15 | vector indegree(n+1), ans; // 入度表,从1开始;存储结果 16 | while (m --) { 17 | cin >>a >>b; 18 | adj[a].push_back(b); 19 | indegree[b] ++; // 入度累加 20 | } 21 | queue q; update(indegree, q); // 初始化 22 | while (!q.empty()) { 23 | int u = q.front(); q.pop(); ans.push_back(u); 24 | for (int v : adj[u]) indegree[v] --; // 更新入度表 25 | update(indegree, q); // 更新队列 26 | } 27 | for (int i = 0; i < ans.size(); i ++) printf("%d%s", ans[i], i == ans.size()-1 ? "\n" : " "); 28 | } 29 | return 0; 30 | } -------------------------------------------------------------------------------- /aoapc_uva/aoapc-code/ch06/UVA10562-opt.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int T; 4 | vector buf; // 存储输入的树 5 | void dfs(int r, int c) { // 递归打印以buf(r,c)为根的子树 6 | printf("%c", buf[r][c]); 7 | if (r < buf.size()-1 && buf[r+1][c] == '|') { // 有孩子 8 | putchar('('); int l=c; 9 | while (buf[r+2][l] == '-') l--; // 查找--的左边界 10 | for (int i=l+1; i < buf[r+2].size() && buf[r+2][i] == '-'; i ++) { 11 | if (i < buf[r+3].size() && buf[r+3][i] != ' ') dfs(r+3, i); // 注意r+3的有效范围判断 12 | } 13 | putchar(')'); 14 | } 15 | else printf("()"); 16 | } 17 | int main() { 18 | scanf("%d", &T); getchar(); // 吸收多余换行 19 | string s; 20 | while (T --) { 21 | buf.clear(); 22 | while (getline(cin, s) && s != "#") buf.push_back(s); // 以数组存储树 23 | putchar('('); 24 | for (int i=0; !buf.empty() && i < buf[0].size(); i ++) 25 | if (buf[0][i] != ' ') {dfs(0,i); break;} // 找到根 26 | puts(")"); 27 | } 28 | return 0; 29 | } -------------------------------------------------------------------------------- /aoapc_uva/aoapc-code/ch06/UVA11988.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | string s; 4 | int main() { 5 | while (cin >>s) { 6 | list l; 7 | auto p = l.begin(); // 初始化 8 | for (auto ch : s) { 9 | if (ch == '[') p = l.begin(); // 开头 10 | else if (ch == ']') p = l.end(); // 结尾 11 | else { 12 | p = l.insert(p, ch); // 返回插入数据的迭代器 13 | p ++; // 后移一位 14 | } 15 | } 16 | for (auto ch : l) cout < 2 | using namespace std; 3 | int n, m, op, a, b, num=0; 4 | int main() { 5 | while (scanf("%d %d", &n, &m) == 2) { 6 | list l(n); // 存储1-n 7 | vector::iterator> pos(n+1); // pos[i]表示数字i在list中的指针 8 | int idx=1, inv=0; 9 | for (auto p=l.begin(); p != l.end(); p++, idx++) { // 初始化 10 | *p = idx; 11 | pos[idx] = p; 12 | } 13 | for (int i = 0; i < m; i ++) { // m个操作 14 | scanf("%d", &op); 15 | if (op != 4) scanf("%d %d", &a, &b); 16 | if (op == 4) inv = !inv; // 反转标记 17 | else if (op == 3) swap(*pos[a],*pos[b]), swap(pos[a], pos[b]); // 交换 18 | else { 19 | l.erase(pos[a]); // 先擦除 20 | if (inv == 1) op = 3 - op; // 反转则左右交换 21 | auto p=pos[b]; 22 | if (op == 2) p ++; // 插入右侧 23 | pos[a] = l.insert(p, a); // a的新位置 24 | } 25 | } 26 | long long cnt=1, oddsum=0; // 避免溢出 27 | for (auto p=l.begin(); p != l.end(); p++, cnt++) { 28 | if (cnt % 2 == 1) oddsum += *p; 29 | } 30 | printf("Case %d: %lld\n", ++num, (inv == 1 && n%2 == 0) ? (long long)n*(n+1)/2-oddsum : (long long)oddsum); 31 | } 32 | return 0; 33 | } -------------------------------------------------------------------------------- /aoapc_uva/aoapc-code/ch06/UVA1527.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | vector > adj; // 邻接表 4 | int getId(char c1, char c2) { // 获取字符节点的编号 5 | return (c1 - 'A')*2 + ((c2 == '+') ? 0 : 1); // 注意?:优先级很低,要用括号 6 | } 7 | void connect(char a1, char a2, char b1, char b2) { // 参数分别表示两点的第一二个字符 8 | if (a1 == '0' || b1 == '0') return; // 任意一点为0均不连接 9 | adj[getId(a1,a2)^1].push_back(getId(b1,b2)); // 有向图构建;异或含义-> (B+)^1=B- 10 | } 11 | bool bfs() { // 拓扑排序检测是否存在有向环 12 | int indegree[52]={0}, num=0; // 访问数组, 入度表,入队计算 13 | for (int i=0; i < 52; i ++) 14 | for (auto v : adj[i]) indegree[v] ++; // 入度计算 15 | queue q; 16 | for (int i=0; i < 52; i ++) if (indegree[i] == 0) q.push(i); // 队列初始化 17 | while (!q.empty()) { 18 | int u=q.front(); q.pop(); num ++; // 统计出队个数 19 | for (int v : adj[u]) { 20 | indegree[v] --; // 更新入度表 21 | if (indegree[v] == 0) q.push(v); // 入度=0则进队 22 | } 23 | } 24 | return num == 52; // 不存在有向环num=52 25 | } 26 | int main() { 27 | int n; string s; 28 | while (cin >>n) { 29 | adj.clear(); adj.resize(52); // 初始化 30 | for (int i=0; i < n; i ++) { 31 | cin >>s; 32 | for (int i=0; i < 4; i ++) { // 考虑旋转翻转 33 | for (int j=0; j < 4; j ++) 34 | if (i != j) connect(s[i*2],s[i*2+1],s[j*2],s[j*2+1]); // 构建有向图 35 | } 36 | } 37 | printf("%s\n", bfs() ? "bounded" : "unbounded"); 38 | } 39 | return 0; 40 | } -------------------------------------------------------------------------------- /aoapc_uva/aoapc-code/ch06/UVA1527dfs.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | vector > adj; // 邻接表,注意用set存储去重 4 | int vis[52]={0}; // 标记访问数组 5 | int getId(char c1, char c2) { // 获取字符节点的编号 6 | return (c1 - 'A')*2 + ((c2 == '+') ? 0 : 1); // 注意?:优先级很低,要用括号 7 | } 8 | void connect(char a1, char a2, char b1, char b2) { // 参数分别表示两点的第一二个字符 9 | if (a1 == '0' || b1 == '0') return; // 任意一点为0均不连接 10 | adj[getId(a1,a2)^1].insert(getId(b1,b2)); // 有向图构建;异或含义-> (B+)^1=B- 11 | } 12 | bool dfs(int u) { // 判断以顶点u开始是否存在有向图 13 | vis[u] = -1; // 当前遍历的标记 14 | for (int v : adj[u]) // 邻边 15 | if (vis[v] == -1 || (vis[v] == 0 && dfs(v))) return true; // 碰见当前已访问节点,表示存在有向环 16 | vis[u] = 1; // 回溯时标记为1,表示已访问过,必须在return false之前 17 | return false; // 到此处表示当前连通块不存在有向环 18 | } 19 | bool find_cycle() { // 检查图是否存在有向环 20 | memset(vis, 0, sizeof(vis)); // 初始化为0,表示未访问 21 | for (int i=0; i < 52; i ++) // 遍历所有连通块 22 | if (vis[i] == 0 && dfs(i)) return true; // 存在一个环 23 | return false; 24 | } 25 | int main() { 26 | int n; string s; 27 | while (cin >>n) { 28 | adj.clear(); adj.resize(52); // 初始化 29 | for (int i=0; i < n; i ++) { 30 | cin >>s; 31 | for (int i=0; i < 4; i ++) { // 考虑旋转翻转 32 | for (int j=0; j < 4; j ++) 33 | if (i != j) connect(s[i*2],s[i*2+1],s[j*2],s[j*2+1]); // 构建有向图 34 | } 35 | } 36 | printf("%s\n", !find_cycle() ? "bounded" : "unbounded"); 37 | } 38 | return 0; 39 | } -------------------------------------------------------------------------------- /aoapc_uva/aoapc-code/ch06/UVA297.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int T, cnt, img[1025][1025]={0}, idx; 4 | // 根据s[idx]绘制左上角为(r,c),边长为w的正方形区域 5 | void draw(string s, int& idx, int r, int c, int w) { 6 | if (idx >= s.size()) return; 7 | idx ++; // 先后移,注意引用 8 | if (s[idx-1] == 'p') { // 父结点,绘制4个子方格 9 | draw(s, idx, r, c+w/2, w/2); // 1 10 | draw(s, idx, r, c, w/2); // 2 11 | draw(s, idx, r+w/2, c, w/2); // 3 12 | draw(s, idx, r+w/2, c+w/2, w/2); // 4 13 | } 14 | else if (s[idx-1] == 'f') { // 黑色才处理,白色默认0,不计数 15 | for (int i = r; i < r+w; i ++) // 按最小方块标记上色 16 | for (int j = c; j < c+w; j ++) 17 | if (img[i][j] == 0) {cnt++; img[i][j] = 1;} // 统计黑色个数,记得加标记 18 | } 19 | } 20 | int main() { 21 | scanf("%d", &T); 22 | string s1, s2; 23 | while (T --) { 24 | cin >>s1 >>s2; 25 | cnt=0; fill(img[0], img[0]+1025*1025, 0); // 初始化 26 | draw(s1, idx=0, 0, 0, 32); // 1024=32*32个格子 27 | draw(s2, idx=0, 0, 0, 32); // 注意初始化idx=0 28 | printf("There are %d black pixels.\n", cnt); 29 | } 30 | return 0; 31 | } -------------------------------------------------------------------------------- /aoapc_uva/aoapc-code/ch06/UVA422.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int n, a, b; 4 | char ch; 5 | map > mp; // 矩阵->(行数,列数) 6 | int simu(string s) { // 模拟相乘过程,错误返回-1,否则返回次数 7 | int ans = 0; 8 | stack > stk; // 矩阵栈,第一二维 9 | bool isErr=false; // 标记是否有错误 10 | for (auto c : s) { 11 | if (isalpha(c)) stk.push(mp[c]); // 矩阵 12 | if (c == ')') { // 出栈计算 13 | auto p1 = stk.top(); stk.pop(); 14 | auto p2 = stk.top(); stk.pop(); 15 | if (p2.second != p1.first) { // 错误 16 | isErr = true; 17 | break; 18 | } 19 | ans += p2.first*p2.second*p1.second; // 运算次数 20 | stk.push({p2.first, p1.second}); // 重新压入 21 | } 22 | } 23 | return ans = (isErr) ? -1 : ans; 24 | } 25 | int main() { 26 | scanf("%d", &n); 27 | while (n --) { 28 | getchar(); 29 | scanf("%c %d %d", &ch, &a, &b); 30 | mp[ch] = {a,b}; 31 | } 32 | string s; 33 | while (cin >>s) { 34 | int ans = simu(s); 35 | if (ans == -1) puts("error"); 36 | else printf("%d\n", ans); 37 | } 38 | return 0; 39 | } -------------------------------------------------------------------------------- /aoapc_uva/aoapc-code/ch06/UVA514.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int n, a[1010]; 4 | int main() { 5 | while (cin >>n && n != 0) { 6 | while (cin >>a[1] && a[1] != 0) { 7 | for (int i = 2; i <= n; i ++) scanf("%d", &a[i]); // 输入 8 | stack stk; // 模拟栈 9 | int j = 1; // 判断联系满足的个数 10 | for (int i = 1; i <= n; i ++) { // 1-n依次压入 11 | stk.push(i); // 压栈 12 | while (!stk.empty() && stk.top() == a[j]) stk.pop(), j ++; // 当栈非空且栈顶为a[j]时,出栈 13 | } 14 | printf("%s\n", stk.empty() && j == n+1 ? "Yes" : "No"); // 栈空表示合法 15 | } 16 | puts(""); // 两组间空行 17 | } 18 | return 0; 19 | } -------------------------------------------------------------------------------- /aoapc_uva/aoapc-code/ch06/UVA572.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int m, n, dict[8][2]={{0,1},{0,-1},{1,0},{-1,0},{1,1},{1,-1},{-1,1},{-1,-1}}; // 8个方向 4 | char grid[101][101]; // 方格 5 | void dfs(int x, int y) { 6 | grid[x][y] = '*'; // 标记 7 | int xx, yy; 8 | for (int i = 0; i < 8; i ++) { // 8个方向 9 | xx = x + dict[i][0]; yy = y + dict[i][1]; 10 | if (xx >= 0 && xx < m && yy >= 0 && yy < n && grid[xx][yy] == '@') dfs (xx, yy); // 位置合法&&有油 11 | } 12 | } 13 | int main() { 14 | while (scanf("%d %d", &m, &n) == 2 && m != 0) { 15 | getchar(); // 吸收空行 16 | for (int i = 0; i < m; i ++) { 17 | for (int j = 0; j < n; j ++) scanf("%c", &grid[i][j]); 18 | getchar(); // 吸收空行 19 | } 20 | int ans = 0; // 存储结果 21 | for (int i = 0; i < m; i ++) { // 遍历所有格子 22 | for (int j = 0; j < n; j ++) { 23 | if (grid[i][j] == '@') { // 发现油格 24 | ans ++; // 数量增加 25 | dfs(i, j); // 找连通块 26 | } 27 | } 28 | } 29 | printf("%d\n", ans); 30 | } 31 | return 0; 32 | } -------------------------------------------------------------------------------- /aoapc_uva/aoapc-code/ch06/UVA679-2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int T, D, I; 4 | int main() { 5 | scanf("%d", &T); 6 | while (T --) { 7 | scanf("%d %d", &D, &I); 8 | long long ans=1; 9 | for (int i = 1; i <= D-1; i ++) { // 模拟I个小球掉落 10 | if (I % 2 == 1) { // I表示第几个经过当前点 11 | I = (I+1)/2; // 更新 12 | ans *= 2; 13 | } 14 | else { // 偶数走右子树 15 | I /= 2; 16 | ans = ans*2 + 1; 17 | } 18 | } 19 | printf("%lld\n", ans); 20 | } 21 | scanf("%d", &T); // 最后的-1,多余的输入! 22 | return 0; 23 | } -------------------------------------------------------------------------------- /aoapc_uva/aoapc-code/ch06/UVA679.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | #define MAX(D) (1< 2 | using namespace std; 3 | map cnt; // 位置->个数;统计每叠对应权值总和 4 | void createTree(int pos=0) { // 先序隐式建树,同时累加每个位置的值 5 | int v; scanf("%d", &v); 6 | if (v != -1) { 7 | cnt[pos] += v; // 累加值 8 | createTree(pos-1); // 左子树 9 | createTree(pos+1); // 右子树 10 | } 11 | } 12 | int main() { 13 | for (int i = 1; ; i ++) { 14 | cnt.clear(); createTree(0); // 初始化,隐式建树求值 15 | if (cnt.empty()) break; // 读到最后一个-1,结束 16 | printf("Case %d:\n", i); 17 | for (auto p : cnt) { // map按照key的字典序升序排列 18 | printf("%d%s", p.second, p.first == cnt.rbegin()->first ? "\n" : " "); 19 | } 20 | puts(""); // 每个测试用例后均有空行 21 | } 22 | return 0; 23 | } -------------------------------------------------------------------------------- /aoapc_uva/aoapc-code/ch06/UVA839-opt.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int T, W; 4 | bool isEqu(int& w) { // 先序读入(隐式建树);后序判断是否平衡 5 | int wl, dl, wr, dr; 6 | scanf("%d %d %d %d", &wl, &dl, &wr, &dr); 7 | bool b1=true, b2=true; // 判断左右子树是否平衡 8 | if (wl == 0) b1 = isEqu(wl); // 左子树递归判断 9 | if (wr == 0) b2 = isEqu(wr); // 右子树递归判断 10 | w = wl + wr; // 重量为引用,累加影响上一层结果 11 | return b1 && b2 && (wl * dl == wr * dr); // 左右子树和当前节点均平衡 12 | } 13 | int main() { 14 | scanf("%d", &T); 15 | for (int i = 0; i < T; i ++) { 16 | printf("%s%s", isEqu(W) ? "YES":"NO", i == T-1 ? "\n":"\n\n"); 17 | } 18 | return 0; 19 | } -------------------------------------------------------------------------------- /aoapc_uva/aoapc-code/ch06/UVA839.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | struct Node { 4 | int wl, wr, dl, dr; 5 | Node *l=NULL, *r=NULL; 6 | }; 7 | string s; 8 | int T; 9 | bool readInput(int& wl, int& dl, int& wr, int& dr) { // 读取输入 10 | if (getline(cin, s) && !s.empty()) { 11 | stringstream input(s); 12 | input >>wl >>dl >>wr >>dr; 13 | return true; // 成功 14 | } 15 | else return false; // 失败 16 | } 17 | Node* createTree() { // 递归建树(先序) 18 | Node* root = NULL; 19 | int wl, dl, wr, dr; 20 | if (readInput(wl, dl, wr, dr)) { // 读入成功 21 | root = new Node; 22 | root->wl = wl; root->wr = wr; 23 | root->dl = dl; root->dr = dr; 24 | if (wl == 0) root->l = createTree(); 25 | if (wr == 0) root->r = createTree(); 26 | } 27 | return root; 28 | } 29 | int dfs(Node* root) { // 后序遍历并判断是否平衡 30 | if (root == NULL) return -1; // 空树 31 | if (root->l != NULL) root->wl = dfs(root->l); // 左子树 32 | if (root->r != NULL) root->wr = dfs(root->r); // 右子树 33 | if (root->wl == -1 || root->wr == -1) return -1; // 非法,剪枝 34 | if (root->wl * root->dl == root->wr*root->dr) return root->wl+root->wr; // 平衡,返回左右重量和 35 | else return -1; // 非法标志 36 | } 37 | int main() { 38 | scanf("%d ", &T); // 两个空格可吸收换行 39 | for (int i = 0; i < T; i ++) { 40 | Node* bt = createTree(); 41 | printf("%s%s\n", dfs(bt) != -1 ? "YES" : "NO", i != T-1 ? "\n" : ""); 42 | if (i != T-1) getchar(); // 空行吸收 43 | } 44 | return 0; 45 | } -------------------------------------------------------------------------------- /aoapc_uva/aoapc-code/ch06/acsdn.txt: -------------------------------------------------------------------------------- 1 | ## 紫书刷题进行中,题解系列【[GitHub](https://github.com/wyjoutstanding/Algorithm/tree/master/aoapc_uva)|[CSDN](https://blog.csdn.net/qq_40738840/article/details/104175021)】 -------------------------------------------------------------------------------- /aoapc_uva/aoapc-code/ch06/data: -------------------------------------------------------------------------------- 1 | 3 2 | 500 500 499 3 | 0 0 999 4 | 1000 1000 200 5 | 3 6 | 500 500 499 7 | 0 0 999 8 | 1000 1000 500 -------------------------------------------------------------------------------- /aoapc_uva/aoapc-note/错题集.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wyjoutstanding/Algorithm/4d5c99f5a91d4a8dfcededa9d2da4b375080fb4e/aoapc_uva/aoapc-note/错题集.docx --------------------------------------------------------------------------------