机考[41-50]

本文介绍了五个编程挑战,涉及数组处理、字符串解析、团队组建、字符删除和数据分类等算法问题。通过示例代码展示了解决方案,强调了效率和逻辑的重要性。这些挑战有助于提升程序员在实际问题中的算法设计和实现能力。
摘要由CSDN通过智能技术生成

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 ;
            }
        }
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

旧梦昂志

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值