42 lines
6.5 KiB
JSON
42 lines
6.5 KiB
JSON
{
|
||
"S0401P1": {
|
||
"key": "S0401P1 小杨的回文串",
|
||
"title": "小杨的回文串",
|
||
"statement": "给定一个只含英文字母、大小写混合的字符串,问三件事:①把所有字母统一转小写后,它是不是回文串(是Yes/否No);②原串里有多少个大写字母;③原串里有多少个小写字母。回文就是正读倒读一样,如 abba、abcba。",
|
||
"key_points": "先统计后转换(统计的是原串的大写/小写个数);大写字母 +32 = 小写字母;用双指针 l/r 向中间夹,发现一次不相等就判否;三行输出顺序是 回文结果/大写个数/小写个数。",
|
||
"code_file": "小杨的回文串.cpp",
|
||
"ref_code": "#include <bits/stdc++.h>\n#define endl '\\n'\nusing namespace std;\n\nstring s;\nint cnt1, cnt2; // cnt1大写 cnt2小写 \n\nint main(){\n\tcin >> s;\n\t\n\tint len = s.size();\n\tfor(int i = 0; i < len; i++){\n\t\t// 先数小写的个数 \n\t\tif(islower(s[i])){\n\t\t\tcnt2++;\n\t\t} \n\t\t// 再数大写的个数 \n\t\tif(isupper(s[i])){\n\t\t\tcnt1++;\n\t\t\t// 转换成小写\n\t\t\ts[i] = s[i] + 32; \n\t\t}\n\t}\n\t\n\tint l = 0, r = len - 1;\n\tbool ok = true;\n\twhile(l <= r){\n\t\tif(s[l] != s[r]){\n\t\t\tok = false;\n\t\t\tbreak;\n\t\t}\n\t\tl++, r--;\n\t}\n\t\n\tif(ok){\n\t\tcout << \"Yes\";\n\t} else {\n\t\tcout << \"No\";\n\t}\n\t\n\tcout << endl << cnt1 << endl << cnt2;\n\treturn 0;\n}"
|
||
},
|
||
"S0401P2": {
|
||
"key": "S0401P2 小杨有序去重",
|
||
"title": "小杨有序去重",
|
||
"statement": "给定一份非降序的成绩单(相邻可能相等),去掉连续的重复成绩,得到“出现过的不同成绩”列表。用双指针在数组上原地完成:慢指针 j 指向已保留部分的末尾,快指针 i 向后扫,遇到 a[i] ≠ a[j] 就把 a[i] 复制到 a[j+1]。输出两行:去重后的列表;不同成绩的个数。",
|
||
"key_points": "前提是“有序”,只去相邻重复;比较对象是 a[j](保留区末尾),不是 a[i-1];j 从 1 开始、i 从 2 开始(第一个数无条件保留);n 最大 1e5,必须一遍扫完。",
|
||
"code_file": "小杨有序去重.cpp",
|
||
"ref_code": "#include <bits/stdc++.h>\n#define endl '\\n'\nusing namespace std;\n\nconst int MAXN = 100010;\nint n;\nint arr[MAXN];\n\nint main(){\n\n cin >> n;\n for(int i = 1; i <= n; i++){\n cin >> arr[i];\n }\n\n if(n == 0){\n cout << endl << 0 << endl;\n return 0;\n }\n \t\n\tint j = 1; // 慢指针\n\tfor(int i = 2; i <= n; i++){\n\t\t// i表示快指针,一直向后移动\n\t\tif(arr[i] == arr[j]) continue;\n\t\t// 如果不相同\n\t\tarr[j+1] = arr[i];\n\t\tj++; \n\t} \n\t\n\tfor(int i = 1; i <= j; i++){\n\t\tcout << arr[i] << \" \";\n\t}\n\tcout << endl << j;\n return 0;\n}"
|
||
},
|
||
"S0401P3": {
|
||
"key": "S0401P3 小杨的进制数位",
|
||
"title": "小杨的进制数位",
|
||
"statement": "把十进制数 n 转换成 k 进制(2≤k≤16),并统计表示里的字符构成:①k 进制表示(超过 9 的数位用大写 A~F 表示 10~15);②表示中数字字符(0~9)的个数;③表示中字母字符(A~F)的个数。",
|
||
"key_points": "除 k 取余、余数倒着拼(out = S[余数] + out);查表 “0123456789ABCDEF”;n=0 要特判输出 0;统计的是 k 进制表示里的字符,不是十进制原数。",
|
||
"code_file": "小杨的进制数位.cpp",
|
||
"ref_code": "#include <bits/stdc++.h>\n#define endl '\\n'\nusing namespace std;\n\nint num, k;\nstring out;\nstring S = \"0123456789ABCDEF\";\nint cnt1 = 0,cnt2 = 0;\n\nint main(){\n\tcin >> num >> k;\n\t\n\tif(num == 0){\n\t\tcout << 0 << endl << 1 << endl << 0;\n\t\treturn 0;\n\t}\n\t\n\tint t = num;\n\twhile(t > 0){\n\t\tint g = t % k;\n\t\t\n\t\tout = S[g] + out;\n\t\t\n\t\tt /= k;\n\t}\n\t\n\tfor(char c : out){\n\t\tif(isupper(c)){\n\t\t\tcnt2++;\n\t\t}else if(isdigit(c)){\n\t\t\tcnt1++;\n\t\t}\n\t}\n\tcout << out << endl << cnt1 << endl << cnt2;\n\treturn 0;\n}"
|
||
},
|
||
"S0401P4": {
|
||
"key": "S0401P4 小杨的幸运数字",
|
||
"title": "小杨的幸运数字",
|
||
"statement": "有些正整数的二进制表示里恰好只有 1 个 1(如 1=1、2=10、8=1000),这样的数叫“幸运数”,也就是 2 的幂。给 n 个正整数,统计:①这 n 个数里幸运数的个数;②这 n 个数的二进制表示中 1 的总个数。",
|
||
"key_points": "对每个数单独数它的 1 的个数(cnt1 每轮要清零);sum 累计的是“1 的个数”,cnt 累计的是“满足条件的数”,别混;1(=2^0)也是幸运数;进阶可用 n&(n-1)==0 判断/__builtin_popcount 数 1。",
|
||
"code_file": "小杨的幸运数字.cpp",
|
||
"ref_code": "#include <bits/stdc++.h>\n#define endl '\\n'\nusing namespace std;\n\nint n, num, cnt = 0, sum = 0;\nstring str = \"01\";\n\nint main() {\n\tcin >> n;\n\n\tfor(int i = 1; i <= n; i++) {\n\t\tcin >> num;\n\t\tint t = num;\n\t\t\n\t\tstring out = \"\";\n\t\tint cnt1 = 0;// 判断1的个数 \n\t\t\n\t\twhile(t > 0) {\n\t\t\tint g = t % 2;\n\t\t\t\n\t\t\tif(g == 1){\n\t\t\t\tsum++; // 总数加一 \n\t\t\t\tcnt1++; // 个数加一 \n\t\t\t}\n\t\t\t\n\t\t\tout = str[g] + out;\n\t\t\tt /= 2;\n\t\t}\n\t\t\n\t\tif(cnt1 == 1){\n\t\t\tcnt++; \n\t\t} \n\t}\n\t\n\tcout << cnt << endl << sum;\n\n\n\treturn 0;\n}"
|
||
},
|
||
"S0401P5": {
|
||
"key": "S0401P5 小杨的报数游戏",
|
||
"title": "小杨的报数游戏",
|
||
"statement": "n 个小朋友围成一圈,编号 1~n。从 1 号开始沿顺时针从 1 报数,报到 k 的小朋友出列,出列者下一位重新从 1 报数……直到全部出列。按出列顺序输出编号(约瑟夫问题)。",
|
||
"key_points": "数组 arr[i] 记状态(0 在场/1 出列);只有 arr[idx]==0 的人才报数;报满 k 出列后 cnt 归零、p--;idx 越界就回绕 idx>n→idx=1;边界 k=1 依次出列 1 2 3…n。",
|
||
"code_file": "小杨的报数游戏.cpp",
|
||
"ref_code": "#include <iostream>\nusing namespace std;\n\nint main() {\n\tint n, k;\n\tcin >> n >> k;\n\tint arr[110] = {0}; // 0表示当前这个同学还在,1表示这个同学出列了\n\tint idx = 1; // 表示当前这个叫到第几个同学\n\tint cnt = 0; // 本轮报数的计数器\n\tint p = n; // 当前人数 \n\t\n\twhile(p != 0){\n\t\t// 先判断当前这个人是不是出列了\n\t\tif(arr[idx] == 0){\n\t\t\tcnt++;\n\t\t\tif(cnt == k){\n\t\t\t\t// 这个人出列\n\t\t\t\tcout << idx << \" \"; // 当前这个人出列\n\t\t\t\tarr[idx] = 1; // 修改当前这个人出列状态\n\t\t\t\tp--;\n\t\t\t\tcnt = 0; \n\t\t\t}\n\t\t} \n\t\tidx++;\n\t\tif(idx > n){\n\t\t\tidx = 1;\n\t\t}\n\t} \n\treturn 0;\n}"
|
||
}
|
||
} |