java初赛模拟题和初赛真题

因为模拟题都是往年真题,然后又只是第二年没积累多少真题,所以两套模拟题一共有6题是不重复的,如下:

在这里插入图片描述

package play;

import java.util.Scanner;

public class Question_1 {
    public static void main(String[] args) {
        Long n,res=0l;
        Scanner scanner=new Scanner(System.in);
        n=scanner.nextLong();
        for (long i=1;i<=n;i++){
            for (int j=1;j<=i;j++){
                if(j*j*j==i)res++;
            }
        }
        System.out.println(res);
    }
}


在这里插入图片描述

package play;

import java.util.Scanner;

public class Question_2 {
    public static void main(String[] args) {
        Scanner scanner=new Scanner(System.in);
        long left,right,res=0;
        left=scanner.nextLong();
        right=scanner.nextLong();
        for (long i=left;i<=right;i++){
            if(i%2==0)continue;
            for (long j=2;j<i;j++){
                if(i%j==0){res++;break;}
            }
        }
        System.out.println(res);
    }
}


在这里插入图片描述

package play;

import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Scanner;

public class Question_3 {
    public static void main(String[] args) {
        Scanner scanner=new Scanner(System.in);
        String target=scanner.nextLine();
        //int length=target.length();
        StringBuilder stringBuilder=new StringBuilder(target);
        for (int i=1;i<stringBuilder.length();i++){
            if (stringBuilder.charAt(i) == stringBuilder.charAt(i-1)){
                stringBuilder.delete(i-1,i+1);
                i-=2;
            }
        }
        if (stringBuilder.length()==0) System.out.println("YES");
        else System.out.println(stringBuilder);

    }
}


在这里插入图片描述

package play;

import java.util.Scanner;

public class Question_4 {
    public static void main(String[] args) {
        int res=0,temp=0,max=0;
        Scanner scanner=new Scanner(System.in);
        int length=scanner.nextInt();
        int step=scanner.nextInt();
        int[] data=new int[length];
        for(int i=0;i<length;i++)
            data[i]=scanner.nextInt();
        for(int i=0;i<step;i++)
            if (is(data[i]))res+=data[i];
        for(int i=step;i<length;i++){
            if(is(data[i]))res+=data[i];
            if (is(data[i-step]))res-=data[i-step];
            max=res>max?res:max;
        }
        System.out.println(max);
    }

    static boolean is(int a){
        for(int i=2;i<a;i++){
            if(a%i==0)return  false;
        }
        return true;
    }
}

在这里插入图片描述
我原来的代码是错的:

package play;

import java.util.Scanner;

public class Console {
    public static void main(String[] args) {
        Scanner scanner=new Scanner(System.in);
        int length,step,dk=0,temp;
        length=scanner.nextInt();
        step=scanner.nextInt();
        int data[]=new int[length];
        for (int i=0;i<length;i++){
            data[i]=scanner.nextInt();
        }
        for (int i=0;i<step;i++){
            for (int j=i;j<step;j++){
                temp=Math.abs(data[i]-data[j]);
                if (temp>dk)dk=temp;
            }
        }
        for (int i=step;i<length;i++){
            for (int j=1;j<step;j++){
                temp=Math.abs(data[i]-data[i-j]);
                if (temp>dk)dk=temp;
            }
        }
        System.out.println(dk);
    }

}

用上dp就好了:

package play;

import java.util.Scanner;

public class Console {
    public static void main(String[] args) {
        Scanner scanner=new Scanner(System.in);
        int length,step,dk=0,temp,max=0;
        length=scanner.nextInt();
        step=scanner.nextInt();
        int dp[]=new int[step];
        int data[]=new int[length];
        for (int i=0;i<length;i++){
            data[i]=scanner.nextInt();
        }
        dp[step-1]=0;
        for (int i=step-2;i>=0;i--){
            max=0;
            for (int j=i+1;j<step;j++){
                temp=Math.abs(data[i]-data[j]);
                if (temp>max)max=temp;
            }
            dp[i]=max>dp[i+1]?max:dp[i+1];
        }
        dk=dp[0];
        for (int i=step;i<length;i++){
            for (int j=0;j<step;j++){
                max=0;
                if (j==step-1){break;}
                for (int k=step-j-1;k>0;k--){
                    temp=Math.abs(data[i]-data[i-k]);
                    if (temp>max)max=temp;
                }
                dp[j]=max>dp[j+1]?max:dp[j+1];
            }
            dk=dp[0]>dk?dp[0]:dk;
        }
        System.out.println(dk);
    }

}

然后我为什么要用dp。。。看到别人的代码才发现直接二重循环找每个k区间的最大值和最小值不就行了嘛。和我的时间复杂度一样但是思路比我的好想多了。淦!然后这题明显比上面的19题要难,抽到这题的话真是挺倒霉的,下面是别人的二重循环的代码:

方法一:和另一道题类似,在双重循环中定义最大值max,最小值min为K区间首个元素,下面再进行判断是否还有比max大的重新确定为max,比min小的重新确定为min。max-min即为Dk,保存在数组res中,res长度为N - K + 1,输出即为res中的最大值。

