• 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)
  • 相关阅读:
    Android开发规范
    驱动开发规范
    USER 版本与ENG 版本差异
    解决:更改短信中心号码不能及时更新显示
    深度分析:Android中Mms设置页面更改短信中心号码流程
    Android中Parcel的分析以及使用
    DialogFragment详解
    开启飞行模式,进入信息,再关闭飞行模式,进入信息设置查看短信息中心号码,有时短信息中心号码显示无。
    研究 iOS 摄像头缩放的内容
    iOS图片缓存库基准对比
  • 原文地址:https://www.cnblogs.com/h-hkai/p/12774484.html
Copyright © 2020-2023  润新知