字符串分割

题目描述

给定一个非空字符串S,其被N个‘-’分隔成N+1个子串,给定正整数K,要求除第一个子串外,其余的子串需先合并为一个整体,再按每K个字符组成新的子串,所有新子串之间用‘-’分隔。对于每个新组成的子串,需按以下规则转换大小写:

  1. 若子串中小写字母数量 > 大写字母数量:将所有大写字母转换为小写字母;
  2. 若子串中大写字母数量 > 小写字母数量:将所有小写字母转换为大写字母;
  3. 若大小写字母数量相等:不做转换。 最终将第一个子串与所有转换后的新子串用‘-’连接,输出结果。

输入格式

输入为两行,第一行为正整数K,第二行为非空字符串S。

输出格式

输出为转换后的字符串。

示例

示例1
输入

1
2
3
12abc-abCABc-4aB@

输出

1
12abc-abc-ABC-4aB-@

示例2
输入

1
2
12
12abc-abCABc-4aB@

输出

1
12abc-abCABc4aB@
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import java.util.Scanner;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (sc.hasNextLine()) { // 注意 while 处理多个 case
int k = Integer.parseInt(sc.nextLine());
String[] strings = sc.nextLine().split("-");
String s = "";
for (int i = 1; i < strings.length; i++) {
s += strings[i];
}
int index = 0;
StringBuilder sb = new StringBuilder(strings[0]);
while (s.length() - index > k) {
sb.append("-" + check(s.substring(index, index + k)));
index += k;
}
if (sb.length() - index > 0) {
sb.append("-" + check(s.substring(index)));
}
System.out.println(sb.toString());
}
}
private static String check(String str) {
int upperNum = 0;
int lowerNum = 0;
for (int i = 0; i < str.length(); i++) {
char ch = str.charAt(i);
if (ch >= 'a' && ch <= 'z') {
lowerNum++;
} else if (ch >= 'A' && ch <= 'Z') {
upperNum++;
}
}
if (lowerNum > upperNum) {
return str.toLowerCase();
} else if (lowerNum < upperNum) {
return str.toUpperCase();
} else {
return str;
}
}
}

组成最大数

题目描述

小组中每位成员都有一张卡片,卡片上是 6 位内的正整数。将所有成员的卡片数字连起来可以组成多种不同的数字,要求计算能组成的最大数字。

输入描述

输入为用 “,” 号分割的多个正整数字符串,无需考虑非数字异常情况,小组人数最多 25 人。

输出描述

输出组成的最大数字字符串。

示例

示例 1

输入

1
22,221

输出

1
22221

示例 2

输入

1
4589,101,41425,9999

输出

1
9999458941425101
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (sc.hasNextLine()) {
String[] strings = sc.nextLine().split(",");
Arrays.sort(strings, (a, b) -> (b + a).compareTo(a + b));
StringBuilder sb = new StringBuilder();
for (String str : strings) {
sb.append(str);
}
System.out.println(sb.toString());
}
}
}

统计射击比赛成绩

题目描述

给定一个射击比赛成绩单,包含多个选手若干次射击的成绩分数,请对每个选手按其最高三个分数之和进行降序排名,输出降序排名后的选手 id 序列。

输入描述

输入第一行,一个整数 N,表示该场比赛总共进行了 N 次射击,产生 N 个成绩分数(2<=N<=100)

输入第二行,一个长度为 N 整数序列,表示参与每次射击的选手 id(0<=id<=99)

输入第三行,一个长度为 N 整数序列,表示参与每次射击选手对应的成绩(0<= 成绩 <=100)

输出描述

符合题设条件的降序排名后的选手 ID 序列

示例

输入

1
2
3
31
3,3,7,4,4,4,4,7,7,3,5,5,5
53,80,68,24,39,76,66,16,100,55,53,80,55

输出

1
5,3,7,4

说明

该场射击比赛进行了 13 次,参赛的选手为 {3,4,5,7}

3 号选手成绩 53,80,55 最高三个成绩的和为 188

4 号选手成绩 24,39,76,66 最高三个成绩的和为 205

5 号选手成绩 53,80,55 最高三个成绩的和为 188

7 号选手成绩 68,16,100 最高三个成绩的和为 184

