2020全国大学生计算机能力挑战赛模拟题(Java组)

一、题解

1、

题目:

统计1到N(含)之间所有立方数的个数,并输出这个数目。
提示:立方数的个数,如8是2的立方数,27是3的立方数,9不是立方数。
输入说明:一个整数N(N<100000);
输出说明:立方数的个数
输入样例:200
输出样例:5

题解:

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int N = scanner.nextInt();
        int index = 0;
        for (int i = 1; i <= N; i++) {
            if (isPow(i)) index++;
        }
        System.out.println(index);
        scanner.close();
    }

    private static boolean isPow(int i){
        if (i == 1)return true;
        for (int j = 1; j < i/2; j++) {
            if (Math.pow(j, 3) == i) return true;
        }
        return false;
    }

}

2、

题目:

统计整数区间[N, M] (N,M<100000)中所有非偶数的合数个数,并输出这个数。
输入说明:两个整数N、M;
输出说明:非偶数的合数个数
输入样例:2 16
输出样例:2

题解:

import java.util.Scanner;
//所谓合数其实就是非素数
public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int N = scanner.nextInt();
        int M = scanner.nextInt();
        int index = 0;
        for (int i = N; i<= M; i++){
            if (isJi(i) && isHe(i)){
                index++;
            }
        }
        System.out.println(index);
        scanner.close();
    }

    private static boolean isHe(int n){
        for (int i=2;i<=(int)Math.sqrt(n);i++){
            if (n%i==0) return true;
        }
        return false;
    }
    private static boolean isJi(int num){
        return num%2 != 0;
    }
}

3、

题目:

字母连连看,给定一个由小写英文字母组成的字符串(长度<1000),如果字符串中有两个连续的字母相同,则这两个字母可同时消除,并不断重复该操作,直到不能消除为止。请编程判断该字符串是否可以完全消除。
输入说明:一个字符串。
输出说明:如果可以完全消除,输出“YES”,如果不可以,输出消除后的结果。
输入样例1:abacddcaba
输出样例1:YES
输入样例2:asdfghhgf
输出样例2:asd

题解:

import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String str = scanner.next();
        char[] chars = str.toCharArray();
        for (int i = 0; i < chars.length - 1; i++) {
            char c1 = chars[i];
            char c2 = chars[i+1];
            if (c1 == c2){
                char[] newChars = new char[chars.length-2];
                for (int j = 0; j < chars.length-2; j++) {
                    if (j >= i){
                        newChars[j] = chars[j+2];
                    }else {
                        newChars[j] = chars[j];
                    }
                }
                chars = newChars;
                i = -1;
            }
        }
        StringBuffer sb = new StringBuffer();
        if (chars.length == 0){
            System.out.println("YES");
        } else {
            for (char aChar : chars) {
                sb.append(aChar);
            }
            System.out.println(sb.toString());
        }
        scanner.close();
    }
}

算法优化:

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String next;
        next = getRandomStr(999);
        char[] chars = next.toCharArray();
        List<Character> characterList = new ArrayList<>();
        for (char aChar : chars) {
            characterList.add(aChar);
        }
        int i = 0,j = i+1;
        while(characterList.size() != 0 && i <= characterList.size()-1 && j <= characterList.size() -1){
            Character character = characterList.get(i);
            Character character1 = characterList.get(j);
            if (character1.equals(character)){
                characterList.remove(i);
                characterList.remove(j-1);
                i--;
                j--;
            }else{
                i++;
                j++;
            }
        }
        System.out.println(characterList.size());
        if (characterList.size() == 0) System.out.println("YES");
        else{
            for (Character character : characterList) {
                System.out.print(character);
            }
        }
        scanner.close();
    }
    /**
     * 获取指定长度的随机字符串
     *
     * @param length 指定长度
     * @return 随机字符串
     */
    public static String getRandomStr(int length) {
        //  final String key = "0123456789";
        final String key = "0123456789QWERTYUIOPLKJHGFDSAZXCVBNMqwertyuioplkjhgfdsazxcvbnm";

        StringBuilder ret = new StringBuilder();
        Random r = new Random();
        for (int i = 0; i < length; i++) {
            ret.append(key.charAt(r.nextInt(key.length())));
        }
        return ret.toString();
    }
}

4、

题目:

由N(N<=10000)个整数组成的数组,其中连续K(K<=200)个元素构成一个区间,称为K区间。一个K区间中所有素数的和记为Sk,请计算整个数组中,所有K区间中的最大Sk值,并输出。
输入说明:第一行是两个整数N和K,第二行输入N个数,表示数组中的元素。
输出说明:最大Sk值
输入样例:8 2
12 23 27 34 19 17 45 8
输出样例:36

