【2020】牛客模考(一模)编程题集合

1. 数组变换

牛牛有一个数组,里面的数可能不相等,现在他想把数组变为:所有的数都相等。问是否可行。
牛牛可以进行的操作是:将数组中的任意一个数改为这个数的两倍。
这个操作的使用次数不限,也可以不使用,并且可以对同一个位置使用多次。
输入描述

输入一个正整数N (N <= 50)
接下来一行输入N个正整数,每个数均小于等于1e9.

输出描述

假如经过若干次操作可以使得N个数都相等,那么输出"YES", 否则输出"NO"

输入例子

2
1 2

输出例子

YES

题解
找出最大的数,判断最大的数是否是其它数的2*N倍即可。

import java.util.*;
public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int N = sc.nextInt();
        int[] a = new int[N];
        int max = Integer.MIN_VALUE;
        for (int i = 0; i < N; i++) {
            a[i] = sc.nextInt();
            if (a[i] > max) {
                max = a[i];
            }
        }
        for (int i = 0; i < N; i++) {
            if (max % a[i] != 0) {
                System.out.println("NO");
                return;
            }
        }
        System.out.println("YES");
    }
}
2. 排序子序列

牛牛定义排序子序列为一个数组中一段连续的子序列,并且这段子序列是非递增或者非递减排序的。牛牛有一个长度为n的整数数组A,他现在有一个任务是把数组A分为若干段排序子序列,牛牛想知道他最少可以把这个数组分为几段排序子序列.
如样例所示,牛牛可以把数组A划分为[1,2,3]和[2,2,1]两个排序子序列,至少需要划分为2个排序子序列,所以输出2。
输入描述

输入的第一行为一个正整数n(1 ≤ n ≤ 10^5)
第二行包括n个整数A_i(1 ≤ A_i ≤ 10^9),表示数组A的每个数字。

输出描述

输出一个整数表示牛牛可以将A最少划分为多少段排序子序列。

输入例子

6
1 2 3 2 2 1

输出例子

2

题解
寻找波峰和波谷,关键代码(a[i] > a[i-1] && a[i] > a[i+1] || a[i] < a[i-1] && a[i] < a[i+1])

import java.util.*;
public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int[] a = new int[n];
        for (int i = 0; i < n; i++) {
            a[i] = sc.nextInt();
        }
        int count = 1;
        for (int i = 1; i < n - 1; i++) {
            if (a[i] > a[i-1] && a[i] > a[i+1] || a[i] < a[i-1] && a[i] < a[i+1]) {
                count++;
                if(n - 3 != i) {
                    i++;
                }
            }
        }
        System.out.println(count);
    }
}
3. 牛牛的数列

牛牛现在有一个n个数组成的数列,牛牛现在想取一个连续的子序列,并且这个子序列还必须得满足:最多只改变一个数,就可以使得这个连续的子序列是一个严格上升的子序列,牛牛想知道这个连续子序列最长的长度是多少。
输入描述

输入包括两行,第一行包括一个整数n(1 ≤ n ≤ 10^5),即数列的长度;
第二行n个整数a_i, 表示数列中的每个数(1 ≤ a_i ≤ 10^9),以空格分割。

输出描述

输出一个整数,表示最长的长度。

输入例子

6
7 2 3 1 5 6

输出例子

5

题解
对每一个数组中的数,如果前后的元素相差大于2,递增子序列数目至少为3,向前向后找递增序列并累计,第一个元素和最后一个元素另外求,得到改变每一个元素得到的最大的递增子序列的长度形成一个数组,数组中最大的值就是所求。

import java.util.*;
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int[] a = new int[n+2];
        for (int i = 1; i <= n; i++) {
            a[i] = sc.nextInt();
        }
        int[] left = new int[n+1];
        int[] right = new int[n+2];
        for (int i = 1; i <= n; i++) {
            left[i] = a[i-1] < a[i] ? left[i-1]+1 : 1;
        }
        for (int j = n; j > 0; j--) {
            right[j] = a[j] < a[j+1] ? right[j+1]+1 : 1;
        }
        int result = 1;
        for (int i = 1; i <= n; i++) {
            result = Math.max(result, left[i-1] + 1);
            result = Math.max(result, right[i+1] + 1);
            if(a[i+1] - a[i-1] >= 2) {
                result = Math.max(result, left[i-1] + right[i+1] + 1);
            }
        }
        System.out.println(result);
    }
}
4. 添加字符

牛牛手里有一个字符串A,羊羊的手里有一个字符串B,B的长度大于等于A,所以牛牛想把A串变得和B串一样长,这样羊羊就愿意和牛牛一起玩了。
而且A的长度增加到和B串一样长的时候,对应的每一位相等的越多,羊羊就越喜欢。比如"abc"和"abd"对应相等的位数为2,为前两位。
牛牛可以在A的开头或者结尾添加任意字符,使得长度和B一样。现在问牛牛对A串添加完字符之后,不相等的位数最少有多少位?
输入描述

第一行为字符串A,第二行为字符串B,A的长度小于等于B的长度,B的长度小于等于50.字符均为小写字母。

输出描述

输出一个整数表示A串添加完字符之后,不相等的位数最少有多少位?

输入例子

abe
cabc

输出例子

1

题解
字符串A与字符串B从头开始逐位比较,找到最短的不相等的位数。