比较各个选手最高 3 个成绩的和,有 4 号 > 3 号 = 5 号 > 7 号,由于 3 号和 5 号成绩相等,且 id 5>3,所以输出 5,3,7,4

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import java.util.*;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (sc.hasNextLine()) {
int n = Integer.parseInt(sc.nextLine());
List<Integer>ids = Arrays.stream(sc.nextLine().split(",")).map(
Integer::parseInt).collect(Collectors.toList());
List<Integer> scores = Arrays.stream(sc.nextLine().split(",")).map(
Integer::parseInt).collect(Collectors.toList());
Map<Integer, List<Integer>>id_scores = new HashMap<>();
for (int i = 0; i < n; i++) {
Integer id = ids.get(i);
Integer score = scores.get(i);
List<Integer> list = id_scores.getOrDefault(id, new ArrayList<>());
list.add(score);
id_scores.put(id, list);
}
StringBuilder sb = new StringBuilder();
id_scores.entrySet()
.stream()
.filter(x->x.getValue().size() >= 3)
.sorted((a, b)-> {
int asum = sum(a.getValue());
int bsum = sum(b.getValue());
if (asum == bsum) {
return b.getKey() - a.getKey();
} else {
return bsum - asum;
}
})
.map(Map.Entry::getKey)
.forEach(x->sb.append(x).append(","));
System.out.println(sb.toString().substring(0, sb.length() - 1));
}
}
private static int sum(List<Integer>list) {
list.sort(Integer::compareTo);
int ans = 0;
for (int i = list.size() - 1; i >= list.size() - 3; i--) {
ans += list.get(i);
}
return ans;
}
}

字符串序列判定

题目描述

输入两个字符串 S 和 L,都只包含英文小写字母。S 长度 <=100,L 长度 <=500,000。判定 S 是否是 L 的有效子串,判定规则如下:

S 中的每个字符在 L 中都能找到(可以不连续),且 S 在L中字符的前后顺序与 S 中顺序要保持一致。

(例如,S=”ace” 是 L=”abcde” 的一个子序列且有效字符是 a、c、e,而”aec” 不是有效子序列,且有效字符只有 a、e)

输入描述

输入两个字符串 S 和 L,都只包含英文小写字母。S 长度 <=100,L 长度 <=500,000。先输入 S,再输入 L,每个字符串占一行。

输出描述

S 串最后一个有效字符在 L 中的位置。(首位从 0 开始计算,无有效字符返回 - 1)

示例

示例 1

输入

1
2
ace
abcde

输出

1
4

示例 2

输入

1
2
fgh
abcde

输出

1
-1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import java.util.*;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (sc.hasNextLine()) {
String S = sc.nextLine();
String L = sc.nextLine();
int j = 0;
int ans = -1;
for (int i = 0; i < L.length(); i++) {
char lch = L.charAt(i);
char sch = S.charAt(j);
if (lch == sch) {
j++;
}
if (j == S.length()) {
ans = i;
break;
}
}
System.out.println(ans);
}
}
}

数据分类

题目描述

对一个数据 a 进行分类,分类方法为:此数据 a(四个字节大小)的四个字节相加对一个给定的值 b 取模,如果得到的结果小于一个给定的值 c,则数据 a 为有效类型,其类型为取模的值;如果得到的结果大于或者等于 c,则数据 a 为无效类型。

例如:

  1. 一个数据 a=0x01010101,b=3,按照分类方法计算 (0x01+0x01+0x01+0x01)%3=1

    如果 c=2,则此 a 为有效类型,其类型为 1

    如果 c=1,则此 a 为无效类型

  2. 一个数据 a=0x01010103,b=3,按照分类方法计算 (0x01+0x01+0x01+0x03)%3=0

    如果 c=2,则此 a 为有效类型,其类型为 0

    如果 c=0,则此 a 为无效类型

输入描述

输入 12 个数据,用空格分隔:

  • 第一个数据为 c
  • 第二个数据为 b
  • 剩余 10 个数据为需要分类的数据

输出描述

输出最多数据的有效类型有多少个数据

示例

示例 1

输入

1
3 4 256 257 258 259 260 261 262 263 264 265

输出

1
3

说明

10 个数据 4 个字节相加后的结果分别为 1 2 3 4 5 6 7 8 9 10

