3.8w+
社区成员
三角回文数
三角回文数 => 即三角又回文
20220514是一个8位数,那就从5000开始遍历判断一个数是否是三角数吧🤐,很捞的解法,但是不会超时
public class Main {
public static void main(String[] args) {
for(int i = 20220515; ; i++) {
if(isRev(i) && isTriangle(i)) {
System.out.print(i);
break;
}
}
}
public static boolean isRev(int num) {
String str = String.valueOf(num);
int len = str.length();
for(int i = 0; i < len / 2; i++) {
if(str.charAt(i) != str.charAt(len - 1 - i)) {
return false;
}
}
return true;
}
public static boolean isTriangle(int num) {
for(int i = 5000; ; i++) {
int tmp = i * (i + 1) / 2;
if(tmp > num) {
break;
}
if(tmp == num) {
return true;
}
}
return false;
}
}
数数
暴力,会超时
感觉可以用埃式筛/欧拉筛做一下,待定...
public class Main{
public static void main(String[] args) {
int result = 0;
for(int i = 2333333; i <= 23333333; i++) {
int tmp = i;
int count = 0;
for(int j = 2; j <= tmp / j; j++) {
while(tmp % j == 0) {
count++;
tmp /= j;
}
}
//!!!重要且容易被忽视的判断,大于1说明剩余的tmp为质数,因非质数都会被拆出来
if(tmp > 1) count++;
if(count == 12) result++;
}
System.out.print(result); // result = 25606
}
}
数组切分
通过梗哥和One哥的题解,对本题的一些理解
本题的关键:一个长度为 N 的数组,A1,A2,A3,…AN 恰好是 1 ∼ N 的一个排列。
1、要判断一个子数组是否恰好可以组成一段连续的自然数,可以用该子数组区间的 最大值 - 最小值 和区间长度进行比较
相等,说明该子数组可以组成一段连续的自然数
2、状态的定义:dp[i]:以 数组下标为i结尾的自然数的所有切分数
3、从数组下标为i(i = 1)(索引从1开始)开始往后遍历,遍历到当前元素后,再向前遍历j = i(j >= 1),判断 区间[j, i]的子数组是否满足题目
满足,则 以数组下标为i结尾的自然数的所有切分数 = 以数组下标为i结尾的自然数的所有切分数 + 以数组下标为j-1结尾的自然数的所有切分数,即 dp[i] = dp[i] + dp[j - 1]
不满足,则 j 继续向前遍历
由此可见状态转移方程为:dp[i] = dp[i] + dp[j - 1] if max(0...i) - min(0...j) == j - i
为什么每次满足 max(0...i) - min(0...j) == j - i 都要加上 dp[i] 呢,这是我一开始的疑惑点
想了又想,发现 每次[j, i] 的区间都是不相同的,如果当前[j, i]区间满足了题意,那么当前以i结尾的所有切分数就要加上[0,j-1]的所有切分数,然后我们的遍历到这里还没有结束,j还需要再向前遍历,在判断[j,i]区间,直至j = 1,所以每次都要加上dp[i] 是将所有可能切分数都给累加起来,这道题让我想起了lc的最长递增子序列的做题步骤😂,但是这题比较难对我来说
import java.util.*;
// 1:无需package
// 2: 类名必须Main, 不可修改
public class Main {
private static final int MOD = 1000 * 1000 * 1000 + 7;
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
//1. 初始化
int n = scan.nextInt();
int[] nums = new int[n];
for(int i = 0; i < n; i++) {
nums[i] = scan.nextInt();
}
//dp[i] : 以下标为i的自然数结尾的切分方法
int[] dp = new int[n + 1];
dp[0] = 1;
for(int i = 1; i <= n; i++) {
int max = nums[i - 1];
int min = nums[i - 1];
for(int j = i; j >= 1; j--) {
max = Math.max(max, nums[j - 1]);
min = Math.min(min, nums[j - 1]);
if(i - j == max - min) {
dp[i] = (dp[i] + dp[j - 1]) % MOD;
}
}
}
System.out.print(dp[n]);
scan.close();
}
}
倍数问题
目前攻克 60%,后面在做优化提升,先打个卡,太菜了😭