机考[51 - 60]

051 【数组组成的最小数字】

给定一个整型数组,请从该数组中选择3个元素组成最小数字并输出(如果数组长度小于3,则选择数组中所有元素来组成最小数字)。
输入描述:
一行用半角逗号分割的字符串记录的整型数组,0 < 数组长度 <= 100,0 < 整数的取值范围 <= 10000。
输出描述:
由3个元素组成的最小数字,如果数组长度小于3,则选择数组中所有元素来组成最小数字。
示例1
输入
21,30,62,5,31
输出
21305
说明
数组长度超过3,需要选3个元素组成最小数字,21305由21,30,5三个元素组成的数字,为所有组合中最小的数字
示例2
输入
5,21
输出
215
说明
数组长度小于3, 选择所有元素来主城最小值,215为最小值。

//思路:
//1、大于3各数的数组,从其中选择3各最小的数,组合排序可以得到最小的数
//2、小于3各数,组合排序即可
//3、可以根据首位进行排序

052 【水仙花数】

所谓水仙花数,是指一个n位的正整数,其各位数字的n次方和等于该数本身。例如153是水仙花数,153是一个3位数,并且153 = 111 + 555 + 333
输入描述:
第一行输入一个整数n,表示一个n位的正整数。n在3到7之间,包含3和7。[3,7]
第二行输入一个正整数m,表示需要返回第m个水仙花数。
输出描述:
返回长度是n的第m个水仙花数。个数从0开始编号。
若m大于水仙花数的个数,返回最后一个水仙花数和m的乘积。
若输入不合法,返回-1。
示例1
输入
3 0
输出
153
说明
153是第一个水仙花数
示例2
输入
9
1
输出
-1
说明
9超出范围

public class ZT02 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int count = Integer.parseInt(sc.nextLine());//[3,7]
        int num = Integer.parseInt(sc.nextLine());
        if (count< 3 || count> 7){
            System.out.println(-1);
            return;
        }//3 100 4 1000
        int start = 1;
        for (int i = 1; i < count; i++) {
            start *= 10;
        }
        int end = start *10 -1;
        int times = 0;
        for (int i = start; i < end; i++) {
            if (checkFlower(i)){
                if (times++ == num) {
                    System.out.println(i);
                    return;
                }
            }
        }
        System.out.println(-1);
    }

    private static boolean checkFlower(int num){
        int temp = num;
        int total = 0;
        while (temp > 0){
            int wei = temp%10;
            total += wei *wei * wei;
            temp /=10;
        }
        return total == num;
    }
}

053 【素数之积】

RSA加密算法在网络安全世界中无处不在,它利用了极大整数因数分解的困难度,数据越大,安全系数越高,给定一个32位正整数,请对其进行因数分解,找出是哪两个素数的乘积。
输入描述:
一个正整数num
0 < num <= 2147483647
输出描述:
如果成功找到,以单个空格分割,从小到大输出两个素数,分解失败,请输出-1 -1
示例1
输入
15
输出
3 5
说明
因数分解后,找到两个素数3和5,使得3*5=15,按从小到大排列后,输出3 5
示例2
输入
27
输出
-1 -1
说明
通过因数分解,找不到任何素数,使得他们的乘积为27,输出-1 -1

public class ZT53 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int target = sc.nextInt();//[0,2147483647]
        int max = target;
        for (int i = 3; i <= max; i++) {
            //先判断能不能被target整除
            if (target % i == 0){
                max = target / i;
                if (checkSu(i) && checkSu(target/i)){
                    System.out.println(i + " " + target/i);
                    return;
                }
            }
        }
        System.out.println(-1 + " " + -1);
    }
    //素数是指除了1和本身不能被其他所有数整除
    private static boolean checkSu(int num){
        for (int i = 2; i < num; i++) {
            if (num % i == 0){
                return false;
            }
        }
        return true;
    }
}

054 【太阳能板最大面积】

给航天器一侧加装长方形或正方形的太阳能板(图中的红色斜线区域),需要先安装两个支柱(图中的黑色竖条),再在支柱的中间部分固定太阳能板。但航天器不同位置的支柱长度不同,太阳能板的安装面积受限于最短一侧的那根支柱长度。如图:
现提供一组整形数组的支柱高度数据,假设每根支柱间距离相等为1个单位长度,计算如何选择两根支柱可以使太阳能板的面积最大。
输入描述:
10,9,8,7,6,5,4,3,2,1
注:支柱至少有2根,最多10000根,能支持的高度范围1~10^9的整数。柱子的高度是无序的,例子中递减只是巧合。
输出描述:
可以支持的最大太阳能板面积:(10米高支柱和5米高支柱之间)
25
示例1
输入
10,9,8,7,6,5,4,3,2,1
输出
25
备注:
10米高支柱和5米高支柱之间宽度为5,高度取小的支柱高也是5,面积为25。任取其他两根支柱所能获得的面积都小于25。所以最大的太阳能板面积为25。