public class Solution4 {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int N = input.nextInt();
        int K = input.nextInt();
        //先划分为 N-K+1 个 K区间,在区间内排序,计算最大绝对值
        //N-K+1 数组的区间数
        int[] nums = new int[N];
        for(int i = 0; i < N; i++){
            nums[i] = input.nextInt();
        }
        int[] res = new int[N - K + 1];
        int max = 0;int min = 0;
        for (int i = 0; i < N - K + 1; i++) {
            for (int j = i; j < i + K ; j++) {
                max = nums[i];
                min = nums[i];

                if(nums[j] > max) {
                    max = nums[j];
                }
                if(nums[j] < min) {
                    min = nums[j];
                }
            }

            res[i] = max - min;

        }
//        Arrays.sort(res);
//        System.out.println(res[N - K]);
        System.out.println(Dk(res));

    }
//找到数组最大值
    private static int Dk(int[] nums) {
        int max = nums[0];
        for(int i = 0; i < nums.length; i++){
            if(nums[i] > max){
                max = nums[i];
            }
        }
        return max;
    }
}

在这里插入图片描述
这里我的代码是错的,不知道怎么改了,麻了

package play;

import java.awt.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.Scanner;

public class Question_5 {
    public static void main(String[] args) {
        float hash[]=new float[26];
        Scanner scanner=new Scanner(System.in);
        int times=scanner.nextInt();
        for (int i=0;i<times;i++){
            hash[scanner.next().charAt(0)-'A']+=scanner.nextInt()*scanner.nextFloat();
        }
        ArrayList<Float> my=new ArrayList<>();
        for (float i : hash)my.add(i);
        my.sort(new Comparator<Float>() {
            @Override
            public int compare(Float o1, Float o2) {
                return o2.compareTo(o1);
            }
        });
        System.out.println(my);
        for (int i=0;i<times;i++){
            int index=0;
            for (int j=0;j<26;j++)if(hash[j]==my.get(i))index=j;
            System.out.printf("%c %f\n",(char)('A'+index),my.get(i));
        }
    }

}

真实的比赛上估计是想不出dp的,能把程序设计写好就不错了。下面是初赛真题(比较难的几题):


在这里插入图片描述

package play;

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner=new Scanner(System.in);
        String res=scanner.nextLine();
        int length=res.length(),i,j;
        int hash[]=new int[26];
        boolean flag[]=new boolean[26];
        int index,sum=0,sum_copy;
        for (i=0;i<length;i++){
            index=res.charAt(i)-'a';
            if (hash[index]==0){hash[index]=1;sum++;}
        }
        sum_copy=sum;
        for (i=0;i<length;i++){
            index=res.charAt(i)-'a';
            if (flag[index]==false&&hash[index]==1){
                flag[index]=true;
                sum--;}
            if (sum==0) {
                //System.out.println(i);
                //System.out.println(res.substring(0,i+1));
                break;
            }

        }
        i++;
        //System.out.println(i);
        for (j=1;j<i;j++){
            if(!ok(res.substring(j,i),sum_copy,hash)){
                System.out.println(res.substring(j-1,i));
                break;
            }
        }
    }

    private static boolean ok(String substring,int sum,int []hash) {
        boolean flag[]=new boolean[26];
        for (int i=0;i<substring.length();i++){
            int index=substring.charAt(i)-'a';
            if (flag[index]==false&&hash[index]==1){
                flag[index]=true;
                sum--;}
            if (sum==0) {
                return true;
            }
        }
        return false;
    }


}

在这里插入图片描述
这题其实一点也不难,总共就只有10个数,直接弄一个10个大小的数组把前10个素数写出来,然后用前缀乘的方法把每一位改成他这一位对应的权,然后对于每一位数,把那10个大小的数组当hash表找到他的权相乘就行了。我就是做第18题卡壳了,然后做到19题就很紧张,首先粗略一看——基于质数的变进制数是什么鬼,算了算了肯定不重要,然后看后面——哦,第一位是2进制,第2位是3进制是把,然后!!第三位的哪个5TM的在第二行,我直接漏看了臆测他是4进制。然后我直接看了输入样例,当时就时间剩下不到半个小时了,我还是在第18题没写完的情况下来做19题的,然后我就犯了两个错误:
第一:把321的1当成了第0位,其实他按题意是第1位
第二:把出题的人当成笨蛋了,我就看着用例的模式,心里想着——哦,好吧,2是第一位,他是二进制,所以他的权是2*1,3是第二位,他是三进制,所以他的权是3*2*1,那如果有第3位,他就是4进制,他的权就是4*3*2*1,好的我会了!

关键还是把第二位当第一位了,想起小甲鱼说过的,军事级别的专家来出题都是从1开始数数的。下次只要坚定这一点或者认真看题这题还是很简单的。


下面是另一个老哥2019年的初赛真题,把他的后3题做了一下:

package play;

import java.util.Scanner;

