1112 Stucked Keyboard

On a broken keyboard, some of the keys are always stucked. So when you type some sentences, the characters corresponding to those keys will appear repeatedly on screen for k times.

Now given a resulting string on screen, you are supposed to list all the possible stucked keys, and the original string.

Notice that there might be some characters that are typed repeatedly. The stucked key will always repeat output for a fixed k times whenever it is pressed. For example, when k=3, from the string thiiis iiisss a teeeeeest we know that the keys i and e might be stucked, but s is not even though it appears repeatedly sometimes. The original string could be this isss a teest.

Input Specification:

Each input file contains one test case. For each case, the 1st line gives a positive integer k (1) which is the output repeating times of a stucked key. The 2nd line contains the resulting string on screen, which consists of no more than 1000 characters from {a-z}, {0-9} and _. It is guaranteed that the string is non-empty.

Output Specification:

For each test case, print in one line the possible stucked keys, in the order of being detected. Make sure that each key is printed once only. Then in the next line print the original string. It is guaranteed that there is at least one stucked key.

Sample Input:

3
caseee1__thiiis_iiisss_a_teeeeeest
 

Sample Output:

ei
case1__this_isss_a_teest

题意:

  给出电脑上屏幕的输出结果,问那几个键是坏键(在输出的结果中总是重复出现n次)

思路:

  先遍历一遍字符串找到所有没有坏的建将其存放入well集合中,再遍历一边字符串所有没有出现在well集合中的键都是坏的建,将其存入broken集合中用来判断是不是第一次出现。如果是第一次出现则将其加入到坏建字符串中。

Code:

 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 int main() {
 6     int n;
 7     string test;
 8     cin >> n >> test;
 9     int len = test.length();
10     set<int> broken, well;
11     string possible = "";
12     for (int i = 0; i < len; ++i) {
13         bool isBroken = true;
14         for (int j = i + 1; j < i + n && j < len; ++j) {
15             if (test[j] != test[j - 1]) {
16                 well.insert(test[i]);
17                 isBroken = false;
18                 break;
19             }
20         }
21         if (isBroken) i += n - 1;
22     }
23     for (int i = 0; i < len; ++i) {
24         if (well.find(test[i]) == well.end()) {
25             if (broken.find(test[i]) == broken.end()) possible += test[i];
26             broken.insert(test[i]);
27             i += n - 1;
28         }
29     }
30 
31     cout << possible << endl;
32     string ans = "";
33     for (int i = 0; i < len; ++i) {
34         if (broken.find(test[i]) == broken.end())
35             ans += test[i];
36         else {
37             ans += test[i];
38             i += n - 1;
39         }
40     }
41     cout << ans << endl;
42     return 0;
43 }

有一组数据被卡到了,还没找到原因。

 找到错误的原因了,当n = 3时***********aa在寻找well键的时候当i走到倒数第二个数字的时候,因为接下来的字符不够n个,

        for (int j = i + 1; j < i + n && j < len; ++j) {
            if (test[j] != test[j - 1]) {
                well.insert(test[i]);
                isBroken = false;
                break;
            }
        }

提前跳出,导致本来是well键的a,没有插入到well中,所以在第二次遍历找坏建的时候会将其当做坏建处理。只要在这个代码之上添加以下代码,就能够通过全部测试样例。

        if (i + n > len) {
            well.insert(test[i]);
            continue;
        }

看了一下别人的博客,对比了一下,发现我写的代码还是太冗余了,多看一下别人的优秀代码对自己也是一种提高。

出处:https://www.liuchuo.net/archives/2075

 1 #include <iostream>
 2 #include <map>
 3 #include <cstdio>
 4 #include <set>
 5 using namespace std;
 6 bool sureNoBroken[256];
 7 int main() {
 8     int k, cnt = 1;
 9     scanf("%d", &k);
10     string s;
11     cin >> s;
12     map<char, bool> m;
13     set<char> printed;
14     char pre = '#';
15     s = s + '#';
16     for(int i = 0; i < s.length(); i++) {
17         if(s[i] == pre) {
18             cnt++;
19         } else {
20             if(cnt % k != 0) {
21                 sureNoBroken[pre] = true;
22             }
23             cnt = 1;
24         }
25         if(i != s.length() - 1) m[s[i]] = (cnt % k == 0);
26         pre = s[i];
27     }
28     for(int i = 0; i < s.length() - 1; i++) {
29         if(sureNoBroken[s[i]] == true)
30             m[s[i]] = false;
31     }
32     for(int i = 0; i < s.length() - 1; i++) {
33         if(m[s[i]] && printed.find(s[i]) == printed.end()) {
34             printf("%c", s[i]);
35             printed.insert(s[i]);
36         }
37     }
38     printf("
");
39     for(int i = 0; i < s.length() - 1; i++) {
40         printf("%c", s[i]);
41         if(m[s[i]])
42             i = i + k - 1;
43     }
44     return 0;
45 }

通过在字符串的末尾添加“#”来判断最后一个字符

2020-07-11 22:10:01

 
永远渴望,大智若愚(stay hungry, stay foolish)
原文地址:https://www.cnblogs.com/h-hkai/p/12774484.html