PAT A1112 Stucked Keyboard (20分)

1. 题目

给出一系列键盘输入,问是否有坏键。

2. 代码

  • 使用一个非法字符加在str后面,就可以判断前后字母是否相等,很方便。
  • 设置两个布尔数组,一个假设是坏键,一个确定不是坏键。只要有一次正确输入就可以确定不是坏键。
2.1 自己代码 (有点繁琐
#include <iostream>
#include <string>
#include <vector>
using namespace std;
const int maxn = 1010;

int main() {
  //freopen("input.txt", "r", stdin);
  int K;
  string str;
  cin >> K;
  cin.ignore();
  getline(cin, str);
  str = str + '*';    //str后加一个控制字符
  bool sure_not_broken[128] = {false};    //确定不是坏键
  bool is_broken[128] = {false};    //假设是坏键
  int broken_cnt[128] = {0};    //坏键出现次数
  vector<char> broken_order;

  for (int i = 1; i < str.size(); ++i) {
    if (str[i] == str[i - 1]) {   //前一个和后一个字符相等,计数
      broken_cnt[str[i - 1]]++;
    } else {    //如果前一个和后一个不一样
      broken_cnt[str[i - 1]]++;
      if (broken_cnt[str[i - 1]] % K != 0) {  //没有到达k次,可以确定不是坏键
        sure_not_broken[str[i - 1]] = true;
        broken_cnt[str[i - 1]] = 0;
      } else {//达到K次,先假设是坏键
        is_broken[str[i - 1]] = true;
        broken_order.push_back(str[i - 1]);
        broken_cnt[str[i - 1]] = 0;   //重新计数
      }
    }
  }
  bool is_count[128] = {false};
  for (int i = 0; i < broken_order.size(); ++i) {
    if (is_broken[broken_order[i]] && !sure_not_broken[broken_order[i]]) {    //如果确定是坏键,输出
      if (!is_count[broken_order[i]]) {
        printf("%c", broken_order[i]);
        is_count[broken_order[i]] = true;
      }
    }
  }
  printf("\n");
  string ans;
  str.erase(str.end() - 1);
  for (int i = 0; i < str.size(); ++i) {
    if (sure_not_broken[str[i]]) {
      ans += str[i];
    } else {
      ans += str[i];
      i += K - 1;
    }
  }
  printf("%s\n", ans.c_str());
  return 0;
}
2.2 柳神代码 (更简洁
#include <iostream>
#include <map>
#include <string>
#include <set>

using namespace std;
bool is_broken[128] = {false};
bool sure_no_broken[256] = {false};
set<char> need_print;

int main() {
  int n;
  string str;
  cin >> n;
  cin >> str;
  char pre = '@';     //pre表示当前字符的前一个字符
  int cnt = 1;
  for (int i = 0; i < str.size(); i++) {
    if (str[i] == pre) {    //如果当前字符和前一个字符一样,cnt++
      cnt++;
    } else {    //不一样
      if (cnt % n != 0) {   //如果未达到损坏的次数 确信没坏设置为true 就算后面出现达到损坏的次数也不作数
        sure_no_broken[pre] = true;
      }
      cnt = 1;    //重置为1
    }
    is_broken[str[i]] = (cnt % n == 0); //是否坏掉
    pre = str[i];   //前往下一个字符
  }
  for (int i = 0; i < str.size(); i++) {
    if (sure_no_broken[str[i]]) {   //如果确信没坏
      is_broken[str[i]] = false;    //坏掉置false
    }
  }
  for (int i = 0; i < str.size(); i++) {
    if (is_broken[str[i]] && need_print.find(str[i]) == need_print.end()) { //如果坏掉且未输出
      printf("%c", str[i]);
      need_print.insert(str[i]);
    }
  }
  printf("\n");
  for (int i = 0; i < str.length(); i++) {    //输出没坏的剩余字符
    printf("%c", str[i]);
    if (is_broken[str[i]])
      i = i + n - 1;
  }
  return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值