PAT(A) - 1112. Stucked Keyboard (20)


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<k<=100 ) 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


思路分析:20分的题不容易拿全分。我把注释写的很详细,直接看程序吧。


#include <cstdio>
#include <string>
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

// 10代表0~9的数字,26代表26个英文字母,1代表那一个空格
// 所以数组长度为10 + 26 + 1
int visit[10 + 26 + 1] = { 0 };  // 访问数组,如果访问过标记为1

// 检查是否是坏掉字符的函数
// 前提坏掉的字符出现次数一定是k的倍数,这步在main函数中已经进行判断
// 然后遍历原字符串中所有只含有字符c的子串,
// 如果所有子串也满足字符c的次数是k的倍数,则说明c是坏字符,否则是假
bool judge( char c, string str, int k ) {
    int count = 0;
    string s;
    for( int i = 0; i < str.size(); i++ ) {
        if( str[i] == c ) {
            s = s + c;
        }
        else {
            if( !s.empty() ) {
                //cout << s << endl;
                int len = s.size();
                if( len % k == 0 ) continue;
                else return false;
            }
            s.clear();
        }
    }
    return true;
}
int main() {
    //freopen( "123.txt", "r", stdin );
    int k;
    scanf( "%d", &k );
    int ch[10 + 26 + 1] = { 0 };    // 刚开始将可能出现的所有字符数量初始化为0

    string str;
    cin >> str;

    for( int i = 0; i < str.size(); i++ ) { // 对出现的每个字符统计次数
        if( str[i] >= '0' && str[i] <= '9' ) {
            ch[str[i] - '0']++;
        }
        else if( str[i] == '_' ) {
            ch[36]++;
        }
        else {
            ch[str[i] - 'a' + 10]++;
        }
    }

    vector<char> vec;   // vec中存放可能坏掉的字符
    bool flag = false;  
    // 开始判断可能是坏掉的字符
    // 因为最后输出坏掉字符的顺序要和输入一直,所以从原字符串的顺序遍历
    for( int i = 0; i < str.size(); i++ ) {
        int index = 0;  // index是字符对应的数组小标
        if( str[i] >= '0' && str[i] <= '9' ) index = str[i] - '0';
        else if( str[i] >= 'a' && str[i] <= 'z' ) index = str[i] - 'a' + 10;
        else index = 36;
        if( visit[index] == 0 ) {   // 如果还没访问过
            if( ch[index] != 0 && ch[index] % k == 0 ) {    // 如果是坏掉的字符,则出现次数必定为k的倍数
                flag = judge( str[i], str, k );     // 检查是否是坏的字符
                if( flag ) vec.push_back( str[i] ); // 加入容器
            }
            visit[index] = 1;   // 标记为1,说明已经访问过了
        }
    }

    // 按顺序输出坏掉的字符
    for( int i = 0; i < vec.size(); i++ ) {
        printf( "%c", vec[i] );
    }
    
    printf( "\n" );
    // 再输出应该打印的正确结果
    for( int i = 0; i < str.size(); i++ ) {
        if( find( vec.begin(), vec.end(), str[i] ) == vec.end() ) {
            printf( "%c", str[i] );
        }
        else {
            if( k == 1 ) continue;  // 注意这里当k = 1时,说明所有键都坏掉了,则什么也不输出
            printf( "%c", str[i] );
            i = i + k - 1;
        }
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值