055 【停车场车辆统计】

特定大小的停车场,数组cars[]表示,其中1表示有车,0表示没车。车辆大小不一,小车占一个车位(长度1),货车占两个车位(长度2),卡车占三个车位(长度3),统计停车场最少可以停多少辆车,返回具体的数目。
输入描述:
整型字符串数组cars[],其中1表示有车,0表示没车,数组长度小于1000。
输出描述:
整型数字字符串,表示最少停车数目。
示例1
输入
1,0,1
输出
2
说明
1个小车占第1个车位
第二个车位空
1个小车占第3个车位
最少有两辆车
示例2
输入
1,1,0,0,1,1,1,0,1
输出
3
说明
1个货车占第1、2个车位
第3、4个车位空
1个卡车占第5、6、7个车位
第8个车位空
1个小车占第9个车位
最少3辆车

public class ZT55 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String[] split = sc.nextLine().split(",");
        //连续的2个1可以是1个 连续三个1可以是1个
        int total = 0;
        int tem = 0;
        for (int i = 0; i < split.length; i++) {
            if (Integer.parseInt(split[i]) == 1){
                tem++;
            }else {
                if (tem != 0){
                    total += calcMin(tem);
                }
                tem = 0;
            }
        }
        total += calcMin(tem);
        System.out.println(total);
    }

    private static int calcMin(int num){
        //6 -> 2
        int total = 0;
        while (num >= 3){//有多少3 除掉多少3
            num -= 3;
            total++;
        }
        while (num >= 2){//有多少3 除掉多少3
            num -= 2;
            total++;
        }
        total += num;
        return total;
    }
}

056 【统计射击比赛成绩】

给定一个射击比赛成绩单,包含多个选手若干次射击的成绩分数,请对每个选手按其最高3个分数之和进行降序排名,输出降序排名后的选手ID序列。条件如下:
1、一个选手可以有多个射击成绩的分数,且次序不固定。
2、如果一个选手成绩少于3个,则认为选手的所有成绩无效,排名忽略该选手。
3、如果选手的成绩之和相等,则成绩之和相等的选手按照其ID降序排列。
输入描述:
输入第一行,一个整数N,表示该场比赛总共进行了N次射击,产生N个成绩分数(2<=N<=100)。
输入第二行,一个长度为N整数序列,表示参与每次射击的选手ID(0<=ID<=99)。
输入第三行,一个长度为N整数序列,表示参与每次射击的选手对应的成绩(0<=成绩<=100)。
输出描述:
符合题设条件的降序排名后的选手ID序列。
示例1
输入
13
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
输出
5,3,7,4
说明
该场射击比赛进行了13次,参赛的选手为{3,4,5,7}。
3号选手成绩:53,80,55,最高3个成绩的和为:80+55+53=188。
4号选手成绩:24,39,76,66,最高3个成绩的和为:76+66+39=181。
5号选手成绩:53,80,55,最高3个成绩的和为:80+55+53=188。
7号选手成绩:68,16,100,最高3个成绩的和为:100+68+16=184。
比较各个选手最高3个成绩的和,有3号=5号>7号>4号,由于3号和5号成绩相等且ID号5>3,所以输出为:5,3,7,4

public class ZT56 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int count = Integer.parseInt(sc.nextLine());
        String[] turnList = sc.nextLine().split(",");
        String[] scores = sc.nextLine().split(",");
        List<Player> plays = new ArrayList<>();
        Map<Integer,Integer> map= new HashMap<>();
        int tempCount = 0;
        //获取成绩
        for (int i = 0; i < count; i++) {
            int idx = Integer.parseInt(turnList[i]);
            List<Integer> li = new ArrayList<>();
            li.add(Integer.parseInt(scores[i]));
            Player pls = new Player(idx,li);
            if (plays.contains(pls)) {
                plays.get(map.get(idx)).list.add(Integer.parseInt(scores[i]));
            }else{
                map.put(idx,tempCount++);
                plays.add(pls);
            }
        }
        //整理成绩
        for (int i = 0; i < plays.size(); i++) {
            Player player = plays.get(i);
            List<Integer> list = player.list;
            list.sort((a0,b0) -> b0 -a0);//逆序
            int total = 0;
            for (int j = 0; j < 3; j++) {
                total += list.get(j);
            }
            player.setScore(total);
        }
        plays.sort(null);
        for (int i = 0; i < plays.size(); i++) {
            if (i == plays.size() -1){
                System.out.print(plays.get(i).idx);
            }else {
                System.out.print(plays.get(i).idx + ",");
            }
        }
    }
    static class Player implements Comparable<Player>{
        private int idx;
        private List<Integer> list;
        private int score;

        public void setScore(int score) {
            this.score = score;
        }

        public Player(int idx, List<Integer> list) {
            this.idx = idx;
            this.list = list;
        }

        @Override
        public boolean equals(Object obj) {
            Player ply = (Player)obj;
            return ply.idx == this.idx;
        }

        @Override
        public int compareTo(Player ply) {
            if (ply.score != this.score){
                return ply.score - this.score;
            }else {
                return ply.idx - this.idx;
            }
        }
    }
}

