PAT甲组1112.Stucked Keyboard思路解析和代码+测试样例

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
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
import java.util.HashMap; public class Manage { public static void main(String[] args) { HashMap<String, String> teacherClassMap = new HashMap<>(); // 存储老师和班级的对应关系 HashMap<String, String[]> groupMap = new HashMap<>(); // 存储班级和小组的对应关系 HashMap<String, String[]> classStudentMap = new HashMap<>(); // 存储班级和学生的对应关系 // 添加数据 teacherClassMap.put("小王", "一班"); teacherClassMap.put("小李", "二班"); teacherClassMap.put("小明", "三班"); groupMap.put("一班", new String[]{"一组", "二组", "三组"}); groupMap.put("二班", new String[]{"甲组", "乙组", "丙组"}); groupMap.put("三班", new String[]{"A组", "B组", "C组"}); classStudentMap.put("一班", new String[]{"一组学生1", "一组学生2", "一组学生3"}); classStudentMap.put("二班", new String[]{"甲组学生1", "甲组学生2", "甲组学生3"}); classStudentMap.put("三班", new String[]{"A组学生1", "A组学生2", "A组学生3"}); // 遍历数据 for (String teacher : teacherClassMap.keySet()) { String className = teacherClassMap.get(teacher); System.out.println(teacher + " 管理的班级是:" + className); for (String groupName : groupMap.keySet()) { String[] groupName = groupMap.get(className); System.out.println(className + " 所有的组是:" + groupName); String[] students = classStudentMap.get(groupName); for (String student : students) { System.out.println(" 学生姓名:" + student); } } } } }
最新发布
07-14
代码存在一些错误,我已经修改了一下: ```java import java.util.HashMap; public class Manage { public static void main(String[] args) { HashMap<String, String> teacherClassMap = new HashMap<>(); // 存储老师和班级的对应关系 HashMap<String, String[]> groupMap = new HashMap<>(); // 存储班级和小组的对应关系 HashMap<String, String[]> classStudentMap = new HashMap<>(); // 存储班级和学生的对应关系 // 添加数据 teacherClassMap.put("小王", "一班"); teacherClassMap.put("小李", "二班"); teacherClassMap.put("小明", "三班"); groupMap.put("一班", new String[]{"一组", "二组", "三组"}); groupMap.put("二班", new String[]{"甲组", "乙组", "丙组"}); groupMap.put("三班", new String[]{"A组", "B组", "C组"}); classStudentMap.put("一组", new String[]{"一组学生1", "一组学生2", "一组学生3"}); classStudentMap.put("二组", new String[]{"二组学生1", "二组学生2", "二组学生3"}); classStudentMap.put("三组", new String[]{"三组学生1", "三组学生2", "三组学生3"}); classStudentMap.put("甲组", new String[]{"甲组学生1", "甲组学生2", "甲组学生3"}); classStudentMap.put("乙组", new String[]{"乙组学生1", "乙组学生2", "乙组学生3"}); classStudentMap.put("丙组", new String[]{"丙组学生1", "丙组学生2", "丙组学生3"}); classStudentMap.put("A组", new String[]{"A组学生1", "A组学生2", "A组学生3"}); classStudentMap.put("B组", new String[]{"B组学生1", "B组学生2", "B组学生3"}); classStudentMap.put("C组", new String[]{"C组学生1", "C组学生2", "C组学生3"}); // 遍历数据 for (String teacher : teacherClassMap.keySet()) { String className = teacherClassMap.get(teacher); System.out.println(teacher + " 管理的班级是:" + className); String[] groups = groupMap.get(className); for (String groupName : groups) { System.out.println(className + " 所有的组是:" + groupName); String[] students = classStudentMap.get(groupName); for (String student : students) { System.out.println(" 学生姓名:" + student); } } } } } ``` 这段代码将会输出老师、班级、小组和学生的对应关系。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值