故对 4 取模的结果为 1 2 3 0 1 2 3 0 1 2

c 为 3,所以 0、1、2 都是有效类型

类型为 1 和 2 的有 3 个数据,类型为 0 的只有 2 个数据,故输出 3

示例 2

输入

1
1 4 256 257 258 259 260 261 262 263 264 265

输出

1
2

说明

10 个数据 4 个字节相加后的结果分别为 1 2 3 4 5 6 7 8 9 10

故对 4 取模的结果为 1 2 3 0 1 2 3 0 1 2

c 为 1,所以只有 0 是有效类型,类型为 0 的有 2 个数据,故输出 2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import java.util.*;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (sc.hasNextLine()) {
String []strings = sc.nextLine().split(" ");
int c = Integer.parseInt(strings[0]);
int b = Integer.parseInt(strings[1]);
Map<Integer, Integer>count = new HashMap<>();
for (int i = 2; i < strings.length; i++) {
int x = Integer.parseInt(strings[i]);
int sum = sum(x);
sum %= b;
if (sum < c) {
count.put(sum, count.getOrDefault(sum, 0) + 1);
}
}
int ans = 0;
for (int x : count.values()) {
ans = Math.max(ans, x);
}
System.out.println(ans);
}
}
private static int sum(int x) {
int byte1 = (x >> 24) & 0xFF;
int byte2 = (x >> 16) & 0xFF;
int byte3 = (x >> 8) & 0xFF;
int byte4 = x & 0xFF;
return byte1 + byte2 + byte3 + byte4;
}
}

5键键盘的输出

题目描述

有一个特殊的 5 键键盘,上面有 a,ctrl-c,ctrl-x,ctrl-v,ctrl-a 五个键,功能如下:

  • a 键:在屏幕上输出一个字母 a;
  • ctrl-c(对应数字 2):将当前选择的字母复制到剪贴板;
  • ctrl-x(对应数字 3):将当前选择的字母复制到剪贴板,并清空选择的字母;
  • ctrl-v(对应数字 4):将当前剪贴板里的字母输出到屏幕;
  • ctrl-a(对应数字 5):选择当前屏幕上的所有字母。

注意事项

  1. 剪贴板初始为空,新的内容被复制到剪贴板时会覆盖原来的内容;
  2. 当屏幕上没有字母时,ctrl-a 无效;
  3. 当没有选择字母时,ctrl-c 和 ctrl-x 无效;
  4. 当有字母被选择时,a 和 ctrl-v 这两个有输出功能的键会先清空选择的字母,再进行输出。

输入描述

输入为一行,为简化解析,用数字 1-5 代表五个键的输入,数字用空格分隔:

  • 1:a 键
  • 2:ctrl-c
  • 3:ctrl-x
  • 4:ctrl-v
  • 5:ctrl-a

输出描述

输出一个数字,为最终屏幕上字母的数量。

示例

示例 1

输入

1
1 1 1

输出

1
3

说明连续键入 3 个 a,故屏幕上字母的长度为 3。

示例 2

输入

1
1 1 5 1 5 2 4 4

输出

1
2

说明

输入两个 a 后 ctrl-a 选择这两个 a,再输入 a 时选择的两个 a 先被清空,所以此时屏幕只有一个 a,后续的 ctrl-a,ctrl-c 选择并复制了这一个 a,最后两个 ctrl-v 在屏幕上输出两个 a,故屏幕上字母的长度为 2(第一个 ctrl-v 清空了屏幕上的那个 a)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import java.util.*;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (sc.hasNextLine()) {
String [] strings = sc.nextLine().split(" ");
String screen = ""; //屏幕
String temp = ""; //剪切板
boolean selected = false; //是否被选择
for (int i = 0; i < strings.length; i++) {
int x = Integer.parseInt(strings[i]);
if (x == 1) {
if (selected) {
screen = "a";
selected = false;
} else {
screen += "a";
}
} else if (x == 2) {
if (selected) {
temp = screen;
}
} else if (x == 3) {
if (selected) {
temp = screen;
screen = "";
selected = false;
}
} else if (x == 4) {
if (selected) {
screen = temp;
selected = false;
} else {
screen += temp;
}
} else if (x == 5) {
if (!screen.equals("")) {
selected = true;
}
}
// System.out.println("screen=" + screen + ",temp=" + temp + ",selected=" +
// selected);
}
System.out.println(screen.length());
}
}
}

