#hihocoder #1039 字符消除
2015-09-16 18:35
519 查看
总结自己的代码能力,就是渣渣渣。找工作,看到各路大神高歌猛进,自己却…因此痛定思痛,困而学之,决定悔改自新,从头来过…
题目:#1039 : 字符消除
小Hi最近在玩一个字符消除游戏。给定一个只包含大写字母”AB C”的字符串s,消除过程是如下进行的:
如果s包含长度超过1的由相同字母组成的子串,那么这些子 串会被同时消除,余下的子串拼成新的字符串。例如”ABCCBCCC AA”中”CC”,”CCC”和”AA”会被同时消除,余下”AB”和”B”拼成新 的字符串”ABB”。
上述消除会反复一轮一轮进行,直到新的字符串不包含相邻的相同字符为止。例如”ABCCBCCCAA”经过一轮消除得到”ABB”,再经过一轮消除得到”A”
游戏中的每一关小Hi都会面对一个字符串s。在消除开始前小Hi有机会在s中任意位置(第一个字符之前、最后一个字符之后以及相邻两个字符之间)插入任意一个字符(‘A’,’B’或者’C’),得到字符串t。t经过一系列消除后,小Hi的得分是消除掉的字符的总数。
请帮助小Hi计算要如何插入字符,才能获得最高得分。
Input
输入第一行是一个整数T(1<=T<=100),代表测试数据的数量。
之后T行每行一个由’A”B”C’组成的字符串s,长度不超过100。
Output
对于每一行输入的字符串,输出小Hi最高能得到的分数。
Hint
第一组数据:在”ABCBCCCAA”的第2个字符后插入’C’得到”ABCCBCCCAA”,消除后得到”A”,总共消除9个字符(包括插入的’C’)。
第二组数据:”AAA”插入’A’得到”AAAA”,消除后得到”“,总共消除4个字符。
第三组数据:无论是插入字符后得到”AABC”,”ABBC”还是”ABCC”都最多消除2个字符。
Sample Input
3
ABCBCCCAA
AAA
ABC
Sample Output
9
4
2
这道题目比较简单直接,主要考察对于字符的操作,需要依次遍历原字符串每个位置(共n+1个位置,假设字符串长度为n)分别添加‘A’,‘B’,‘C’的情况,一共有3*(n+1)种情况。然后对每种情况的字符串做处理。
依次判断相邻字符是否相等,设置一个计数变量。对于相等的情况,一开始的想法是对原字符串相应位置重置为一个不会出现的字符,比如‘D’,然后下一步再将其去除,递归处理新产生的字符串。对于新字符串长度为1,或者新旧字符串长度没有变化的,停止递归。
由于有对字符的操作,一开始使用了char数组,操作比较繁琐,后来考虑使用了String类,题目中对String的拼接较多,因此使用了Stringbuilder类。本来StringBuilder的操作比char数组慢一些,但是char数组什么需要提前定义大小,因此中间多了一步关于‘D’的操作,总体速度反而满了。
微末道行,暂时就这样了,有时间再多修改自己的代码。过阵子回头来看自己,觉得自己当初怎么这么渣就对了,表面那是功力比现在好…
Java中的知识点:
1.String类与StringBuilder类的区别
对String对象的任何改变都不影响到原对象,相关的任何change操作都会生成新的对象
String str=”hello world”和String str=new String(“hello world”)的区别(是否产生新的对象)
String、StringBuffer以及StringBuilder的区别(是否产生新的字符串、线程安全)
2.char数组与String类的区别
题目:#1039 : 字符消除
小Hi最近在玩一个字符消除游戏。给定一个只包含大写字母”AB C”的字符串s,消除过程是如下进行的:
如果s包含长度超过1的由相同字母组成的子串,那么这些子 串会被同时消除,余下的子串拼成新的字符串。例如”ABCCBCCC AA”中”CC”,”CCC”和”AA”会被同时消除,余下”AB”和”B”拼成新 的字符串”ABB”。
上述消除会反复一轮一轮进行,直到新的字符串不包含相邻的相同字符为止。例如”ABCCBCCCAA”经过一轮消除得到”ABB”,再经过一轮消除得到”A”
游戏中的每一关小Hi都会面对一个字符串s。在消除开始前小Hi有机会在s中任意位置(第一个字符之前、最后一个字符之后以及相邻两个字符之间)插入任意一个字符(‘A’,’B’或者’C’),得到字符串t。t经过一系列消除后,小Hi的得分是消除掉的字符的总数。
请帮助小Hi计算要如何插入字符,才能获得最高得分。
Input
输入第一行是一个整数T(1<=T<=100),代表测试数据的数量。
之后T行每行一个由’A”B”C’组成的字符串s,长度不超过100。
Output
对于每一行输入的字符串,输出小Hi最高能得到的分数。
Hint
第一组数据:在”ABCBCCCAA”的第2个字符后插入’C’得到”ABCCBCCCAA”,消除后得到”A”,总共消除9个字符(包括插入的’C’)。
第二组数据:”AAA”插入’A’得到”AAAA”,消除后得到”“,总共消除4个字符。
第三组数据:无论是插入字符后得到”AABC”,”ABBC”还是”ABCC”都最多消除2个字符。
Sample Input
3
ABCBCCCAA
AAA
ABC
Sample Output
9
4
2
这道题目比较简单直接,主要考察对于字符的操作,需要依次遍历原字符串每个位置(共n+1个位置,假设字符串长度为n)分别添加‘A’,‘B’,‘C’的情况,一共有3*(n+1)种情况。然后对每种情况的字符串做处理。
依次判断相邻字符是否相等,设置一个计数变量。对于相等的情况,一开始的想法是对原字符串相应位置重置为一个不会出现的字符,比如‘D’,然后下一步再将其去除,递归处理新产生的字符串。对于新字符串长度为1,或者新旧字符串长度没有变化的,停止递归。
import java.util.Scanner; public class Main { private static void earse(String input) { int res = 0; int max = 0; char[] cArray = new char[input.length() + 1]; char[] change = {'A', 'B', 'C'}; for (int k = 0; k < 3; k++) { for (int i = 0; i < input.length() + 1; i++) { cArray[i] = change[k]; for (int j = 0; j < i; j++) { cArray[j] = input.charAt(j); } for (int j = i + 1; j < input.length() + 1; j++) { cArray[j] = input.charAt(j-1); } res = earse(cArray); if (res > max) { max = res; } } } System.out.println(max); } private static int earse(char[] cArray) { if (cArray.length <= 1) { return 0; } int res = 0; for (int i = 0; i < cArray.length; i++) { int cnt = 1; while (i < cArray.length - 1 && cArray[i+1] == cArray[i]) { i++; cnt++; } res += (cnt != 1 ? cnt : 0); if (cnt != 1) { for (int j = i + 1 - cnt; j <= i; j++) { cArray[j] = 'D'; } } } if (String.valueOf(cArray).matches(".*D.*") && cArray.length - res >= 2) { char[] nChar = new char[cArray.length - res]; int j = 0; for (int i = 0; i < cArray.length; i++) { if (cArray[i] != 'D') { nChar[j++] = cArray[i]; } } return res + earse(nChar); } else { return res; } } public static void main(String[] args) { Scanner sin = new Scanner(System.in); int N = sin.nextInt(); while(N-- != 0){ String P = sin.next(); earse(P); } } }
由于有对字符的操作,一开始使用了char数组,操作比较繁琐,后来考虑使用了String类,题目中对String的拼接较多,因此使用了Stringbuilder类。本来StringBuilder的操作比char数组慢一些,但是char数组什么需要提前定义大小,因此中间多了一步关于‘D’的操作,总体速度反而满了。
import java.util.Scanner; public class Main { private static void earse(StringBuilder input) { int res = 0; int max = 0; StringBuilder cArray = new StringBuilder(); char[] change = {'A', 'B', 'C'}; for (int k = 0; k < 3; k++) { for (int i = 0; i < input.length() + 1; i++) { if (i == 0) { cArray.append(change[k]).append(input); } else if (i == input.length()) { cArray.append(input).append(change[k]); } else { cArray.append(input.subSequence(0, i)) .append(change[k]). append(input.subSequence(i, input.length())); } res = earse2(cArray); if (res > max) { max = res; } cArray.delete(0, cArray.length()); } } System.out.println(max); } private static int earse2(StringBuilder cArray) { if (cArray.length() <= 1) { return 0; } int res = 0; StringBuilder nChar = new StringBuilder(); for (int i = 0; i < cArray.length(); i++) { int cnt = 1; while (i < cArray.length() - 1 && cArray.charAt(i+1) == cArray.charAt(i)) { i++; cnt++; } if (cnt == 1) { // 使用正向添加,不是反向删除,速度略有加快 nChar.append(cArray.charAt(i)); } else { res += cnt; } } if (cArray.length() - nChar.length() > 0 && nChar.length() >= 2) { return res + earse2(nChar); } else { return res; } } public static void main(String[] args) { Scanner sin = new Scanner(System.in); int N = sin.nextInt(); while(N-- != 0){ String P = sin.next(); earse(new StringBuilder(P)); } } }
微末道行,暂时就这样了,有时间再多修改自己的代码。过阵子回头来看自己,觉得自己当初怎么这么渣就对了,表面那是功力比现在好…
Java中的知识点:
1.String类与StringBuilder类的区别
对String对象的任何改变都不影响到原对象,相关的任何change操作都会生成新的对象
String str=”hello world”和String str=new String(“hello world”)的区别(是否产生新的对象)
String、StringBuffer以及StringBuilder的区别(是否产生新的字符串、线程安全)
2.char数组与String类的区别
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序
- 二叉查找树
- [原创]java局域网聊天系统