题解:

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int N = scanner.nextInt();
        int K = scanner.nextInt();
        int [] array = new int[N];
        for (int i = 0; i < N; i++) {
            array[i] = scanner.nextInt();
        }
        List<Integer> list = new ArrayList<>();
        for (int i = 0; i < array.length - K; i++) {
            int index = 0;
            for (int j = 0; j < K; j++) {
                if (isPrime(array[i+j])){
                    index+=array[i+j];
                }
            }
            list.add(index);
        }
        System.out.println(Collections.max(list));
        scanner.close();
    }

    private static boolean isPrime(int n){
        for (int i=2;i<=(int)Math.sqrt(n);i++){
            if (n%i==0) return false;
        }
        return true;
    }
}

算法优化(双指针、滑动窗口):

public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int k = scanner.nextInt();
        int[] array = new int[n];
        for (int i = 0; i < n; i++) {
            array[i] = scanner.nextInt();
        }
        int begin = 0;
        int end = begin;
        List<Integer> list = new ArrayList<>();
        int max = 0;
        while(end <= array.length-1){
            if (end - begin == k-1){
                if (isPrime(array[end])){
                    max+=array[end];
                }
                list.add(max);
                max = 0;
                begin = end;
            }else{
                if (isPrime(array[end])){
                    max+=array[end];
                }
                end++;
            }
        }
        Integer max1 = Collections.max(list);
        System.out.println(max1);
    }
    private static boolean isPrime(int n){
        for (int i=2;i<=(int)Math.sqrt(n);i++){
            if (n%i==0) return false;
        }
        return true;
    }

进一步优化:

package code;
import java.util.Scanner;
/**
 * @ClassName Main
 * @Description TODO
 * @Author suobanjin
 * @Date 2021/8/28 13:22
 * @Version 1.0
 */
public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int k = scanner.nextInt();
        int[] array = new int[n];
        for (int i = 0; i < n; i++) {
            array[i] = scanner.nextInt();
        }
        int begin = 0;
        int end = begin;
        int max = 0;
        int proMax = 0;
        while(end <= array.length-1){
            if (end - begin == k-1){
                if (isPrime(array[end])){
                    max+=array[end];
                }
                if (max > proMax)proMax = max;
                //list.add(max);
                max = 0;
                begin = end;
            }else{
                if (isPrime(array[end])){
                    max+=array[end];
                }
                end++;
            }
        }
        System.out.println(proMax);
    }
    private static boolean isPrime(int n){
        for (int i=2;i<=(int)Math.sqrt(n);i++){
            if (n%i==0) return false;
        }
        return true;
    }
}

5、

题目:

仓库新进了几批物资,只知道每批物资的数量和单价,请编写程序,按照每种物资的总价值,由高到低次序输出。
输入说明:第1行 一个整数N,表明物资的批次数量
第2-N+1行,每批物资的类别、数量及单价,中间用空格隔开,其中类别用A-Z加以区分。
输出说明:按物资价值降序输出排序结果,每行输出一种物资。
输入样例:5
A 5 10.00
B 3 2.00
A 5 8.00
B 3 2.50
C 10 3.50
输出样例:A 90.00
C 35.00
B 13.50

题解:

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int N = scanner.nextInt();
        Map<String,Double> map = new TreeMap<>();
        for (int i = 0; i < N; i++) {
            String type = scanner.next();
            int pi = scanner.nextInt();
            double price = scanner.nextDouble();
            double counts = pi * price;
            Double aDouble = map.get(type);
            if (aDouble != null){
                counts+=aDouble;
            }
            map.put(type, counts);
        }
        Map<String, Double> stringDoubleMap = sortMap(map);
        stringDoubleMap.forEach((x,y) -> {
            System.out.print(x+" ");
            System.out.printf("%.2f\n", y);
        });
        scanner.close();
    }

    private static Map<String,Double> sortMap(Map<String,Double> map){
        Map<String,Double> sortedMap = new LinkedHashMap<>();
        List<Map.Entry<String,Double>> entries = new ArrayList<>(map.entrySet());
        entries.sort(new MyComparator());
        Iterator<Map.Entry<String,Double>> iterator = entries.iterator();
        Map.Entry<String,Double> temp = null;
        while(iterator.hasNext()){
            temp = iterator.next();
            sortedMap.put(temp.getKey(), temp.getValue());
        }
        return sortedMap;
    }
    static class MyComparator implements Comparator<Map.Entry<String,Double>> {

        @Override
        public int compare(Map.Entry<String, Double> o1, Map.Entry<String, Double> o2) {
            return (int) (o2.getValue() - o1.getValue());
        }
    }
}

二、总结

总体来看题目难度不大,基本都可以暴力解决,但是暴力解决拿不到满分。目前存在的问题还是只会使用暴力,对一些算法的使用不熟练,还是想着快速解决。

  • 0
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

索半斤_suobanjin

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

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

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

打赏作者

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

抵扣说明:

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

余额充值