import java.util.*;
public class Main {
    public static void main (String[] args) {
        Scanner sc = new Scanner(System.in);
        String A = sc.next();
        String B = sc.next();
        char[] cha = A.toCharArray();
        char[] chb = B.toCharArray();
        int min = Integer.MAX_VALUE;
        for (int i = 0; i < chb.length - cha.length + 1; i++) {
            int count = 0;
            for (int j = 0; j < cha.length; j++) {
                if (cha[j] != chb[i+j]) {
                    count++;
                }
            }
            min = Math.min(min, count);
        }
        System.out.println(min);
    }
}
5. 变换次数

牛牛想对一个数做若干次变换,直到这个数只剩下一位数字。
变换的规则是:将这个数变成 所有位数上的数字的乘积。比如285经过一次变换后转化成285=80.
问题是,要做多少次变换,使得这个数变成个位数。
输入描述

输入一个正整数。小于等于2,000,000,000。

输出描述

输出一个整数,表示变换次数。

输入例子

285

输出例子

2

题解
将每个数拆分,重复求乘积即可。

import java.util.*;
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int count = 0;
        while (n > 10) {
            n = solve(n);
            count++;
        }
        System.out.println(count);
    }
    public static int solve(int n) {
        int res = 1;
        while (true) {
            if (n < 10) {
                return res *= n;
            }else{
                res *= (n % 10);
                n = n / 10;
            }
        }
    }
}
6. 神奇数

给出一个区间[a, b],计算区间内“神奇数”的个数。
神奇数的定义:存在不同位置的两个数位,组成一个两位数(且不含前导0),且这个两位数为质数。
比如:153,可以使用数字3和数字1组成13,13是质数,满足神奇数。同样153可以找到31和53也为质数,只要找到一个质数即满足神奇数。
输入描述

输入为两个整数a和b,代表[a, b]区间 (1 ≤ a ≤ b ≤ 10000)。

输出描述

输出为一个整数,表示区间内满足条件的整数个数

输入例子

11 20

输出例子

6

题解
首先保存[10,99]中的所有质数,然后开双重循环,外层循环遍历[a,b],内层循环遍历保存的质数,都转换为字符串,使用String.indexOf( )判断外层循环每一个数是否包含某个质数的所有位数。

import java.util.*;
public class Main {
    public static void main (String[] args) {
        Scanner sc = new Scanner(System.in);
        int a = sc.nextInt();
        int b = sc.nextInt();
        // 存储质数
        List<Integer> list = new ArrayList<>();
        for (int i = 10; i <= 99; i++) {
            boolean isOdd = true;
            for (int j = 2; j <= Math.sqrt(i); j++) {
                if(i % j == 0) {
                    isOdd = false;
                    break;
                }
            }
            if (isOdd) {
                list.add(i);
            }
        }
        int cnt = 0;
        for (int i = a; i <= b; i++) {
            String str = String.valueOf(i);
            for (Integer num : list) {
                String ge = String.valueOf(num%10);
                String shi = String.valueOf(num/10);
                // i = 277这种情况
                if (ge.equals(shi)) {
                    int index = str.indexOf(ge);
                    if(index != -1 && str.indexOf(shi, index + 1) != -1){
                        cnt++;
                        break;
                    }
                }else {
                    if(str.indexOf(ge) != -1 && str.indexOf(shi) != -1) {
                        cnt++;
                        break;
                    }
                }
            }
        }
        System.out.println(cnt);
    }
}
7. 组队竞赛

牛牛举办了一次编程比赛,参加比赛的有3*n个选手,每个选手都有一个水平值a_i.现在要将这些选手进行组队,一共组成n个队伍,即每个队伍3人.牛牛发现队伍的水平值等于该队伍队员中第二高水平值。
例如:
一个队伍三个队员的水平值分别是3,3,3.那么队伍的水平值是3
一个队伍三个队员的水平值分别是3,2,3.那么队伍的水平值是3
一个队伍三个队员的水平值分别是1,5,2.那么队伍的水平值是2
为了让比赛更有看点,牛牛想安排队伍使所有队伍的水平值总和最大。
如样例所示:
如果牛牛把6个队员划分到两个队伍
如果方案为:
team1:{1,2,5}, team2:{5,5,8}, 这时候水平值总和为7.
而如果方案为:
team1:{2,5,8}, team2:{1,5,5}, 这时候水平值总和为10.
没有比总和为10更大的方案,所以输出10.
输入描述

输入的第一行为一个正整数n(1 ≤ n ≤ 10^5)
第二行包括3*n个整数a_i(1 ≤ a_i ≤ 10^9),表示每个参赛选手的水平值.

输出描述

输出一个整数表示所有队伍的水平值总和最大值.

输入例子

2
5 2 8 5 1 5

输出例子

10

题解
对数组排序,每只队伍的值包含{小,中,大}三个数,要使每支队伍的值尽可能大,则使“小”的值最小,“大”的值最大,“中”的值尽可能大,故排序后“小”值从左往右取,“中”值和“大”值从右往左取即可。

import java.util.*;
public class Main {
    public static void main (String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        long[] a = new long[n*3];
        for (int i = 0; i < n*3; i++) {
            a[i] = sc.nextLong();
        }
        Arrays.sort(a);
        long sum = 0;
        for (int j = a.length - 2, i = n; i > 0; i--, j -= 2) {
            sum += a[j];
        }
        System.out.println(sum);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值