字符串分割
题目描述
给定一个非空字符串S,其被N个‘-’分隔成N+1个子串,给定正整数K,要求除第一个子串外,其余的子串需先合并为一个整体,再按每K个字符组成新的子串,所有新子串之间用‘-’分隔。对于每个新组成的子串,需按以下规则转换大小写:
- 若子串中小写字母数量 > 大写字母数量:将所有大写字母转换为小写字母;
- 若子串中大写字母数量 > 小写字母数量:将所有小写字母转换为大写字母;
- 若大小写字母数量相等:不做转换。 最终将第一个子串与所有转换后的新子串用‘-’连接,输出结果。
输入格式
输入为两行,第一行为正整数K,第二行为非空字符串S。
输出格式
输出为转换后的字符串。
示例
示例1
输入
输出
示例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 34 35 36 37 38 39 40 41 42 43 44 45 46
| import java.util.Scanner;
public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); while (sc.hasNextLine()) { 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
输入
输出
示例 2
输入
输出
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
|
输出
说明
该场射击比赛进行了 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
输入
输出
示例 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
| 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 为无效类型。
例如:
一个数据 a=0x01010101,b=3,按照分类方法计算 (0x01+0x01+0x01+0x01)%3=1
如果 c=2,则此 a 为有效类型,其类型为 1
如果 c=1,则此 a 为无效类型
一个数据 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
|
输出
说明
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
|
输出
说明
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):选择当前屏幕上的所有字母。
注意事项
- 剪贴板初始为空,新的内容被复制到剪贴板时会覆盖原来的内容;
- 当屏幕上没有字母时,ctrl-a 无效;
- 当没有选择字母时,ctrl-c 和 ctrl-x 无效;
- 当有字母被选择时,a 和 ctrl-v 这两个有输出功能的键会先清空选择的字母,再进行输出。
输入描述
输入为一行,为简化解析,用数字 1-5 代表五个键的输入,数字用空格分隔:
- 1:a 键
- 2:ctrl-c
- 3:ctrl-x
- 4:ctrl-v
- 5:ctrl-a
输出描述
输出一个数字,为最终屏幕上字母的数量。
示例
示例 1
输入
输出
说明连续键入 3 个 a,故屏幕上字母的长度为 3。
示例 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.length()); } } }
|
检查是否存在满足条件的数字组合
题目描述
给定一个正整数数组,检查数组中是否存在满足规则的数组组合。规则:A = B + 2×C。要求数组中的每个成员只能在结果算式中使用一次(如数组成员为 [0,0,1,5],算式 0=0+2×0 不允许,因为使用了 3 个 0)。
输入描述
第一行输入数组的元素个数;
第二行输出所有数组元素,用空格隔开。
输出描述
如果存在满足要求的数,在同一行里依次输出规则里 A、B、C 的取值,用空格隔开;
如果不存在,输出 0。
示例
示例 1
输入
输出
说明
7 = 3 + 2×2,数组中每个元素仅使用一次。
备注
- 数组长度在 3~100 之间;
- 数组成员为 0~65535;
- 数组成员可以重复,但每个成员只能在结果算式中使用一次;
- 用例保证每组数字里最多只有一组符合要求的解。
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
|
说明
- 获得长度 3 和数组数目 2;
- 先遍历第一行,获得 2,5,6;
- 再遍历第二行,获得 1,7,4;
- 再循环回到第一行,获得 7,9,5;
- 再遍历第二行,获得 3,4;
- 再回到第一行,获得 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 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); 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:正常上班
现需根据员工出勤信息,判断本次是否能获得出勤奖,能获得出勤奖的条件如下:
- 缺勤不超过一次;
- 没有连续的迟到 / 早退;
- 任意连续 7 次考勤,缺勤 / 迟到 / 早退不超过 3 次。
输入描述
第一行输入一个整数 n,表示有多少个员工;后面 n 行,每一行输入若干个字符串(用空格分隔),表示第 i 名员工的出勤信息。
输出描述
输出 n 行,每一行表示这名员工能否获得出勤奖,如果可以,则输出 “true”,否则输出 “false”。
示例
示例 1
输入
1 2 3
| 2 present present absent present present leaveearly present absent
|
输出
示例 2
输入
1 2 3
| 2 present present present
|
输出
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; } }
|