第一题: 数的分解
题目描述
本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。
把 20192019 分解成 33 个各不相同的正整数之和,并且要求每个正整数都不包含数字 22 和 44,一共有多少种不同的分解方法?
注意交换 33 个整数的顺序被视为同一种方法,例如 1000+1001+181000+1001+18 和 1001+1000+181001+1000+18 被视为同一种。
解法:直接模拟即可
public class Main {
static long res = 0;
static boolean check(int x) {
while(x > 0) {
int t = x % 10;
if(t == 2 || t == 4) return false;
x /= 10;
}
return true;
}
public static void main(String[] args) {
for(int a = 1; a <= 2019; a++) {
if(!check(a)) continue;
for(int b = a+1; b <= 2019; b++) {
if(!check(b)) continue;
int c = 2019 - a - b;
if(c <= b || !check(c)) continue;
else res++;
}
}
System.out.println(res);
}
}
![](https://i-blog.csdnimg.cn/blog_migrate/50383314fecd4be549d422d89bf29911.png)
第二题: 猜生日
题目描述
本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。
今年的植树节(2012 年 3月 12 日),小明和他的叔叔还有小伙伴们一起去植树。休息的时候,小明的同学问他叔叔多大年纪,他叔叔说:“我说个题目,看你们谁先猜出来!”
“把我出生的年月日连起来拼成一个 88 位数(月、日不足两位前补 00)正好可以被今天的年、月、日整除!”
他想了想,又补充到:“再给个提示,我是 66 月出生的。”
根据这些信息,请你帮小明算一下,他叔叔的出生年月日。
格式是年月日连成的 88 位数。例如,如果是 19481948 年 66 月 1212 日,就写:1948061219480612。
解法: 第一层枚举年份, 第二层枚举日期 , 拼接成字符串, 再转换成整数,检查这个整数是否能被2012、3、 12 整除。
public class Main {
static boolean check(int x) {
if(x % 2012 == 0 && x % 3 == 0 && x % 12 == 0) return true;
return false;
}
public static void main(String[] args) {
for(int y = 1000; y <= 2012; y++) {
for(int d = 1; d <= 30; d++) {
String s = "";
int x;
if(d < 10) {
s = y + "06" + "0" + d;
x = Integer.parseInt(s);
}else {
s = y + "06" + d;
x = Integer.parseInt(s);
}
if(check(x)) {
System.out.println(s);
}
}
}
//System.out.println(19550604); 最后答案
}
}
![](https://i-blog.csdnimg.cn/blog_migrate/c1f2a8492a34c5f65d5b57fd39b3d405.png)
第三题: 成绩统计
![](https://i-blog.csdnimg.cn/blog_migrate/0ad8a6e829abd0ec1f9cd6ec3123c582.png)
![](https://i-blog.csdnimg.cn/blog_migrate/2c27d9fd023155e70b67690a22c5c8e7.png)
解法: 模拟题目要求,注意格式要求
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
int n = s.nextInt();
int cnt60 = 0, cnt85 = 0;
for(int i = 1; i <= n; i++) {
int x = s.nextInt();
if(x >= 60) cnt60++;
if(x >= 85) cnt85++;
}
int res1 = (int) ((cnt60)*100*1.0/n + 0.5);
int res2 = (int)((cnt85)*100*1.0/n + 0.5);
System.out.println(res1 + "%");
System.out.println(res2 + "%");
}
}
![](https://i-blog.csdnimg.cn/blog_migrate/4dde4e65b1cd640859cdcc9326d58d58.png)
第四题: 最大和
![](https://i-blog.csdnimg.cn/blog_migrate/1cfa6824433f1711ee2c923440e7f119.png)
![](https://i-blog.csdnimg.cn/blog_migrate/b05130383e6bfe5640507a8cf0691742.png)
解法: dp[p]定义为 跳到 每个p上能获得的最大总分值 。
外层遍历每个 i, 内层遍历 从 i 能跳到的每个p ,对能跳到的dp[p] 取最大值 。
![](https://i-blog.csdnimg.cn/blog_migrate/55fbe466043e40fe5e285a1497e001a8.png)
import java.util.Arrays;
import java.util.Scanner;
public class Main {
static int N = (int)1e4 + 10, INF = 0x3f3f3f3f;
static long[] dp = new long[N]; //dp[p]定义为 跳到 每个p上能获得的最大总分值
static int[] a = new int[N];
static int divide(int x) { // 返回最小的质素
for(int i = 2; i <= x/i; i++) {
if(x % i == 0) return i;
}
return x;
}
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
int n = s.nextInt();
for(int i = 1; i <= n; i++) {
a[i] = s.nextInt();
}
Arrays.fill(dp, -INF); // 初始化为最大负数
dp[1] = a[1];
for(int i = 1; i <= n; i++) {
int p = i, d = divide(n-p);
for(p = i+1; p <= i+d; p++) { // i 能跳到 i+1 ~ i + d;
dp[p] = Math.max(dp[p], dp[i]+a[p]);
}
}
System.out.println(dp[n]);
}
}
![](https://i-blog.csdnimg.cn/blog_migrate/1391ea9bd008f777f2bfbe2e5c9a1022.png)
最后祝福大家要开心~~
![](https://i-blog.csdnimg.cn/blog_migrate/32fec3e4f43fd255ea5499a8d563b6f7.jpeg)