📢📢📢哈喽哈喽 昨天满课太忙加上我太菜啦 😂所以没能写题解,会腾出时间补上滴~先看今天的题目叭😍
🌈🌈数的分解🌈🌈
📄题目描述
❓思路分享
🌈这道题目没考到算法,显然暴力是不二之选,我在第一眼看到时就想这部简简单单,当即就三个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;
}
}
🍬🍬猜生日🍬🍬
📄题目描述
❓思路分析
🍬这个题目不难理解,主要是在读题的时候要知道是叔叔出生日期那八位数字能整除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);
}
}
}
}
}
🍒🍒成绩统计🍒🍒
📄题目描述
❓思路分析
🍒题目要求我们按照四舍五入取整数,那我们我这里用的是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)+"%");
}
}
🍊🍊最大和🍊🍊
📄问题描述
❓思路分享
🍊当我们处在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;
}
}
📢📢📢好啦,今天的打卡完成了。再找题做去了,太菜了太菜了,光想不会写也太痛苦了😭
希望大家不要跟我一样,不自己独立写,结果就不会写了,呜呜呜~
加油加油!💪