-
题目大意:键盘上有的键被卡住了,打字时每次按到被卡主的键,都会重复输出k次这个字符。
注意:若之前某个字符正常出现过,后面又出现了n*k次,说明这个键是正常的。
-
思路(来自柳诺):用尽可能多的容器/遍历去存多个信息
- 用map存这个键是否被卡住;
- 用一个数组存这个键是否不为被卡的键,为了避免这个键正常,但恰好输出了n*k次的情况;
- 在输出被卡字符时,用set存这个字符是否之前输出过,避免多次输出;
-
知识点:
- map
- set
-
代码:
#include <iostream> #include <string> #include <map> #include <set> using namespace std; bool normal_key[128]; // {a-z}, {0-9} 的ASKII在0-127内 int main(){ int k; string s; cin >> k; cin >> s; map<char, bool> m; set<char> printed; char pre = '#'; // 存前一个字符 s = s + '#'; // 为了遍历s时不报错 int cnt = 1; // 字符出现的次数从1开始 for(int i = 0; i < s.length(); i++){ if(s[i] == pre) cnt++; else{ if(cnt % k != 0) normal_key[pre] = true; // 注意记录的是pre! else m[pre] = true; // 注意记录的是pre! cnt = 1; } pre = s[i]; } for(int i = 0; i < s.length() - 1; i++){ // 排除特殊情况 if(m[s[i]] && normal_key[s[i]]) m[s[i]] = false; } for(int i = 0; i < s.length() - 1; i++){ // 因为map按键值排序了,所以不能按顺序输出m if(m[s[i]] && printed.find(s[i]) == printed.end()) { // 没输出过这个坏了的键的情况 printf("%c", s[i]); printed.insert(s[i]); // 输出过就放进set } } printf("\n"); for(int i = 0; i < s.length() - 1; i++){ printf("%c", s[i]); if(m[s[i]]) i = i + k - 1; // 后面还会i++ } return 0; }
-
总结:
- 若思路很乱,可尽可能用多的容器/遍历去存多个信息。之前我企图用一个map存一个键为坏键还是好键,但是在处理“这个键是好的,但输出了n*k次”时,我的思路很乱,因为还需做很多判断,要多次改变map的内容,这时我的脑子糊得像浆糊一样(我现在也没理清楚)。在参考柳诺的代码后,发现她用了一个数组去存“确定为好键”的键,一下子思路就变简单和清晰了。柳诺姐姐yyds呜呜呜!!!
- 因为map按键值排序了,所以不能按顺序输出m;unordered_map则是无序存储的,也不能按顺序输出m
- 细节:
- 在存“坏键”时,需要比较
s[i]
和pre
是否相同,所以应该i=s.size() + 1
,不然比较不到最后一个字符。所以还需要在最前面s = s + '#'
; - 因为
pre
记录的是上一个字符的内容,所以存进map或数组时应该存pre
而不是s[i]
。
- 在存“坏键”时,需要比较
【PAT】1112 Stucked Keyboard (20 分)
最新推荐文章于 2023-05-26 16:49:46 发布