先把键盘上每个字符预处理成对应手指编号,再顺序扫描整串文本,分别累加 8 根手指的按键次数。
OJ: luogu
题目 ID: P6263
难度:普及-
标签:模拟字符串
日期: 2026-06-19 09:49
题意
给出一串需要输入的字符。
题目已经规定了标准打字法中,每个键应该由哪根手指负责。要求统计除拇指外的 8 根手指,各自需要按多少次键。
思路
这题本质就是一个“字符到手指编号”的映射统计。
最直接的办法,是把每根手指负责的字符列出来,然后逐个字符去查它属于哪一组:
cpp
// brute.cpp:直接按键盘分组逐字符统计每根手指的按键次数。
#include <bits/stdc++.h>
using namespace std;
string s;
int ans[8];
int get_finger(char ch) {
string group[8] = {
"1QAZ",
"2WSX",
"3EDC",
"4RFV5TGB",
"6YHN7UJM",
"8IK,",
"9OL.",
"0P;/-['=]"
};
for (int i = 0; i < 8; i++) {
for (int j = 0; j < (int) group[i].size(); j++) {
if (group[i][j] == ch) {
return i;
}
}
}
return -1;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
getline(cin, s);
memset(ans, 0, sizeof(ans));
for (int i = 0; i < (int) s.size(); i++) {
int id = get_finger(s[i]);
if (id != -1) {
ans[id]++;
}
}
for (int i = 0; i < 8; i++) {
cout << ans[i] << '\n';
}
return 0;
}如何建模
把 8 根手指编号为:
- 左手小指
- 左手无名指
- 左手中指
- 左手食指
- 右手食指
- 右手中指
- 右手无名指
- 右手小指
然后把题图中属于同一根手指的所有键放进同一个字符串分组里。
例如:
- 左手小指:
1QAZ - 左手食指:
4RFV5TGB - 右手小指:
0P;/-['=]
这样每读到一个字符,只要查出它属于哪一组,就能给对应手指计数。
为什么顺序扫描就够了
每个字符对应的负责手指是固定的,不会因为上下文改变。
所以整串文本的答案,就是每个字符独立归类后,把对应手指的计数加一。
代码
cpp
#include <bits/stdc++.h>
using namespace std;
string s;
int ans[8];
int belong[256]; // 每个字符由哪根手指负责,-1 表示不统计
void init_belong() {
memset(belong, -1, sizeof(belong));
string group[8] = {
"1QAZ",
"2WSX",
"3EDC",
"4RFV5TGB",
"6YHN7UJM",
"8IK,",
"9OL.",
"0P;/-['=]"
};
for (int i = 0; i < 8; i++) {
for (int j = 0; j < (int) group[i].size(); j++) {
belong[(int) group[i][j]] = i;
}
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
getline(cin, s);
init_belong();
memset(ans, 0, sizeof(ans));
for (int i = 0; i < (int) s.size(); i++) {
int id = belong[(int) s[i]];
if (id != -1) {
ans[id]++;
}
}
for (int i = 0; i < 8; i++) {
cout << ans[i] << '\n';
}
return 0;
}复杂度
- 时间复杂度:
- 空间复杂度:
其中 n 是字符串长度。预处理字符映射后,每个字符只需要一次常数时间查询。
总结
这题没有算法难点,关键只是把题图里的键位归属抄对。
一旦字符到手指的映射表建好,剩下就是一遍简单统计。
