第十四届蓝桥杯 三十天刷题 第五天

文章讲述了在解决数的分解、猜生日、成绩统计和最大和等问题时,如何避免暴力方法导致的效率低下,提出了优化策略。例如,通过只遍历两数来找到三数之和,以及利用动态规划解决最大和问题,强调了理解和优化算法的重要性。
摘要由CSDN通过智能技术生成

📢📢📢哈喽哈喽 昨天满课太忙加上我太菜啦 😂所以没能写题解,会腾出时间补上滴~先看今天的题目叭😍


  1. 🌈🌈数的分解🌈🌈

📄题目描述

❓思路分享

🌈这道题目没考到算法,显然暴力是不二之选,我在第一眼看到时就想这部简简单单,当即就三个for循环框框一顿写,我点下运行之后我的电脑开始发出呼呼呼的声音,就这样等了5-6秒,控制台弹出了答案,我去OJ上输出答案,是对的。但幸运的是,我看了一眼大佬们的题解,才发现:男人!真的不能太暴力!

暴力固然是对的,但是像我第一次那样直接不加考虑的三个for循环直接交上去铁定超时,如果不是填空那不是没了吗?

那我们来看一下如何优化吧~

🍎三数相加是2019,那我们只需要遍历两个数,第三个数用2019减去前两个数。而且,要保证我们统计的种类数不重复,应该保持这三个数的相对有序性,在遍历第二个数的时候就不从1开始,而是从前一个数的后一位开始就行啦。这样我们程序的效率就大大提高了!我学到了,你学到了吗?

📗参考代码

public class Main {
    public static void main(String[] args) {
    int ans = 0;
        for(int i = 1; i <= 2019;i++) {
            for(int j = i+1; j <= 2019;j++) {
                int k = 2019 - i -j;
                if(k > j && i + j + k == 2019 && check(i) && check (j) && check(k)) ans++;
            }
        }
        System.out.println(ans);//40785
    }
    
    static boolean check(int x) {
        while(x != 0) {
            if(x%10==2 || x%10 == 4) {
                return false;
            }
            x /= 10;
        }
        return true;
    }
}


  1. 🍬🍬猜生日🍬🍬

📄题目描述

❓思路分析

🍬这个题目不难理解,主要是在读题的时候要知道是叔叔出生日期那八位数字能整除2012,3,12这三个数,明白这一点就没有什么问题了,暴力求就可以啦~

📗参考代码

public class 猜生日 {

    public static void main(String[] args) {
        int sum = 0;
        
        for(int i = 1900; i < 2012; i++) {
            for(int j = 1; j <= 30;j++) {
                sum = i * 10000 + 600 + j;//已知月份是6
                if(sum % 2012 == 0 && sum % 3 == 0 && sum % 12==0) {//判断条件
                    System.out.println(sum);
                }
            }
        }
    }    
}


  1. 🍒🍒成绩统计🍒🍒

📄题目描述

❓思路分析

🍒题目要求我们按照四舍五入取整数,那我们我这里用的是Math.round(double a),大家可以看下图,详细些。

📗参考代码

import java.util.Scanner;

public class 成绩统计 {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        double jige = 0;
        double youxiu = 0;
        for(int i = 1;i<=n;i++) {
            int a = sc.nextInt();
            if(a>=60) { 
                jige++;
            if(a>=85) youxiu++;
            }
        }
        System.out.println(Math.round(jige*100/n)+"%");
        System.out.println(Math.round(youxiu*100/n)+"%");
    }
}


  1. 🍊🍊最大和🍊🍊

📄问题描述

❓思路分享

🍊当我们处在p点时,需要求D(n-p),即n-p的最小质因子a,然后在p后面的a个格子里面找分数最大的格子,那个格子的就成了下一个p,并累加分数,以此类推。。。。。。这个逐渐走向n的过程就成了一个动态规划问题。

心得:思路基本上有,但是,但是,太菜了太菜了,不会写哇😭😭😭太痛苦了家人们,最后的最后,参考大佬(小羊不会飞)的代码终于是写了出来,结果又发现有个超时的,受小羊指点,将D(n-(i+1))用一个临时变量储存起来,这样就不用每次循环都计算,就这一个小小的细节处理,那个超时就解决了,佩服大佬的经验,也看到自己的诸多不足,唉~还是自己主动思考写代码太少了,剩一个月了,要加油呀~

📗参考代码

import java.io.*;
import java.util.Arrays;

public class 最大和 {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));

    public static void main(String[] args) throws IOException {
            int n = Integer.parseInt(br.readLine());
            String[] s = br.readLine().trim().split(" ");
            int[] a = new int[n];//每个格子的分数
            int[] dp = new int[n];
            for(int i = 0; i < n; i++) a[i] = Integer.parseInt(s[i]);
            Arrays.fill(dp, Integer.MIN_VALUE);
            dp[0] = a[0];//开始在第一个格子
            for(int i = 0;i < n;i++) {
                //细节处理,这样就不会在每次在里层循环计算,提高效率,否则会tle一个样例
                int temp = D(n-(i+1));
                for(int j = 1; j <= temp;j++) {
                    //动态规划找下一步要走的步数,即n-p的最小质因子步内分数最大的格子
                    dp[i+j] = Math.max(dp[i]+a[i+j],dp[i+j]);
                }
            }
            out.println(dp[n-1]);
            out.flush();
    }
    
    //求最小质因子
    static int D(int n) {
        if(n==1)return 1;
        if(n==2)return 2;
        if(n==3)return 3;
        if(isPrime(n))return n;//没有质因子,那么最小的就是n本身了
        for(int i = 2;i <= n/i;i++) {
            if(n%i==0 && isPrime(i)) {//i是n的质因子,并且i再没有更小的质因子,那么n的最小质因子就是i
                return i;
            }
        }
        return n;
    }
    
    //如果不存在质因子,返回true
    static boolean isPrime(int n) {
        for(int i = 2; i <= n/i; i++) {
            if(n%i == 0) return false;
        }
        return true;
    }
}


📢📢📢好啦,今天的打卡完成了。再找题做去了,太菜了太菜了,光想不会写也太痛苦了😭

希望大家不要跟我一样,不自己独立写,结果就不会写了,呜呜呜~

加油加油!💪

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值