057 【完全二叉树非叶子部分后序遍历】

给定一个以顺序储存结构存储整数值的完全二叉树序列(最多1000个整数),请找出此完全二叉树的所有非叶子节点部分,然后采用后序遍历方式将此部分树(不包含叶子)输出。
1、只有一个节点的树,此节点认定为根节点(非叶子)。
2、此完全二叉树并非满二叉树,可能存在倒数第二层出现叶子或者无右叶子的情况
其他说明:二叉树的后序遍历是基于根来说的,遍历顺序为:左-右-根 根输出
输入描述:
一个通过空格分割的整数序列字符串
输出描述:
非叶子部分树结构
示例1
输入
1 2 3 4 5 6 7
输出
2 3 1
说明
找到非叶子部分树结构,然后采用后续遍历输出
备注:
输出数字以空格分隔

public class ZT57Tree {
    private static List<TreeNode> nodes = new ArrayList<>();

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String[] input = sc.nextLine().split(" ");
        int[] arr = new int[input.length+1];
        for (int i = 1; i <= input.length; i++) {
            arr[i] = Integer.parseInt(input[i-1]);
        }
        buildTree(arr);
        //检查叶子节点
        for (int i = 0; i < nodes.size(); i++) {
            int degree = 0;
            if (nodes.get(i).left != null){
                degree++;
            }
            if (nodes.get(i).right != null){
                degree++;
            }
            nodes.get(i).degree = degree;
        }
        afterPrint(nodes.get(1));
    }

    private static void buildTree(int[] arr){
        nodes.add(new TreeNode(0,null,null));
        //先将所有的节点放到数组中
        for (int i = 1; i < arr.length; i++) {
            nodes.add(new TreeNode(arr[i],null,null));
        }
        for (int i = 1; i < nodes.size(); i++) {
            if (2 * i < nodes.size()){
                nodes.get(i).left = nodes.get(2 * i);
            }
            if (2 * i +1 < nodes.size()){
                nodes.get(i).right = nodes.get(2 * i +1);
            }
        }
    }

    private static void print(TreeNode node){
        //只输出非叶子节点
        if (node.degree != 0){
            System.out.println(node.val);
        }
    }
    //前序遍历 根[根输出] 左 右
    private static void prePrint(TreeNode node){
        print(node);
        if (node.left != null){
            prePrint(node.left);
        }
        if (node.right != null){
            prePrint(node.right);
        }
    }

    //中序遍历  左 根[根输出] 右
    private static void middlePrint(TreeNode node){
        if (node.left != null){
            middlePrint(node.left);
        }
        print(node);
        if (node.right != null){
            middlePrint(node.right);
        }
    }

    //后续遍历 左-右-根[根输出]
    private static void afterPrint(TreeNode node){
        if (node.left != null){
            afterPrint(node.left);
        }
        if (node.right != null){
            afterPrint(node.right);
        }
        print(node);
    }

    private static class TreeNode{
        private int degree;
        private int val;
        private TreeNode left;
        private TreeNode right;

        public TreeNode(int val, TreeNode left, TreeNode right) {
            this.val = val;
            this.left = left;
            this.right = right;
        }
    }
}

058 【玩牌高手】

给定一个长度为n的整型数组,表示一个选手在n轮内可选择的牌面分数。选手基于规则选牌,请计算所有轮结束后其可以获得的最高总分数。选择规则如下:
1、在每轮里选手可以选择获取该轮牌面,则其总分数加上该轮牌面分数,为其新的总分数。
2、选手也可不选择本轮牌面直接跳到下一轮,此时将当前总分数还原为3轮前的总分数,若当前轮次小于等于3(即在第1、2、3轮选择跳过轮次),则总分数置为0。
3、选手的初始总分数为0,且必须依次参加每一轮。
输入描述:
第一行为一个小写逗号分割的字符串,表示n轮的牌面分数,1<= n <=20。
分数值为整数,-100 <= 分数值 <= 100。
不考虑格式问题。
输出描述:
所有轮结束后选手获得的最高总分数。
示例1
输入
1,-5,-6,4,3,6,-2
输出
11
说明
总共有7轮牌面。
第一轮选择该轮牌面,总分数为1。
第二轮不选择该轮牌面,总分数还原为0。
第三轮不选择该轮牌面,总分数还原为0。
第四轮选择该轮牌面,总分数为4。
第五轮选择该轮牌面,总分数为7。
第六轮选择该轮牌面,总分数为13。
第七轮如果不选择该轮牌面,则总分数还原到3轮1前分数,即第四轮的总分数4,如果选择该轮牌面,总分数为11,所以选择该轮牌面。
因此,最终的最高总分为11。

