快手篇
快手(入门)
KS9字符串排序
描述
月神拿到一个新的数据集,其中每个样本都是一个字符串,样本的的后六位是纯数字,月神需要将所有样本的后六位数字提出来,转换成数字,并排序输出。
注意: 这里的排序并不是针对每个字符串的后六位,而是需要按数字大小顺序输出所有样本的后六位数字。
月神要实现这样一个很简单的功能确没有时间,作为好朋友的你,一定能解决月神的烦恼,对吧。
数据范围: 字符串长度满足 1 ≤ n ≤ 100 ,每组测试中包含 1 ≤ m ≤100 个字符串
输入描述:
每个测试用例的第一行是一个正整数 M ,表示数据集的样本数目
接下来输入 M 行,每行是数据集的一个样本,每个样本均是字符串,且后六位是数字字符。
输出描述:
对每个数据集,输出所有样本的后六位构成的数字排序后的结果(每行输出一个样本的结果)
示例:
输入:
4
abc123455
cba312456
boyxx213456
cdwxa654321
输出:
123455
213456
312456
654321
解题
import java.util.*;
public class Main {
public static void main(String[] args) {
// 根据输入的组数获取创建数组容量
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] arr = new int[n];
// 循环输入字符串
for (int i = 0; i < n ; i++) {
String str = sc.next();
// 截取输入字符串中需要的部分,并转为int类型
int num = Integer.parseInt(str.substring(str.length() - 6, str.length()));
// 将num有序放入到数组中(按从小到大排序)
int j = i;
for (; j > 0 && arr[j - 1] > num; j--) {
arr[j] = arr[j - 1];
}
arr[j] = num;
}
// 输出数组
for (int i: arr) {
System.out.println(i);
}
}
}
KS12游戏海报
描述
小明有 26 种游戏海报,用小写字母 “a” 到 “z” 表示。小明会把游戏海报装订成册(可能有重复的海报),册子可以用一个字符串来表示,每个字符就表示对应的海报,例如 abcdea 。小明现在想做一些“特别版”,然后卖掉。特别版就是会从所有海报(26种)中随机选一张,加入到册子的任意一个位置。那现在小明手里已经有一种海报册子,再插入一张新的海报后,他一共可以组成多少不同的海报册子呢?
数据范围:输入的字符串长度满足 1 ≤ n ≤ 20
输入描述:
海报册子的字符串表示
输出描述:
一个整数,表示可以组成的不同的海报册子种类数
解题
import java.util.*;
public class Main{
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String str = sc.next();
// 获取字符串长度
int len = str.length();
// 有26个字母,有 len+1 个空,有len个可能重复的字符
System.out.println((len + 1) * 26 - len);
}
}
KS17字符串归一化
描述
通过键盘输入一串小写字母 (a~z) 组成的字符串。请编写一个字符串归一化程序,统计字符串中相同字符出现的次数,并按字典序输出字符及其出现次数。例如字符串"babcc"归一化后为"a1b2c2"
数据范围:输入的字符串长度满足 1 ≤ n ≤ 106 ,保证输入中仅包含小写的英文字母
输入描述:
每个测试用例每行为一个字符串,以’\n’结尾,例如cccddecca
输出描述:
输出压缩后的字符串ac5d2e
解题(法一)
import java.util.*;
/**
用26个字母的(ASCII法)
*/
public class Main{
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String str = sc.nextLine();
// 创建存储26个字母的数组
int[] arr = new int[26];
// 遍历得到的字符串
char c ;
for (int i = 0;i < str.length(); i++) {
c = str.charAt(i); // 通过遍历获取每一个字符
arr[(int)c - 97] ++; // a的ASCII为97
}
// 遍历输出存储 > 0
for (int i = 0;i < arr.length; i++) {
if (arr[i] > 0) { // 大于0就表示字符串中有
System.out.print((char)(i + 97)); // 逆推回字母
System.out.print(arr[i]);
}
}
}
}
解题(法二)
import java.util.*;
/**
hashmap存储法
*/
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String str = sc.nextLine();
char[] chars = str.toCharArray(); // 将字符串转为字符数组
// 定义存储【字符】和【字符数量】的hashmap
HashMap<Character, Integer> map = new HashMap<>();
for (int i = 0;i < str.length(); i++) { // 遍历字符数组
// 如果map中有这个键【chars[i]】,就给这个键的值 +1,没有就注入一个键并且 值=1
if (map.containsKey(chars[i])) {
map.put(chars[i], map.get(chars[i]) + 1);
}else {
map.put(chars[i], 1);
}
}
// 将hashmap转为字符串
int temp = 97; // 或者'a','a'=97
StringBuilder sbd = new StringBuilder();
for (int i = 0; i < 26; i++) {
char ch = (char) temp; // 强转为字符(26个字母)
if (map.containsKey(ch)) { // hashmap中有的键
sbd.append(ch).append(map.get(ch)); // 将键和值一起存进去
}
temp++; // 下一个字母
}
// 输出字符串
System.out.println(sbd);
}
}
快手(简单)
KS6字符串长度最大乘积
描述
已知一个字符串数组words,要求寻找其中两个没有重复字符的字符串,使得这两个字符串的长度乘积最大,输出这个最大的乘积。如:
words=[“abcd”,“wxyh”,“defgh”], 其中不包含重复字符的两个字符串是"abcd"和"wxyh",则输出16
words=[“a”,“aa”,“aaa”,“aaaa”], 找不到满足要求的两个字符串,则输出0
数据范围:输入的字符串长度满足2 ≤ n ≤ 100 ,保证只包含小写字母
输入描述:
[“a”,“ab”,“abc”,“cd”,“bcd”,“abcd”]
输出描述:
4
解题(法一)
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String str = sc.nextLine();
// 提取完整的字符串
str = str.substring(1, str.length() - 1); // 去掉输入的'[' 和 ']'字符
String[] strs = str.split(","); // 先根据 ',' 来简单筛选字符数组中的字符串
for (int i = 0; i < strs.length; i++) {
if (strs[i].length() == 0) {
continue;
}
// 去掉简单筛选的头尾,即 " 和 ",得到完整的字符串
strs[i] = strs[i].substring(1, strs[i].length() - 1);
}
int max = 0; // 记录不重复字符串的长度乘积
HashSet<Character> set = new HashSet<>(); // 存储一个字符串的每个字符
// 控制字符串和后面的比较,在依次递进
for (int i = 0;i < strs.length; i++) {
// 控制第 j 个字符串和后面的比较
for (int j = i + 1; j < strs.length; j++) {
int index = 0; // 主要用户记录该字符串索引到的位置
// 将字符串的字符一个个存入set中当作key
for (; index < strs[i].length(); index++) {
set.add(strs[i].charAt(index));
}
// 如果有重复的就退出,进而index != strs[j].length()
for (index = 0;index < strs[j].length(); index++) {
if (set.contains(strs[j].charAt(index))) {
break;
}
}
// 判断前面的for是否有退出
if (index == strs[j].length()) {
int temp = strs[i].length() * strs[j].length();
if (temp > max) {
max = temp;
}
}
set.clone(); // 清除set内容,为下一个字符串准备
}
}
System.out.println(max);
}
}
解题(法二)
相对法一:没有使用HashSet而是直接使用字符串进行对比
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String str = sc.nextLine();
// 提取完整的字符串
str = str.substring(1, str.length() - 1); // 去掉输入的'[' 和 ']'字符
String[] strs = str.split(","); // 先根据 ',' 来简单筛选字符数组中的字符串
for (int i = 0; i < strs.length; i++) {
if (strs[i].length() == 0) {
continue;
}
// 去掉简单筛选的头尾,即 " 和 ",得到完整的字符串
strs[i] = strs[i].substring(1, strs[i].length() - 1);
}
int max = 0; // 记录不重复字符串的长度乘积
// 控制字符串和后面的比较,在依次递进
for (int i = 0;i < strs.length; i++) {
// 控制第 j 个字符串和后面的比较
for (int j = i + 1; j < strs.length; j++) {
int index = 0; // 主要用户记录该字符串索引到的位置
// 如果有重复的就退出,进而index != strs[j].length()
for (;index < strs[j].length(); index++) {
if (strs[i].contains(strs[j].substring(index, index + 1))) {
break;
}
}
// 判断前面的for是否有退出
if (index == strs[j].length()) {
int temp = strs[i].length() * strs[j].length();
if (temp > max) {
max = temp;
}
}
}
}
System.out.println(max);
}
}
KS7今年的第几天
描述
输入年、月、日,计算该天是本年的第几天。
输入:
包括三个整数年、月、日。
输出:
输出一个整数,代表Input中的年、月、日对应本年的第几天。
数据范围:输入的年 1 ≤ y ≤ 3000 ,输入的月满足 1 ≤ m ≤ 12 , 输入的日满足1 ≤ d ≤ 31
输入描述:
输入:1990 9 20
输出描述:
输入:263
解题
import java.util.*;
public class Main {
public static void main(String[] args) {
// 获取年月日信息
Scanner sc = new Scanner(System.in);
int year = sc.nextInt();
int mon = sc.nextInt();
int day = sc.nextInt();
// 定义一年中每个月的天数(2月再做判断),索引即月数
int[] mons = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
// 判断2月份天数
if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
mons[1] = 29;
}
// 存储天数(先存储当月天数再存储当月前的每月的天数)
int days = day;
for (int i = 0;i < mon - 1; i++) {
days += mons[i];
}
System.out.println(days);
}
}
KS8数字序列第n位的值
描述
有一个无限长的数字序列1,2,2,3,3,3,4,4,4,4,5,5,5,5,5。。。(数字序列从1开始递增,且数字k在该序列中正好出现k次),求第n项是多少
数据范围:1 ≤ n ≤ 109
输入描述:
输入为一个整数n
输出描述:
输出一个整数,即第n项的值
解题
import java.util.Scanner;
/*
根据索引(1+2+3+4)判断,小于或等于索引的即为要输出的数字
*/
public class Main {
public static void main(String[] args){
Scanner input = new Scanner(System.in);
int index = input.nextInt();
int n = 1; // 记录到的索引最大范围
for (int num = 1;num <= index; n++) {
num += n;
}
System.out.println(n - 1);
}
}
KS21解析加减法运算
描述
解析加减法运算
如:
输入字符串:“1+2+3” 输出:“6”
输入字符串:“1+2-3” 输出:“0”
输入字符串:“-1+2+3” 输出:“4”
输入字符串:“1” 输出:“1”
输入字符串:“-1” 输出:“-1”
已知条件:输入的运算都是整数运算,且只有加减运算
要求:输出为String类型,不能使用内建的eval()函数
数据范围:计算过程中所有值满足 ∣val∣ ≤ 106 ,输入的字符串长度满足 1 ≤ *n *≤ 106
输入描述:
输入字符串:“1+2+3”
输出描述:
输出:“6”
解题
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner in = new Scanner(System.in);
String str = in.nextLine();
int num = 0; // 记录运算值
int start = 0; // 记录一个数值的开始索引
int end = 1; // 记录一个数值的结束索引
for(; end<str.length(); end++){
// 确保是完整的数据,当遇到下一个运算符号的时候才进入运算
if(str.charAt(end) == '+' || str.charAt(end) == '-'){
num += Integer.parseInt(str.substring(start, end));
start = end;
}
}
// 最后一个没有下一个运算符号了,所以单独处理
num += Integer.parseInt(str.substring(start, end));
System.out.println(num);
}
}
KS20字符串压缩
描述
对字符串进行 RLE 压缩,将相邻的相同字符,用计数值和字符值来代替。例如:aaabccccccddeee,则可用 3a1b6c2d3e 来代替。
数据范围:字符串长度满足 1 \le n \le 10^5 \1≤n≤105
输入描述:
输入为a-z,A-Z的字符串,且字符串不为空,如aaabccccccddeee
输出描述:
压缩后的字符串,如3a1b6c2d3e
解题
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String str = sc.nextLine();
char[] chs = str.toCharArray(); // 将字符串转为字符数组
int count = 0; // 记录连续的字符长度
for (int i = 0;i < chs.length; i++) {
count += 1;
// 如果是下一个不连续或者是最后一个就
if (i == chs.length - 1 || chs[i] != chs[i + 1]) {
System.out.print(count + "" + chs[i]);
count = 0;
}
}
}
}
KS27二进制中有多少个1
描述
把一个 32-bit 整型转成二进制,其中包含多少个 1 ,比如 5 的二进制表达是 101 ,其中包含 2 个 1
数据范围:输入的数字满足 0 ≤ n ≤ 231−1
输入描述:
输入为整型(十进制),只需兼容32-bit即可,如5、32
输出描述:
输出为字符串,如“2”、“1”
示例1
输入:5
输出:2
解题
import java.util.*;
public class Main {
public static void main(String[] agrs) {
Scanner sc = new Scanner(System.in);
int num = sc.nextInt();
int count = 0; // 记录1的个数
for (; num > 0; num /= 2) { // 短除法
if (num % 2 == 1) { // 奇数
count++;
}
}
System.out.print(count);
}
}
KS33寻找奇数
描述
现在有一个长度为 n 的正整数序列,其中只有一种数值出现了奇数次,其他数值均出现偶数次,请你找出那个出现奇数次的数值。
数据范围:1 ≤ n ≤ 2×106
输入描述:
第一行:一个整数n,表示序列的长度。第二行:n个正整数ai,两个数中间以空格隔开。
输出描述:
一个数,即在序列中唯一出现奇数次的数值。
解题(法一:会超时)
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int str = sc.nextInt();
String s;
while((s = sc.nextLine()) != null) {
String strs = sc.nextLine();
String[] strArr = strs.split(" ");
int remain = 0;
for(int i = 0; i < strArr.length; i++) {
// 出现偶数次的数在经过不断异或后一定为0,与0异或不改变数
remain ^= Integer.parseInt(strArr[i]);
}
// 所以最后剩下的数就是出现过奇数次的数
System.out.println(remain);
}
}
}
解题(法二:不会超时)
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String strN;
while((strN = br.readLine()) != null) {
String[] strArr = br.readLine().split(" ");
int remain = 0;
for(int i = 0; i < strArr.length; i++)
// 出现偶数次的数在经过不断异或后一定为0,与0异或不改变数
remain ^= Integer.parseInt(strArr[i]);
// 所以最后剩下的数就是出现过奇数次的数
System.out.println(remain);
}
}
}