您的位置:首页 > 编程语言 > Java开发

#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,或者新旧字符串长度没有变化的,停止递归。

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类的区别
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  hihocoder java