public class Question_3 {
    public static void main(String[] args) {
        Scanner scanner=new Scanner(System.in);
        String ss=scanner.nextLine();
        String ts=scanner.nextLine();
        int length=ts.length();
        int index=0;
        boolean flag=true;
        for (int i=0;i<length;i++){
            index=ss.indexOf(ts.charAt(i),index);
            if (index==-1)flag=false;
            index++;
        }
        if (flag) System.out.println("YES");
        else System.out.println("NO");
    }
}

package play;

import java.util.Scanner;

public class Question_4 {
    public static void main(String[] args) {
        Scanner scanner=new Scanner(System.in);
        int length=scanner.nextInt();
        int target=scanner.nextInt();
        if (length<3) System.out.println(-1);;                //一定要特判
        int[] inputs=new int[length];
        for (int i=0;i<length;i++){
            inputs[i]=scanner.nextInt();
        }
        for (int i=0;i<length;i++){
            for (int j=i+1;j<length;j++){
                for (int k=j+1;k<length;k++){
                    if (inputs[i]+inputs[j]+inputs[k]==target){
                        System.out.printf("%d %d %d",i+1,j+1,k+1);
                        return;
                    }
                }
            }
        }

    }

}
package play;

import java.util.Scanner;

public class Question_5 {
    public static void main(String[] args) {
        Scanner scanner=new Scanner(System.in);
        String input=scanner.nextLine();
        int length=input.length();
        int[] vetor=new int[1000];
        int j=0,res;
        for (int i=0;i<length;i++){
            char temp=input.charAt(i);
            if (temp<='9'&&temp>='0'){
                char temp2;
                if (i-1>=0&&(temp2=input.charAt(i-1))<='9'&&temp2>='0'&&vetor[j-1]!=-1)vetor[j-1]=Integer.parseInt(input.substring(i, i + 1))+vetor[j-1]*10;
                else vetor[j++] = Integer.parseInt(input.substring(i, i + 1));
            }
            else if (temp=='+')vetor[j++]=-1;
        }
        res=j>0?vetor[0]:0;
        for (int i=1;i<j;i++){
            if (i+1<j&&vetor[i+1]==-1)vetor[++i+1]+=vetor[i++-1];
            res*=vetor[i];
        }
        System.out.println(res);
    }

}

下面是另一个老哥的2020年初赛真题,他的18题和我一样,19题如下:
题目:某商品有2种不同数量的包装,对应不同的价格;同时提供满200元减50元的不限量购物券,试求解最佳购买策略,在单次购买中以最低总价购买正好500个商品。
输入说明:两种包装的数量和价格(均为整数)
输出说明:两种商品各自购买数量(无解则输出:-1)
输入样例:100 80 200 150
输出样例:5 0
我的代码有重复很啰嗦,很久没有做遍历的题了:

package play;

import java.util.HashSet;
import java.util.Scanner;

public class Main {
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int one_count = sc.nextInt();
        int one_price = sc.nextInt();
        int two_count = sc.nextInt();
        int two_price = sc.nextInt();
        int min=Integer.MAX_VALUE,now,i_=-1,j=-1;
        if (500%one_count==0||500%one_count==two_count){
            for (int i=500/one_count;i>=1;i--){
                int temp=(500-i*one_count);
                if (temp%two_count==0){
                    now=i*one_price+temp/two_count*two_price;
                    now-=now/200*50;
                    if (now<min){
                        min=now;
                        i_=i;
                        j=temp/two_count;
                    }
                }
            }
        }
        if (500%two_count==0||500%two_count==one_count){
            for (int i=500/two_count;i>=1;i--){
                int temp=(500-i*two_count);
                if (temp%one_count==0){
                    now=i*two_price+temp/one_count*one_price;
                    now-=now/200*50;
                    if (now<min){
                        min=now;
                        i_=i;
                        j=temp/one_count;
                    }
                }
            }
        }
        System.out.println(i_==-1?-1:i_+" "+j);
    }
}

小哥本人的代码写得不错:

import java.util.Scanner;

public class Main {
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int one_count = sc.nextInt();
        int one_price = sc.nextInt();
        int two_count = sc.nextInt();
        int two_price = sc.nextInt();
        int min = 10000, one_res = 0, two_res = 0;
        boolean flag = false;   // 是否有解
        for ( int i = 0; i <= 500/one_count; i++ ) {
            if ( (500-i*one_count) % two_count != 0 )    // 凑不成 500
                continue;
            int temp = i * one_price + ( 500 - i * one_count ) / two_count * two_price;
            temp = temp - (temp / 200 * 50);      // 不限量 满200减50
            if ( temp < min ) {
                min = temp;
                one_res = i;
                two_res = ( 500 - one_res * one_count ) / two_count;
                flag = true;
            }
        }
        System.out.println( flag ? String.format("%d %d", one_res, two_res) : -1);
        sc.close();
    }
}

上面就是目前搜集到的可供训练题目。要是题不够做,去刷leetcode上的简单题,只看第一个测试用例并且只允许自己提交一次就和比赛差不多了。

有不对的地方欢迎指出,一起交流

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值