检查是否存在满足条件的数字组合

题目描述

给定一个正整数数组,检查数组中是否存在满足规则的数组组合。规则:A = B + 2×C。要求数组中的每个成员只能在结果算式中使用一次(如数组成员为 [0,0,1,5],算式 0=0+2×0 不允许,因为使用了 3 个 0)。

输入描述

第一行输入数组的元素个数;

第二行输出所有数组元素,用空格隔开。

输出描述

如果存在满足要求的数,在同一行里依次输出规则里 A、B、C 的取值,用空格隔开;

如果不存在,输出 0。

示例

示例 1

输入

1
2
4
2 7 3 0

输出

1
7 3 2

说明

7 = 3 + 2×2,数组中每个元素仅使用一次。

备注

  1. 数组长度在 3~100 之间;
  2. 数组成员为 0~65535;
  3. 数组成员可以重复,但每个成员只能在结果算式中使用一次;
  4. 用例保证每组数字里最多只有一组符合要求的解。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import java.util.*;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (sc.hasNextLine()) {
String []strings = sc.nextLine().split(" ");
int n = Integer.parseInt(strings[0]);
int []arr = new int[n];
for (int i = 1; i <= n; i++) {
arr[i - 1] = Integer.parseInt(strings[i]);
}
boolean ans = false;
Arrays.sort(arr);
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
for (int k = 0; k < n; k++) {
if (arr[k] == arr[j] + arr[i] * 2 && i != j && j != k && i != k) {
ans = true;
System.out.println(arr[k] + " " + arr[j] + " " + arr[i]);
}
}
}
}
if (!ans) {
System.out.println(0);
}
}
}
}

数组拼接

题目描述

现在有多组整数数组,需要将它们合并成一个新的数组。合并规则:从每个数组里按顺序取出固定长度的内容合并到新的数组中,取完的内容会删除掉;如果该行不足固定长度或者已经为空,则直接取出剩余部分的内容放到新的数组中,继续下一行。

输入描述

第一行是每次读取的固定长度,0 < 长度 < 10;

第二行是整数数组的数目,0 < 数目 < 1000;

第 3-n 行是需要合并的数组,不同的数组用回车换行分隔,数组内部用逗号分隔,最大不超过 100 个元素。

输出描述

输出一个新的数组,用逗号分隔。

示例

示例 1

输入

1
2
3
4
3
2
2,5,6,7,9,5,7
1,7,4,3,4

输出

1
2,5,6,1,7,4,7,9,5,3,4,7

说明

  1. 获得长度 3 和数组数目 2;
  2. 先遍历第一行,获得 2,5,6;
  3. 再遍历第二行,获得 1,7,4;
  4. 再循环回到第一行,获得 7,9,5;
  5. 再遍历第二行,获得 3,4;
  6. 再回到第一行,获得 7,按顺序拼接成最终结果。

示例 2

输入

1
2
3
4
5
4
3
1,2,3,4,5,6
1,2,3
1,2,3,4

输出

1
1,2,3,4,1,2,3,1,2,3,4,5,6
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import java.util.*;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (sc.hasNextLine()) {
int len = Integer.parseInt(sc.nextLine());
int cnt = Integer.parseInt(sc.nextLine());
List<String> list = new ArrayList<>();
for (int i = 1; i <= cnt; i++) {
list.add(sc.nextLine());
}
Map<Integer, Queue<Integer>>map = new HashMap<>();
for (int i = 0; i < list.size(); i++) {
String []strings = list.get(i).split(",");
Queue<Integer> queue = new ArrayDeque<>();
for (String str : strings) {
queue.offer(Integer.parseInt(str));
}
map.put(i, queue);
}
int num = 0;
List<Integer>ans = new ArrayList<>();
while (!map.isEmpty()) {
if (map.containsKey(num)) {
for (int i = 0; i < len; i++) {
if (map.get(num).isEmpty()) {
map.remove(num);
break;
}
ans.add(map.get(num).poll());
}
}
num++;
num %= list.size();
}
System.out.println(ans.toString().substring(1, ans.toString().length() - 1));
}
}
}

