题目
时间限制: 3000MS
内存限制: 589824KB
题目描述:
小明很喜欢打字,今天小红给了小明一个字符串。
这个字符串只包含大写和小写字母。
我们知道,按下CapsLock键,可以切换大小写模式。
我们在小写模式时候,同时按下shift+字母键,就能写出大写字母。
在大写模式的时候,按下shift+字母键,就能写出小写字母。
现在问题来了,给你一个字符串,问你最少使用多少个按键,就可以写出这个字符串呢?
注意,按shift和字母键,算两次按键。开始时均为小写状态。
感觉代码没有问题,但赛码网提示只有9%AC。不知道因为什么?
太晚了,改天再分析。
输入描述
第一行一个T,表示有T组输入。
接下来T组数据:
每组数据一个字符串s,s的长度小于等于100。仅包含大小写字母。
输出描述
对于每组数据,输出最少按键次数。
样例输入
3
A
AA
AAAAAA
样例输出
2
3
7
import java.util.Scanner;
/**
* @author songquanheng
* 2022/1/25-22:01
*/
public class Huiwen {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
for (int i=0; i<n; i++) {
String str = scanner.next();
System.out.println(click(str));
}
}
public static int click(String str) {
boolean lowercaseMode = true;
int click = 0;
char[] chars = str.toCharArray();
for (int i = 0; i < chars.length; i++) {
char ch = chars[i];
if (i == chars.length - 1) {
if ((lowercaseMode && Character.isLowerCase(ch)) || (!lowercaseMode &&Character.isUpperCase(ch))) {
click++;
continue;
} else {
click += 2;
continue;
}
}
char nextChar = chars[i + 1];
if (lowercaseMode) {
if (Character.isLowerCase(ch)) {
click++;
continue;
}
if (Character.isUpperCase(ch) && Character.isLowerCase(nextChar)) {
// 不切换大小写模式
click += 2;
continue;
}
if (Character.isUpperCase(ch) && Character.isUpperCase(nextChar)) {
click += 2;
lowercaseMode = false;
}
} else {
if (Character.isUpperCase(ch)) {
click++;
continue;
}
if (Character.isLowerCase(ch) && Character.isUpperCase(nextChar)) {
// 不切换大小写
click += 2;
continue;
}
if (Character.isLowerCase(ch) && Character.isLowerCase(nextChar)) {
click += 2;
lowercaseMode = true;
}
}
}
return click;
}
/**
* 在字符串头部或者尾部添加1个字符串,判断能否成为回文字符串
*
* @param text 待判断的字符串
* @return
*/
public static boolean canBecomeHuiweb(String text) {
int i = 0;
char[] chars = text.toCharArray();
while (chars[i] == chars[chars.length - 1 - i] && i<(chars.length-1)/2) {
i++;
}
text = text.substring(i, text.length() - i);
String substring = text.substring(0, 1);
String subString2 = text.substring(text.length() - 1, text.length());
String res = text + substring;
return isHuiweb(res) || isHuiweb(subString2 + text);
}
public static boolean isHuiweb(String text) {
char[] chars = text.toCharArray();
StringBuilder stringBuilder = new StringBuilder();
for (int i = chars.length - 1; i >= 0; i--) {
stringBuilder.append(chars[i]);
}
String res = stringBuilder.toString();
return res.equals(text);
}
}
===
这道题目让我有点崩溃,周六花了两个小时,还是没有做出AC的程序。
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int groups = scanner.nextInt();
for (int i = 0; i < groups; i++) {
String input = scanner.next();
System.out.print(new Main().minimalKey(input));
System.out.println();
}
}
private int minimalKey(String input) {
// 键入次数
int count = 0;
boolean lowerMode = true;
List<Record> records = getRecords(input);
for (int i = 0; i < records.size(); i++) {
Record record = records.get(i);
if (same(byMode(lowerMode), record.getaChar())) {
// 大小写模式与待处理的记录相同
count += record.getNumber();
continue;
}
// 处理大小写模式与待处理记录不相同的情形
if (record.getNumber() > 1) {
// 点击capslock
count += record.getNumber();
count += 1;
lowerMode = !lowerMode;
} else {
count += 2;
// 通过shift进行键入
if (i == records.size() - 1) {
} else {
}
}
}
return count;
}
/**
* 获取相同大小写的统计
*
* @param input 输入的字符串
* @return
*/
private List<Record> getRecords(String input) {
List<Record> records = new ArrayList<>();
Character current = null;
int cnt = 1;
if (input.length() == 0) {
return records;
}
if (input.length() == 1) {
records.add(new Record(byCurrent(input.charAt(0)), 1));
return records;
}
for (int i = 0; i < input.length(); i++) {
if (current == null) {
current = input.charAt(i);
continue;
}
// 统计相同大小写的个数
// 注意: 退出while循环的条件是第i个字符与当前不同或者i与长度相同
while (i < input.length() && same(current, input, i)) {
cnt++;
i++;
}
records.add(new Record(byCurrent(current), cnt));
if (i < input.length()) {
// 这表明same函数为假
current = negateCurrent(current);
cnt = 1;
}
// 处理AAAA或者aaa这种最后的连续的情况,相当于边界情况
if (i == input.length() - 1) {
records.add(new Record(byCurrent(current), cnt));
}
}
return records;
}
private char byCurrent(Character current) {
if (Character.isLowerCase(current)) return 'a';
else return 'A';
}
private char byMode(boolean lowerMode) {
if (lowerMode) {
return 'a';
} else {
return 'A';
}
}
private char negateCurrent(Character current) {
if (Character.isLowerCase(current)) return 'A';
else return 'a';
}
private boolean same(Character current, String input, int i) {
char ch = input.charAt(i);
return same(current, ch);
}
private boolean same(Character current, char ch) {
boolean bothLower = Character.isLowerCase(current) && Character.isLowerCase(ch);
boolean bothUpper = Character.isUpperCase(current) && Character.isUpperCase(ch);
return bothLower || bothUpper;
}
}
class Record {
private char aChar;
private int number;
public Record(char aChar, int number) {
this.aChar = aChar;
this.number = number;
}
public char getaChar() {
return aChar;
}
public void setaChar(char aChar) {
this.aChar = aChar;
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
@Override
public String toString() {
return "Record{" +
"aChar=" + aChar +
", number=" + number +
'}';
}
}