059 【相对开音节】

相对开音节构成的结构为辅音+元音(aeiou)+辅音(r除外)+e,常见的单词有bike、cake等。
给定一个字符串,以空格为分隔符,反转每个单词中的字母,若单词中包含如数字等其他非字母时不进行反转。
反转后计算其中含有相对开音节结构的子串个数(连续的子串中部分字符可以重复)。
输入描述:
字符串,以空格分割的多个单词,字符串长度<10000,字母只考虑小写
输出描述:
含有相对开音节结构的子串个数,注:个数<10000
示例1
输入
ekam a ekac
输出
2
说明
反转后为 make a cake 其中make、cake为相对开音节子串,返回2
示例2
输入
!ekam a ekekac
输出
2
说明
反转后为!ekam a cakeke 因!ekam含非英文字符所以未反转,其中 cake、keke为相对开音节子串,返回2

public class ZT59 {
    public static void main(String[] args) {
        Scanner sc =new Scanner(System.in);
        String[] input = sc.nextLine().split(" ");
        int total = 0;
        for (int i = 0; i < input.length; i++) {
            String content = input[i];
            boolean flag = true;
            for (int j = 0; j < content.length(); j++) {
                if (content.charAt(j) < 'a' ||  content.charAt(j)> 'z'){
                    flag = false;
                    break;
                }
            }
            if (flag){
                total += checkKai(content);
            }
        }
        System.out.println(total);
    }

    private static int checkKai(String str){
        String strTemp = "";
        for (int i = str.length()-1; i >=0 ; i--) {
            strTemp += str.charAt(i);
        }

        int left = 0;
        int right = 0;
        int total = 0;
        String tem = "";
        while (right<=str.length()){
            tem = strTemp.substring(left,right);
            if (tem.length() < 4 ){
                right++;
                continue;
            }
            if (checkTrue(tem)) {
                total++;
            }
            left++;
            right++;

        }
        return total;
    }

    private static boolean checkTrue(String str){
        //辅音+元音(aeiou)+辅音(r除外)+e blame
        if (!yuanyin.contains(str.charAt(0)) && 'e' == str.charAt(str.length()-1)){//首位是辅音 末尾是元音
            int temYuan = 0;
            for (int i = 1; i < str.length()-1; i++) {//中间2位或3位
                if (yuanyin.contains(str.charAt(i))){
                    temYuan = i;
                }
                if (temYuan!= 0 && !yuanyin.contains(str.charAt(i)) && str.charAt(i) != 'r' && i> temYuan){
                    return true;
                }
            }
        }
        return false;
    }

    private static List<Character> yuanyin = new ArrayList<>();
    static {
        char[] f1 = {'a','e','i','o','u'};
        for (int i = 0; i < f1.length; i++) {
            yuanyin.add(f1[i]);
        }
    }
}

060 【消消乐游戏】

游戏规则:输入一个只包含英文字母的字符串,字符串中的两个字母如果相邻且相同,就可以消除。
在字符串上反复执行消除的动作,直到无法继续消除为止,此时游戏结束。
输出最终得到的字符串长度。
输入描述:
输入原始字符串 str ,只能包含大小写英文字母,字母的大小写敏感, str 长度不超过100。
输出描述:
输出游戏结束后,最终得到的字符串长度
示例1
输入
gg
输出
0
说明
gg 可以直接消除,得到空串,长度为0
示例2
输入
mMbccbc
输出
3
说明
在 mMbccbc 中,可以先消除 cc ;此时字符串变成 mMbbc ,可以再消除 bb ;此时字符串变成 mMc ,此时没有相邻且相同的字符,无法继续消除。最终得到的字符串为 mMc ,长度为3
备注:
输入中包含 非大小写英文字母 时,均为异常输入,直接返回 0

public class ZT60 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String input = sc.nextLine();
        while (true){
            char pre = input.charAt(0);
            boolean flag = false;
            for (int i = 1; i < input.length(); i++) {
                if (input.charAt(i) == pre){
                    input = input.substring(0,i-1) + input.substring(i+1);
                    flag = true;
                    break;
                }else {
                    pre = input.charAt(i);
                }
            }
            if (!flag || input.length() == 0){
                System.out.println(input.length());
                return;
            }
        }
    }
}
  • 1
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

旧梦昂志

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

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

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

打赏作者

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

抵扣说明:

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

余额充值