数列描述

题目描述

有一个数列 A [n],从 A [0] 开始每一项都是一个数字字符串,数列中 A [n+1] 是对 A [n] 的描述,生成规则如下:

  • A [0] = 1(初始项)
  • A [1] = 11:含义是 A [0] 由 “1 个 1” 组成,即从左到右连续出现 1 次 1
  • A [2] = 21:含义是 A [1] 由 “2 个 1” 组成,即从左到右连续出现 2 次 1
  • A [3] = 1211:含义是 A [2] 由 “1 个 2、1 个 1” 组成,即从左到右先连续出现 1 次 2,再连续出现 1 次 1
  • A [4] = 111221:含义是 A [3] 由 “1 个 1、1 个 2、2 个 1” 组成,即从左到右先连续出现 1 次 1,再连续出现 1 次 2,最后连续出现 2 次 1

给定整数 n(0<=n<=59),输出数列的第 n 项结果。

输入描述

输入一个整数 n,表示数列的第 n 项(0<=n<=59)。

输出描述

输出数列第 n 项的字符串内容。

示例

示例 1

输入

1
4

输出

1
111221
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import java.util.*;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
List<String>list = new ArrayList<>();
while (sc.hasNextLine()) {
int n = Integer.parseInt(sc.nextLine());
list.add("1");
for (int i = 1; i <= n; i++) {
String str = list.get(i - 1);
String str1 = process(str);
// System.out.println(str1);
list.add(str1);
}
System.out.println(list.get(n));
}
}
private static String process(String str) {
int len = str.length();
int i = 0;
int cnt = 0;
char ch;
StringBuilder sb = new StringBuilder();
while (i < len) {
ch = str.charAt(i);
while (str.charAt(i) == ch && i < len) {
cnt++;
i++;
if (i >= len) {
break;
}
}
sb.append(cnt).append(ch);
cnt = 0;
}
return sb.toString();
}
}

考勤信息

题目描述

公司用一个字符串来表示员工的出勤信息:

  • absent:缺勤
  • late:迟到
  • leaveearly:早退
  • present:正常上班

现需根据员工出勤信息,判断本次是否能获得出勤奖,能获得出勤奖的条件如下:

  1. 缺勤不超过一次;
  2. 没有连续的迟到 / 早退;
  3. 任意连续 7 次考勤,缺勤 / 迟到 / 早退不超过 3 次。

输入描述

第一行输入一个整数 n,表示有多少个员工;后面 n 行,每一行输入若干个字符串(用空格分隔),表示第 i 名员工的出勤信息。

输出描述

输出 n 行,每一行表示这名员工能否获得出勤奖,如果可以,则输出 “true”,否则输出 “false”。

示例

示例 1

输入

1
2
3
2
present
present absent present present leaveearly present absent

输出

1
true false

示例 2

输入

1
2
3
2
present
present present

输出

1
true true
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
import java.util.*;
import java.util.stream.Collectors;
public class Main {
static Map<String, Integer>map = new HashMap<>();
static {
map.put("absent", 0);
map.put("late", 1);
map.put("leaveearly", 1);
map.put("present", 2);
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (sc.hasNextLine()) {
int n = Integer.parseInt(sc.nextLine());
StringBuilder ans = new StringBuilder();
for (int i = 1; i <= n; i++) {
String str = sc.nextLine();
ans.append(judge(str) + " ");
}
System.out.println(ans.toString());
}
}
private static boolean judge(String str) {
String []strings = str.split(" ");
StringBuilder sb = new StringBuilder();
for (String str1 : strings) {
sb.append(map.get(str1));
}
String s = sb.toString();
int absentCnt = 0;
int len = s.length();
for (int i = 0; i < len; i++) {
char ch = s.charAt(i);
if (ch == '0') {
absentCnt++;
if (absentCnt > 1) {
return false;
}
} else if (ch == '1') {
if (s.charAt(i + 1) == '1' && i + 1 < len) {
return false;
}
}
if (i >= 6) {
int badCnt = 0;
for (int j = i; j >= i - 6; j--) {
if (s.charAt(j) != '2') {
badCnt++;
}
}
if (badCnt > 3) {
return false;
}
}
}
return true;
}
}