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

 初稿,记录了思路历程,测试点1不过:(测试点1的情况是:前面出现了k次,可能是坏键,后面那个可能是坏键的键又出现了不是k的倍数次)。我想前面判断是坏键,后面不可能出现不是k倍次数。因为:. The stucked key will always repeat output for a fixed k times whenever it is pressed. 所以想到这种情况我就把它舍弃了,因为这不合题意。但是这种情况还有一种解释:那个可能是坏键的键本来就是好的,只不过前面恰好出现了k次。只是巧合而已

#include <iostream>
#include <vector>
#include <string>

using namespace std;

int k;

bool checkkey(int i, string s)
{
	//for (int j = 1; j < k; j++)
	//{
	//	if (s[i] != s[i + j])
	//	{
	//		return true;
	//	}
	//}
	//
	首次出现连续三个,大于k=2会误判

	//if (s[i + k - 1] == s[i + k])
	//{
	//	return true;
	//}

	//return false;

	//新思路
	int cnt = 1;
	char c = s[i];
	for (int j = i + 1; j < s.length(); j++)
	{
		if (c == s[j])
		{
			cnt++;
		}
		else
		{
			break;
		}
	}

	/*if (cnt%k == 0)
	{
		return false;
	}
	else
	{
		return true;
	}	*/
	return cnt % k == 0 ? false : true;
}

int main()
{
	freopen("in.txt", "r", stdin);
	cin >> k;
	getchar();
	vector<bool> book(256, false), broken(256);
	vector<char> ans;
	string s;
	getline(cin, s);
	/*cin >> s;*/
	int len = s.length();
	for (int i = 0; i < len; i++ )
	{
		if (!book[s[i]  ])//没有遍历过
		{
			book[s[i]  ] = true;
			//新思路
			
			broken[s[i]  ] = checkkey(i, s);
			ans.push_back(broken[s[i]  ] ? '\0' : s[i]);
			
			//if (!checkkey(i, s))//broken key
			//{
			//	ans.push_back(s[i]);
			//	broken[s[i]  ] = false;

			//}
			//else
			//{
			//	broken[s[i]  ] = true;
			//	i++;
			//}

			//else//末尾的不够k个的,自动认为不是坏键
			//{
			//	broken[s[i]  ] = true;
			//	i++;
			//}
		}
		//遍历过其实啥都不用干 ,我已经知道你是不是坏键了,接着遍历就行了,如果我把checkkey函数写在main里,我就可以i+cnt,这样可以少算几步,不过懒得移下来,无所谓了

		//else//输出过,看是否为坏键
		//{
		//	/*if (broken[s[i]  ])
		//	{
		//		i++;
		//	}
		//	else
		//	{
		//		i +k;
		//	}*/
		//	i++;
		//}
	}
	//output
	for (auto c : ans)
	{
		if (c!='\0')
		{
			cout << c;
		}		
	}
	cout << endl;
	for (int i = 0; i < len; )
	{
		cout << s[i];
		if (broken[s[i]  ])
		{
			i++;
		}
		else
		{
			i += k;
		}
	}
	cout << endl;
	return 0;
}

次稿: (这时只有测试点1不过,因为我舍弃了点1那种情况觉得不可能出现那种情况)

#include <iostream>
#include <vector>
#include <string>

using namespace std;

int main()
{
	//freopen("in.txt", "r", stdin);
	int k;
	cin >> k;
	getchar();
	vector<bool> book(256,false),broken(256);//book is ture表示遍历过;broken is ture表示好键
	vector<char> ans;//储存坏键
	string s;
	getline(cin, s);
	int len = s.length();
	for (int i = 0; i < len; i++)
	{		
		if (!book[s[i]])
		{
			book[s[i]] = true;
			int cnt = 1;
			for (int j = 1; i + j < len; j++)
			{
				if (s[i] == s[i + j])
				{
					cnt++;
				}
				else
				{
					break;
				}
			}
			broken[s[i]] = (cnt%k == 0 ? false : true);//cnt是k的倍数说明是坏的
			if (!broken[s[i]])
			{
				ans.push_back(s[i]);//记住坏键
			}
			i += cnt-1;//思路慢慢清晰和简单,这里我又想到,不需要book数组,不用看是否遍历过,因为之前思路遍历过其实啥也不用干,这里i+=cnt之后,所有i肯定都没有遍历过,因为遍历过的是相同的那段,都已经+cnt跳过了,不过我还是选了之前的做法,不然的话在记住坏键的时候得检查是否已经记住过
		}		
	}
	//output
	for (auto c:ans)
	{
		cout << c;
	}
	cout << endl;
	for (int i = 0; i < len; )
	{
		cout << s[i];
		broken[s[i]] ? i++ : i += k;
	}
	return 0;
}

 

吾思:(终稿)

#include <iostream>
#include <vector>
#include <string>

using namespace std;

int main()
{
	//freopen("in.txt", "r", stdin);
	int k;
	cin >> k;
	getchar();
	vector<bool> book(256, false), broken(256);//book is ture表示遍历过;broken is ture表示好键
	vector<char> ans;//储存坏键
	string s;
	getline(cin, s);
	int len = s.length();
	for (int i = 0; i < len; )
	{	
		int cnt = 1;
		for (int j = 1; i + j < len; j++)
		{
			if (s[i] == s[i + j])//统计相同的这段中有多少相同字符
			{
				cnt++;
			}
			else
			{
				break;
			}
		}
		broken[s[i]] = (cnt%k == 0 ? false : true);//cnt是k的倍数说明是坏的
		bool added = false;
		for (auto c:ans)//检查有没有记住过s[i]
		{
			if (c == s[i])
			{
				added = true;
			}
		}
		if (!broken[s[i]]&&!added)//是坏键而且没有记住过
		{
			ans.push_back(s[i]);//记住坏键
		}
		//跳过相同的字符
		i += cnt;//思路慢慢清晰和简单,这里我又想到,不需要book数组,不用看是否遍历过,因为之前思路遍历过其实啥也不用干,这里i+=cnt之后,所有i肯定都没有遍历过,因为遍历过的是相同的那段,都已经+cnt跳过了,不过我还是选了之前的做法,不然的话在记住坏键的时候得检查是否已经记住过
	}
	//output
	for (auto c : ans)
	{
		if (!broken[c])
		{
			cout << c;
		}	
	}
	cout << endl;
	for (int i = 0; i < len; )
	{
		cout << s[i];//就算是坏键,他也要输出一次,所以不管好坏,最起码要输出一次
		broken[s[i]] ? i++ : i += k;
	}
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值