华为机考
041 【求解连续数列】
已知连续正整数数列{K}=K1,K2,K3…Ki的各个数相加之和为S,i=N (0<S<100000, 0<N<100000), 求此数列K。
输入描述:
输入包含两个参数,1)连续正整数数列和S,2)数列里数的个数N。
输出描述:
如果有解输出数列K,如果无解输出-1
示例1
输入
525 6
输出
85 86 87 88 89 90
示例2
输入
3 5
输出
-1
public class ZT41 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String[] input = sc.nextLine().split(" ");
int result = Integer.parseInt(input[0]);
int count = Integer.parseInt(input[1]);
int middle = 0;
if (result/count == 0){
System.out.println(-1);
return;
}
int[] arr = new int[count];
int start = 0;
if (result % count == 0){//count是奇数
//正好的中间的奇数位
middle = result/count;
start = middle - count/2;
}else {//向下取整了 ,middle是中间的前一个数
middle = result/count;
start = middle - count/2 +1;
}
int idx = 0;
while (idx<count){
arr[idx] = start;
start++;
idx++;
}
int sum = 0;
for (int i = 0; i < arr.length; i++) {
sum += arr[i];
}
if (sum == result){
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
}else {
System.out.println(-1);
}
}
}
用数学表达式求和后,直接计算出起始位置更优
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int sum = in.nextInt();
int n = in.nextInt();
// sum(x x+1 x+2 ... x+n-1) = sum
// n*x + n*(n-1)/2 = sum
// x= [sum - n*(n-1)/2 ]/n
int temp = sum - n*(n-1)/2;
if (temp <=0 || temp%n!=0){
System.out.println(-1);
return;
}
int begin = temp/n;
for (int i = 0; i < n; i++) {
System.out.print(begin+i);
System.out.print(' ');
}
}
}
042 【求字符串中所有整数的最小和】
输入字符串s,输出s中包含所有整数的最小和
说明
字符串s,只包含 a-z A-Z ± ;
合法的整数包括
1) 正整数 一个或者多个0-9组成,如 0 2 3 002 102
2)负整数 负号 - 开头,数字部分由一个或者多个0-9组成,如 -0 -012 -23 -00023
输入描述:
包含数字的字符串
输出描述:
所有整数的最小和
示例1
输入
bb1234aa
输出
10
示例2
输入
bb12-34aa
输出
-31
说明
1+2+(-34) = 31
public class ZT42 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String input = sc.nextLine();
//原则1、正数所有都拆分
//2、负数保留最大
boolean fuShu = false;
String tempNum = "-";
List<Integer> list = new ArrayList<>();
for (int i = 0; i < input.length(); i++) {
char tem = input.charAt(i);
if (tem == '-'){
fuShu = true;
continue;
}
if (tem >= '0' && tem <= '9'){
if (fuShu){ //只要不是字符就一直往下记录
tempNum += tem;
}else {
list.add(Integer.parseInt(String.valueOf(tem)));
}
}else {
if (tempNum != "-"){
list.add(Integer.parseInt(tempNum));
tempNum = "-";
}
fuShu = false;
}
}
int total = 0;
for (int i = 0; i < list.size(); i++) {
total += list.get(i);
}
System.out.println(total);
}
}
043 【求最多可以派出多少支团队】
用数组代表每个人的能力,一个比赛活动要求参赛团队的最低能力值为N,每个团队可以由1人或2人组成,且1个人只能参加1个团队,请计算出最多可以派出多少支符合要求的团队?
输入描述:
5
3 1 5 7 9
8
第一行数组代表总人数,范围[1,500000]
第二行数组代表每个人的能力,每个元素的取值范围[1, 500000],数组的大小范围[1,500000]
第三行数值为团队要求的最低能力值,范围[1, 500000]
输出描述:
3
最多可以派出的团队数量
示例1
输入
5
3 1 5 7 9
8
输出
3
说明
3,5组成一队,1,7组成一队,9自己一个队,故输出3
public class ZT43 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int count = Integer.parseInt(sc.nextLine());
String[] input = sc.nextLine().split(" ");
int limit = Integer.parseInt(sc.nextLine());
int maxTeam = 0;
int[] arr = new int[count];
for (int i = 0; i < count; i++) {
int tem = Integer.parseInt(input[i]);
if (tem >= limit){
maxTeam++;
}else {
arr[i] = tem;
}
}
Arrays.sort(arr);//1 2 3 5 6
int left = 0;
int right = arr.length-1;
while (left< right){
if (arr[left] + arr[right] < limit){//最小+最大 < min
left++;
continue;
}else {//min + max >= limit
maxTeam++;
left++;
right--;
}
}
System.out.println(maxTeam);
}
}
044 【删除字符串中字符最少字符】
删除字符串中出现次数最少的字符,如果有多个字符出现次数一样,则都删除。
输入描述:
输入abcdd
字符串中只包含小写英文字母。
输出描述:
dd
示例1
输入
abcdd
输出
dd
示例2
输入
aabbccdd
输出
empty
说明
如果字符串的字符都被删除,则范围empty
public class ZT44 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String input = sc.nextLine();
Map<String,Integer> map = new HashMap<>();
for (int i = 0; i < input.length(); i++) {
int orDefault = map.getOrDefault(String.valueOf(input.charAt(i)), 0);
map.put(String.valueOf(input.charAt(i)),orDefault+1);
}
int less = Collections.min(map.values());
StringBuilder res = new StringBuilder();
Set<String> set = new HashSet<>();
for (Map.Entry<String,Integer> mp:map.entrySet()) {
int times = mp.getValue();
if (times == less) {
set.add(mp.getKey());
}
}
for (int i = 0; i < input.length(); i++) {
if (!set.contains(String.valueOf(input.charAt(i)))) {
res.append(input.charAt(i));
}
}
if (res.length() == 0){
System.out.println("empty");
}else {
System.out.println(res);
}
}
}
045 【数据分类】
对一个数据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个数据为需要分类的数据,请找到有效类型中包含数据最多的类型,并输出该类型含有多少个数据。
输入描述:
输入12个数据,用空格分隔,第一个数据为c,第二个数据为b,剩余10个数据为需要分类的数据。
输出描述:
输出最多数据的有效类型有多少个数据。
示例1
输入
3 4 256 257 258 259 260 261 262 263 264 265
输出
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 4 256 257 258 259 260 261 262 263 264 265
输出
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
public class ZT45 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String[] input = sc.nextLine().split(" ");
int c1 = Integer.parseInt(input[0]);
int b1 = Integer.parseInt(input[1]);
int[] arr = new int[b1-1];
for (int i = 2; i < input.length; i++) {
int res = calcAdd(Integer.parseInt(input[i])) % b1;
if (res < c1){//有效
arr[res]++;
}
}
int max = -1;
for (int i = 0; i < arr.length ; i++) {
max = Math.max(max,arr[i]);
}
System.out.println(max);
}
private static int calcAdd(int num){
String str = Integer.toBinaryString(num);
//100000000
int total = 0;
while (str.length() > 8){
String temp = str.substring(str.length()-8);
total += Integer.parseInt(temp);
str = str.substring(0,str.length()-8);
}
total += Integer.parseInt(str);
return total;
}
}
046 【数列描述】
有一个数列a[N] (N=60),从a[0]开始,每一项都是一个数字。数列中a[n+1]都是a[n]的描述。其中a[0]=1。
规则如下:
a[0]:1
a[1]:11(含义:其前一项a[0]=1是1个1,即“11”。表示a[0]从左到右,连续出现了1次“1”)
a[2]:21(含义:其前一项a[1]=11,从左到右:是由两个1组成,即“21”。表示a[1]从左到右,连续出现了两次“1”)
a[3]:1211(含义:其前一项a[2]=21,从左到右:是由一个2和一个1组成,即“1211”。表示a[2]从左到右,连续出现了1次“2”,然后又连续出现了1次“1”)
a[4]:111221(含义:其前一项a[3]=1211,从左到右:是由一个1、一个2、两个1组成,即“111221”。表示a[3]从左到右,连续出现了1次“1”,连续出现了1次“2”,连续出现了两次“1”)
请输出这个数列的第n项结果(a[n],0≤n≤59)。
输入描述:
数列的第n项(0≤n≤59):
4
输出描述:
数列的内容:
111221
示例1
输入
4
输出
111221
public class ZT46 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int input = sc.nextInt();
String temp = "1";
for (int i = 1; i <= input; i++) {
int idx = 0;
char pre = ' ';
StringBuilder sb = new StringBuilder();
for (int j = 0; j < temp.length(); j++) {
if (j == 0){
pre = temp.charAt(j);
}
char tem = temp.charAt(j);
if (tem == pre){
idx++;
}else {
sb.append(idx).append(pre);
idx = 1;
pre = tem;
}
}
sb.append(idx).append(pre);
temp = sb.toString();
}
System.out.println(temp);
}
}
047 【数字涂色】
疫情过后,希望小学终于又重新开学了,三年二班开学第一天的任务是将后面的黑板报重新制作。黑板上已经写上了N个正整数,同学们需要给这每个数分别上一种颜色。为了让黑板报既美观又有学习意义,老师要求同种颜色的所有数都可以被这种颜色中最小的那个数整除。现在请你帮帮小朋友们,算算最少需要多少种颜色才能给这N个数进行上色。
输入描述:
第一行有一个正整数N,其中1 \leq N \leq 1001≤N≤100。
第二行有N个int型数(保证输入数据在[1,100]范围中),表示黑板上各个正整数的值。
输出描述:
输出只有一个整数,为最少需要的颜色种数。
示例1
输入
3
2 4 6
输出
1
说明
所有数都能被2整除
示例2
输入
4
2 3 4 9
输出
2
说明
2与4涂一种颜色,4能被2整除;3与9涂另一种颜色,9能被3整除。不能4个数涂同一个颜色,因为3与9不能被2整除。所以最少的颜色是两种。
public class ZT47 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int count = Integer.parseInt(sc.nextLine());
String[] input = sc.nextLine().split(" ");
int[] arr = new int[count];
for (int i = 0; i < count; i++) {
arr[i] = Integer.parseInt(input[i]);
}
Arrays.sort(arr);
List<Integer> list = new ArrayList<>();
for (int i = 0; i < arr.length; i++) {
//如果list的数能整除arr[i] 就过 否则要加进list
int temp = arr[i];
boolean flag = false;
for (int j = 0; j < list.size(); j++) {
int num = list.get(j);
if (temp % num == 0){
flag = true;
break;
}
}
if (!flag){
list.add(temp);
}
}
System.out.println(list.size());
}
}
048 【数组二叉树】
二叉树也可以用数组来存储,给定一个数组,树的根节点的值存储在下标1,对于存储在下标N的节点,它的左子节点和右子节点分别存储在下标2N和2N+1,并且我们用值-1代表一个节点为空。
给定一个数组存储的二叉树,试求从根节点到最小的叶子节点的路径,路径由节点的值组成。
输入描述:
输入一行为数组的内容,数组的每个元素都是正整数,元素间用空格分隔。注意第一个元素即为根节点的值,即数组的第N个元素对应下标N,下标0在树的表示中没有使用,所以我们省略了。输入的树最多为7层。
输出描述:
输出从根节点到最小叶子节点的路径上,各个节点的值,由空格分隔,用例保证最小叶子节点只有一个。
示例1
输入
3 5 7 -1 -1 2 4
输出
3 7 2
说明
数组存储的二叉树如图,故到最小叶子节点的路径为3 7 2
示例2
输入
5 9 8 -1 -1 7 -1 -1 -1 -1 -1 6
输出
5 8 7 6
说明
数组存储的二叉树如图,故到最小叶子节点的路径为10 8 7 6,注意数组仅存储至最后一个非空节点,故不包含节点“7”右子节点的-1
public class ZT48 {
public static void main(String[] args) {//1 2 4 8 16
Scanner sc = new Scanner(System.in);
String[] input = sc.nextLine().split(" ");
//先找到最小叶子节点所在行 求行号
int min = Integer.MAX_VALUE;//数组每个元素都是正整数
int idx = 0;
for (int i = 1; i < input.length; i++) {
if (Integer.parseInt(input[i]) != -1 && Integer.parseInt(input[i])<min){
idx = i;
min = Integer.parseInt(input[i]);
}
}
int line = calcLine(idx);
int[] arr = new int[line];
//line表示行号 start表示该行首个元素
int start = calcStart(line);//arr[7]
arr[line-1] = Integer.parseInt(input[idx]);
//求该值在所在行的序号
int turnInLine = idx - start + 1 ;
//求剩余其他行
line--;
turnInLine = turnInLine%2 ==0 ? turnInLine/2 : turnInLine/2+1;//3
while (line > 0){
start = calcStart(line);//arr
arr[line-1] = Integer.parseInt(input[turnInLine + start -1 ]);
line--;
turnInLine = turnInLine%2 ==0 ? turnInLine/2 : turnInLine/2+1;//2
}
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
System.out.println();
}
private static int calcStart(int line){
int total = 0;
int tem = 0;
while (line>1){
total += 1<<tem;
tem++;
line--;
}
return total;
}
//计算在第几行
private static int calcLine(int line){
int tem = 0;
while (line>0){
line -= 1<<tem;
tem++;
}
return tem;
}
}
049 【数组拼接】
现在有多组整数数组,需要将它们合并成一个新的数组。合并规则,从每个数组里按顺序取出固定长度的内容合并到新的数组中,取完的内容会删除掉,如果该行不足固定长度或者已经为空,则直接取出剩余部分的内容放到新的数组中,继续下一行。
输入描述:
第一行是每次读取的固定长度,0<长度<10
第二行是整数数组的数目,0<数目<1000
第3-n行是需要合并的数组,不同的数组用回车换行分隔,数组内部用逗号分隔,最大不超过100个元素。
输出描述:
输出一个新的数组,用逗号分隔。
示例1
输入
3
2
2,5,6,7,9,5,7
1,7,4,3,4
输出
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
输入
4
3
1,2,3,4,5,6
1,2,3
1,2,3,4
输出
1,2,3,4,1,2,3,1,2,3,4,5,6
public class ZT49 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int limit = Integer.parseInt(sc.nextLine());
int num = Integer.parseInt(sc.nextLine());
Map<Integer, List<Integer>> map = new HashMap<>();
//存
for (int i = 0; i < num; i++) {
String[] split = sc.nextLine().split(",");
List<Integer> list = new ArrayList<>();
for (int j = 0; j < split.length; j++) {
list.add(Integer.parseInt(split[j]));
}
map.put(i,list);
}
//取
List<Integer> list = new ArrayList<>();
while (!map.isEmpty()){
Iterator<Map.Entry<Integer, List<Integer>>> iterator = map.entrySet().iterator();
List<Integer> removeKey = new ArrayList<>();
while (iterator.hasNext()){
Map.Entry<Integer, List<Integer>> next = iterator.next();
List<Integer> value = next.getValue();
int start = 0;
for (int i = 0; i < value.size(); i++) {
if (i<limit){
list.add(value.get(i));
start++;
}
}
value = value.subList(start,value.size());
if (value.size() == 0){
removeKey.add(next.getKey());
}else {
next.setValue(value);
}
}
for (int i = 0; i < removeKey.size(); i++) {
map.remove(removeKey.get(i));
}
}
System.out.println(list);
}
}
050 【数组去重和排序】
给定一个乱序的数组,删除所有的重复元素,使得每个元素只出现一次,并且按照出现的次数从高到低进行排序,相同出现次数按照第一次出现顺序进行先后排序。
输入描述:
一个数组
输出描述:
去重排序后的数组
示例1
输入
1,3,3,3,2,4,4,4,5
输出
3,4,1,2,5
备注:
数组大小不超过100
数组元素值大小不超过100
public class ZT50 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String[] split = sc.nextLine().split(",");
Map<Integer,Integer> map = new HashMap<>();
List<Order> list = new ArrayList<>();
int idxInList = 0;
for (int i = 0; i < split.length; i++) {
int value = Integer.parseInt(split[i]);
Order order = new Order(i,value,1);
if (list.contains(order)){
int idx = map.get(value);
list.get(idx).count++;
}else {
map.put(value,idxInList++);
list.add(order);
}
}
list.sort(null);//能把下标重排吗?
for (int i = 0; i < list.size(); i++) {
System.out.print(list.get(i).value + ",");
}
}
private static class Order implements Comparable<Order>{
private int idx;//出场顺序
private int value;
private int count;
public Order(int idx ,int value, int count) {
this.idx = idx;
this.value = value;
this.count = count;
}
@Override
public boolean equals(Object obj) {
Order order = (Order) obj;
return order.value == this.value;
}
@Override
public int compareTo(Order order) {
if (order.count != this.count){
return order.count - this.count;
}else {
return this.idx - order.idx ;
}
}
}
}