A1112
个人思路
哇,我要吐了,这道题自己的思路真的不太清晰,导致代码修改起来困难重重!!!!
逻辑真的太重要了!!!
该题为字符串处理问题,也有些文章使用stl处理
起初个人思路是比对连续K个字符(当出现K的倍数时,会出错),并统计字符连续出现的个数。
随后思路:遍历每个字符,统计从当前位置开始连续相同字符的个数(直到不相同为止),个数是K的倍数,说明是坏键,否则为好键
几点注意:
以K=3为例
- sss_s的特例,应该记录同一字符不同位置的最小次数
- bbbb_ccc,b的次数并非K的倍数,因此是好键,c为坏键
个人思路代码
测试点1未通过,始终未发现错误出在哪里
#include <bits/stdc++.h>
using namespace std;
int K, len;
char str[1005];
//poscnt:字符串第i个字符连续重复的次数,keycnt:字母i在字符串中最小的重复次数()
int poscnt[1005], keycnt[1005];
//isBroke:按键好坏,isprint:输出错误字符时,避免重复输出
bool isBroken[150], isPrint[150];
int main(int argc, char *argv[]) {
scanf("%d", &K);
getchar();
scanf("%s", str);
len = strlen(str);
memset(isBroken, true, sizeof(isBroken));
for(int i = 0; i < len; ++i)
{
int pos = str[i];
poscnt[i]++;
for(int j = i + 1; str[j] == str[i]; ++j)//向后遍历K位
{
if(str[j] != str[i])//K位之内有一位与str[i]不同
break;
else
{
poscnt[i]++;
}
}
if(str[i] == str[i - 1] && i != 0)//保证连续重复的字符存储最大的重复次数
poscnt[i] = max(poscnt[i], poscnt[i - 1]);
}
//统计同一字符不同位置出现的最小次数,并判断按键好坏
for(int i = 0; i < len; ++i)
{
int pos = str[i];
if(keycnt[pos] == 0)//第一次遇到字母str[i]直接赋值
keycnt[pos] = poscnt[i];
else//取最小值
keycnt[pos] = min(keycnt[pos], poscnt[i]);//存储同一字符不同位置出现的最小次数,避免故意按k次
if(keycnt[pos] % K != 0)//判断按键好坏,不是k的倍数,说明是好键
isBroken[pos] = false;
}
//输出
for(int i = 0; i < len; ++i)
{
int pos = str[i];
if(isPrint[pos] == false && isBroken[pos] == true)
{
printf("%c", pos);
isPrint[pos] = true;
}
}
printf("\n");
for(int i = 0; i < len; ++i)
{
int pos = str[i];
if(keycnt[pos] % K != 0)
printf("%c", str[i]);
else
{
printf("%c", str[i]);
i += K - 1;
}
}
return 0;
}
本题思路
问题都是出在 统计同一字符不同位置出现的最小次数,并判断按键好坏
进行了优化,去掉了keycnt[]数组
AC代码
#include <bits/stdc++.h>
using namespace std;
int K, len;
char str[1005];
//poscnt:字符串第i个字符连续重复的次数
int poscnt[1005];
//isBroke:按键好坏,isprint:输出错误键时防止重复输出
bool isBroken[150], isPrint[150];
int main(int argc, char *argv[]) {
scanf("%d", &K);
getchar();
scanf("%s", str);
len = strlen(str);
memset(isBroken, true, sizeof(isBroken));
for(int i = 0; i < len; ++i)
{
int pos = str[i];
poscnt[i]++;
for(int j = i + 1; str[j] == str[i]; ++j)//向后遍历K位
{
if(str[j] != str[i])//K位之内有一位与str[i]不同
break;
else
{
poscnt[i]++;
}
}
if(str[i] == str[i - 1] && i != 0)//保证连续重复的字符存储最大的重复次数
poscnt[i] = max(poscnt[i], poscnt[i - 1]);
}
//统计同一字符不同位置出现的最小次数,并判断按键好坏
for(int i = 0; i < len; ++i)
{
//优化!!逻辑太乱了!!!实在是太傻了
int pos = str[i];
if(poscnt[i] % K == 0)
continue;
else
isBroken[pos] = false;
/*if(keycnt[pos] == 0)//第一次遇到字母str[i]直接赋值
keycnt[pos] = poscnt[i];
else//取最小值
{
if(keycnt[pos] % K != 0)//更新keycnt后,判断为好键
{
isBroken[pos] = false;
continue;
}
if(poscnt[i] % K != 0)//当前为好键
{
keycnt[pos] = poscnt[i];
isBroken[pos] = false;
continue;
}
keycnt[pos] = min(keycnt[pos], poscnt[i]);//存储同一字符不同位置出现的最小次数,避免故意按k次
}
if(keycnt[pos] % K != 0)//判断按键好坏,不是k的倍数,说明是好键
isBroken[pos] = false;*/
}
//输出
for(int i = 0; i < len; ++i)
{
int pos = str[i];
if(isPrint[pos] == false && isBroken[pos] == true)
{
printf("%c", pos);
isPrint[pos] = true;
}
}
printf("\n");
for(int i = 0; i < len; ++i)
{
int pos = str[i];
if(isBroken[pos] == false)//优化
printf("%c", str[i]);
else
{
printf("%c", str[i]);
i += K - 1;
}
}
return 0;
}
附赠测试样例,为了找BUG不择手段
3
thiiis_iiisss_a_teeeeeest
ans
ie
this_isss_a_teest
3
thiiisss_iiis
ans
i
thisss_is
3
eeeeee
ans
e
ee
6
eeeeee
ans
e
e
3
abcd
ans
abcd
3
sss_s
ans
sss_s
3
aaabbbccceeeabc
ans
e
aaabbbccceabc
3
aaabbbcccceeeabc
ans
e
aaabbbcccceabc
3
cccaaaaabbbb
ans
c
caaaaabbbb
3
eeeesseeeaaa
ans
eeeessa
3
sss_ssss
ans
sss_ssss