第十四届蓝桥杯三月真题刷题训练——第 7 天(3.10)

serein_2216 2023-03-10 20:38:48

三角回文数

三角回文数 => 即三角又回文

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%,后面在做优化提升,先打个卡,太菜了😭

...全文
10 回复 打赏 收藏 举报
写回复
回复
切换为时间正序
请发表友善的回复…
发表回复
发帖
高校算法学习社区

3.8w+

社区成员

和众多高校算法内卷分子,一起学习和交流算法那。浓郁的算法交流氛围,拒绝躺平,有效内卷。加入我们,私信我拉你入核心内卷群。
算法数据结构leetcode 个人社区
社区管理员
  • 执 梗
  • Dream-Y.ocean
  • ღCauchyོꦿ࿐
加入社区
帖子事件
创建了帖子
2023-03-10 20:38
社区公告

 刷题!