1112. Stucked Keyboard (20)

1112. Stucked Keyboard (20)

时间限制
400 ms
内存限制
65536 kB
代码长度限制
16000 B
判题程序
Standard
作者
CHEN, Yue

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
题意:开头的keyboard很重要,一开始没认出是键盘看到样例的s就很疑惑,又读了一遍认出以后就秒懂题意。 有一把坏键盘,在输出时某几个特定的字符会连续打出k个,给定一条字符串,判断该字符串中有哪几个坏键(按出现顺序排列),并还原成正确的字符串

分析:如果某个字符是坏键,则当它出现时,一定有连续的n*k个,n>=1

           例如,k=2,aaaaabc,则abc均正常

           如果某个字符以好键的形式出现过,那么它一定是好键

           例如,k=3,aaabcda,则abcd均正常


           大概要注意的是这两个地方。做起来的感觉是,大致思路一下就有了,但是实现的时候会觉得很乱,各种要注意的地方很多,而且字符串操作太烦了,修修修修了半天,如果考试遇到这个肯定要跪。


#include<iostream>
#include<string>
using namespace std;
int map[500] = { 0 };//记录哪些字母or数字有问题 
int main()
{
	int k, i, j;
	cin >> k;
	string words, bad;
	cin >> words;
	for (i = 0; i<words.size(); i++)
	{
		j = 1;
		while (j < k && i + j < words.size()) {
			if (words[i] != words[i + j]) break;
			j++;//判断是否有k个连续,如果没有,break,导致j != k
		}
		if (j != k) {//说明words[i] 对应的 是好键
			map[(int)words[i]] = 1;// 1 代表好键
			if (bad.find(words[i]) != bad.npos)//假如输入aaabac,k=3,a开始会被判断成坏键,这里要把误判的修改回来 
				bad.erase(bad.find(words[i]));
		}
		else {
			if (map[(int)words[i]] != 1) {//如果已经确认是好键了,如abaaa,k=3,则不应该加入到坏键中
				map[(int)words[i]] = 2;// 2 代表坏键
				if (bad.find(words[i]) == bad.npos)//如果坏键中没有出现过该字符,则加入
					bad += words[i];
			}
			i += k - 1;//很重要,如aaabcd,k=3,假设这一轮i指向第一个a,下一轮i就应该指向b。
		}//如果i指向了第二个a,则a会被认为是好键
	}
	cout << bad << endl;
	for (i = 0; i<words.size(); i++)
		if (map[(int)words[i]] == 2) 
			words.erase(words.begin() + i + 1, words.begin() + i + k);
	cout << words << endl;
}


————————————————————————————————————————————————————

忽然发现,因为我的map只用了 1和2,所以实际上只要用 0和1,也能完美代替。

而且如果把0代表坏键,那么上面代码的第24行就不需要考虑有没有确认过是好键

以下是更改后的代码(其实就是删了两行然后改了一下最后的输出条件):

#include<iostream>
#include<string>
using namespace std;
int map[500] = { 0 };//记录哪些字母or数字有问题 ,0代表坏键,1代表好键
int main()
{
	int k, i, j;
	cin >> k;
	string words, bad;
	cin >> words;
	for (i = 0; i<words.size(); i++)
	{
		j = 1;
		while (j < k && i + j < words.size()) {
			if (words[i] != words[i + j]) break;
			j++;//判断是否有k个连续,如果没有,break,导致j != k
		}
		if (j != k) {//说明words[i] 对应的 是好键
			map[(int)words[i]] = 1;// 1 代表好键
			if (bad.find(words[i]) != bad.npos)//假如输入aaabac,k=3,a开始会被判断成坏键,这里要把误判的修改回来 
				bad.erase(bad.find(words[i]));
		}
		else {
			if (bad.find(words[i]) == bad.npos)//如果坏键中没有出现过该字符,则加入
				bad += words[i];
			i += k - 1;//很重要,如aaabcd,k=3,假设这一轮i指向第一个a,下一轮i就应该指向b。
		}//如果i指向了第二个a,则a会被认为是好键
	}
	cout << bad << endl;
	for (i = 0; i < words.size(); i++)
		if (!map[(int)words[i]])
			words.erase(words.begin() + i + 1, words.begin() + i + k);
	cout << words << endl;
}





posted @ 2018-01-07 13:30  九大于七  阅读(255)  评论(0编辑  收藏  举报