蓝桥杯省赛7日集训-简单数论(1)

蓝桥杯省赛7日集训-简单数论 - 蓝桥云课

目录

第一题:质因数分解 

题目描述

输入描述

输出描述

输入输出样例

运行限制

题目 分析

一个质因数分解的模板——与第六题相识

 题目代码

第二题:质数

题目描述

输入描述

输出描述

输入输出样例

运行限制

题目分析

题目代码

 第三题:小数第n位

题目描述

输入描述

输出描述

输入输出样例

运行限制

题目分析

难点:如何获得小数部分

 题目代码

第四题:棋盘放麦子

题目描述

运行限制

题目分析

题目代码

第五题: 等差数列

题目描述

输入描述

输出描述

输入输出样例

运行限制

题目分析

题目代码

第六题:数数

问题描述

答案提交

运行限制

题目分析

题目代码

第七题:约数个数

题目描述

运行限制

题目分析

 题目代码

第八题: 质数拆分

题目描述

运行限制

 题目分析

题目代码


第一题:质因数分解 

题目描述

已知正整数 n 是两个不同的质数的乘积,试求出较大的那个质数。

输入描述

输入只有一行,包含一个正整数 6≤n≤2×10^9。

输出描述

输出只有一行,包含一个正整数 p,即较大的那个质数。

输入输出样例

示例

输入

21

输出

7

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 128M

题目 分析

/**
* 分解质因数只针对合数
* 先用一个合数的最小质因数去除这个合数,得出的数若是一个质数,就写成这个合数相乘形式;
* 若是一个合数就继续按原来的方法,直至最后是一个质数 。
*/

因为质因数可能重复,所以应用while,重复判断质因数

一个质因数分解的模板——与第六题相识

 static int judge(int n) {
        int count = 0;
        for (int i = 2; i <= Math.sqrt(n); i++) {
            while (n % i == 0) {
                count++;//质因数+1
                n = n / i;
            }
        }
        if (n > 1) count++;
        return count;
    }

不要忘记最后n>1的情况

if (n > 1) count++;

 题目代码

import java.util.HashSet;
import java.util.Scanner;

/**
 * 分解质因数只针对合数
 * 先用一个合数的最小质因数去除这个合数,得出的数若是一个质数,就写成这个合数相乘形式;
 * 若是一个合数就继续按原来的方法,直至最后是一个质数 。
 */
public class 质因数分解 {
    public static void main(String[] args) {
        Scanner sca = new Scanner(System.in);
        long n = sca.nextInt();
        HashSet set = new HashSet<>();
        //已知正整数n 是两个不同的质数的乘积,试求出较大的那个质数。
        //只需要到sqrt(n)即可,因为如果有一个因数大于等于sqrt(n),那么必定有一个因数小于等于sqrt(n)
        for (long i = 2l; i <= Math.sqrt(n); i++)       //分解质因数:从最小的质因数遍历,
        {
            while (n % i == 0)       //因为质因数可能重复,所以应用while,重复判断质因数 9==3*3
            {
                set.add(i);
                n = n / i;           //n改变
            }
        }
        //特别注意最后n%i!=0的时候如果n>1,n也是一个质因数要加上
        //比如 21 = 3 * 7  (21/3==7、7%3!=0)
        if (n > 1) set.add(n);
        
        long max = 0;
        for (Long i : set) {
            if (i > max) max = i;
        }
        System.out.println(max);
    }
}

第二题:质数

题目描述

给定一个正整数 N,请你输出 N 以内(不包含 N)的质数以及质数的个数。

输入描述

输入一行,包含一个正整数 N。1≤N≤10^3

输出描述

共两行。

第 11 行包含若干个素数,每两个素数之间用一个空格隔开,素数从小到大输出。

第 22 行包含一个整数,表示N以内质数的个数。

输入输出样例

示例

输入

10

输出

2 3 5 7
4

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 128M

题目分析

就一个判断质数 

1)直观判断法改进
对于每个数n,其实并不需要从2判断到n-1,我们知道,一个数若可以进行因数分解,那么分解时得到的两个数一定是一个小于等于sqrt(n),一个大于等于sqrt(n),据此,上述代码中并不需要遍历到n-1,遍历到sqrt(n)即可,因为若sqrt(n)左侧找不到约数,那么右侧也一定找不到约数。


原文链接:https://blog.csdn.net/huang_miao_xin/article/details/51331710

题目代码

import java.util.Scanner;

public class 质数 {
    public static void main(String[] args) {
        Scanner sca = new Scanner(System.in);
        int n = sca.nextInt();
        int count =0;
        for (int i = 2; i < n; i++) {
            if (judge(i)) {
                count++;
                System.out.print(i+" ");
            }
        }
        System.out.println();
        System.out.println(count);
    }

    static Boolean judge(int n) {
        if (n<=0){
            return false;
        }
        for (int i = 2; i <=Math.sqrt(n); i++) {
            if (n % i == 0) {
                return false;
            }
        }
        return true;
    }
}

 第三题:小数第n位

题目描述

我们知道,整数做除法时,有时得到有限小数,有时得到无限循环小数。

如果我们把有限小数的末尾加上无限多个 0,它们就有了统一的形式。

本题的任务是:在上面的约定下,求整数除法小数点后的第 n 位开始的 3 位数。

输入描述

输入一行三个整数:a b n,用空格分开。a 是被除数,b 是除数,n 是所求的小数后位置(0

输出描述

输出一行 3 位数字,表示:a 除以 b,小数后第 n 位开始的 3 位数字。

输入输出样例

示例

输入

1 8 1

输出

125

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 256M

题目分析

难点:如何获得小数部分

第 n 位的后三位,也就是第 n ------ n + 2 位,把第 n + 2 位(含)之前的部分变成整数,再%1000就是我们要的三位数答案,最小的位是第 n + 2 位,想把它变成整数的个位,需要 乘 10n+2 ,也就是 a / b * 10^(n+2) % 1000 即为答案,因为 n 的范围可能很大,所以就需要用快速幂取模算法

想了解快速幂取模算法看下面链接

蓝桥杯--历届试题 小数第n位(java)_x/d%m=x%(d脳m)/d_码畜也有梦想的博客-CSDN博客

 题目代码

import java.util.Scanner;

public class 小数第n位 {
    public static void main(String[] args) {
        Scanner sca = new Scanner(System.in);
        double a = sca.nextDouble();
        double b = sca.nextDouble();
        int n = sca.nextInt();
        int temp = (int)Math.floor((a/b)*Math.pow(10,n+2));
        int res = temp%1000;
        System.out.println(res);
    }
}

不是满分代码

第四题:棋盘放麦子

题目描述

本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。

你一定听说过这个故事。国王对发明国际象棋的大臣很佩服,问他要什么报酬,大臣说:请在第 1 个棋盘格放 1 粒麦子,在第 2 个棋盘格放 2 粒麦子,在第 3 个棋盘格放 4 粒麦子,在第 4 个棋盘格放 8 粒麦子,......后一格的数字是前一格的两倍,直到放完所有棋盘格(国际象棋共有 64 格)。

国王以为他只是想要一袋麦子而已,哈哈大笑。

当时的条件下无法准确计算,但估算结果令人吃惊:即使全世界都铺满麦子也不够用!

请你借助计算机准确地计算,到底需要多少粒麦子。

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 128M

题目分析

  1. java中最大范围是64位 long 型整数 题目中还是不够

  2. java.math.BigInteger 可以用来表示任意大小的整数

常用的两种定义方式
BigInteger a=new BigInteger("123");        //没有参数为long的构造函数,用字符串来构造
BigInteger b=BigInteger.valueOf(123);    //静态方法,返回val对应的BigInteger
BigInteger类中定义了四则运算的方法,add,subtract,multiply,divide。对 BigInteger 做运算的时候,只能使用实例方法
如:
a=a.add(b);

题目代码

import java.math.BigInteger;
public class 棋盘放麦子 {

    public static void main(String[] args) {
        BigInteger sum = BigInteger.valueOf(1);
        BigInteger add = BigInteger.valueOf(1);
        BigInteger mul = BigInteger.valueOf(2);
        for (int i = 0; i < 63; i++) {
            add = add.multiply(mul);//*2
            sum = sum.add(add);//+
        }
        System.out.print(sum);
    }
}

第五题: 等差数列

题目描述

数学老师给小明出了一道等差数列求和的题目。但是粗心的小明忘记了一 部分的数列,只记得其中 N 个整数。

现在给出这 N 个整数,小明想知道包含这 N 个整数的最短的等差数列有几项?

输入描述

输入的第一行包含一个整数 N。

第二行包含 N 个整数 A1​,A2​,⋅⋅⋅,AN​。(注意 A1​ ∼ AN​ 并不一定是按等差数列中的顺序给出)

其中,2≤N≤10^5,0≤Ai​≤10e9。

输出描述

输出一个整数表示答案。

输入输出样例

示例

输入

5
2 6 4 10 20

输出

10

样例说明: 包含 2、6、4、10、20 的最短的等差数列是 2、4、6、8、10、12、14、16、 18、20。

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 256M

题目分析

注意一下公差为0的时候 

题目代码

import java.util.Arrays;
import java.util.Scanner;

public class 等差数列 {
    public static void main(String[] args) {
        Scanner sca = new Scanner(System.in);
        int n = sca.nextInt();
        int[] arr = new int[n];
        for (int i = 0; i < n; i++) {
            arr[i] = sca.nextInt();
        }
        Arrays.sort(arr);
        int min = Integer.MAX_VALUE;
        for (int i = 1; i < n; i++) {//找最小公差
            if (arr[i] - arr[i - 1] < min) {
                min = arr[i] - arr[i - 1];
            }
        }
        int a = arr[0];
        int count =0 ;
        if (min==0){//公差为0
            System.out.println(arr.length);
            return;
        }
        while (true) {
            if (a > arr[arr.length - 1]) {
                break;
            }
            count++;
            a = a + min;
        }
        System.out.println(count);
    }
}

第六题:数数

问题描述

任何一个大于 1 的正整数都能被分解为若干个质数相乘, 比如 28=2×2×7 被分解为了三个质数相乘。请问在区间 [2333333, 23333333] 中有多少个正整数 可以被分解为 12 个质数相乘?

答案提交

这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一 个整数, 在提交答案时只填写这个整数, 填写多余的内容将无法得分。

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 512M

题目分析

直接套 质因数分解模板 

 static int judge(int n) {
        int count = 0;
        for (int i = 2; i <= Math.sqrt(n); i++) {
            while (n % i == 0) {
                count++;//质因数+1
                n = n / i;
            }
        }
        if (n > 1) count++;
        return count;
    }

题目代码

public class 数数 {
    public static void main(String[] args) {
        int res = 0;
        for (int i = 2333333; i <= 23333333; i++) {
            if (judge(i) == 12) {
                res++;
            }
        }
        System.out.println(res);
    }

    static int judge(int n) {
        int count = 0;
        for (int i = 2; i <= Math.sqrt(n); i++) {
            while (n % i == 0) {
                count++;//质因数+1
                n = n / i;
            }
        }
        if (n > 1) count++;
        return count;
    }
}

第七题:约数个数

题目描述

本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。

1200000 有多少个约数(只计算正约数)。

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 128M

题目分析

只需注意1也为n的因数即可(1不是质数)

 题目代码

public class 约数个数 {
    public static void main(String[] args) {
        int n = 1200000;
        int count =0;
        for (int i = 1; i <= Math.sqrt(1200000); i++) {
            if (n%i==0){
                count = count+2;
            }
        }
        if (Math.sqrt(n)*Math.sqrt(n)==n){
            count--;
        }
        System.out.println(count);
    }
}

第八题: 质数拆分

题目描述

本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。

将 20192019 拆分为若干个两两不同的质数之和,一共有多少种不同的方法?

注意交换顺序视为同一种方法,例如 2+2017=2019 与 2017+2=2019 视为同一种方法。

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 128M

 题目分析

01背包问题

蓝桥杯学习——01 背包_蓝桥杯01背包_小卢先冲的博客-CSDN博客

题目代码

// 1:无需package
// 2: 类名必须Main, 不可修改

public class Main {

    static int n = 2500;
    static int[] arr = new int[n];//存放质数
    static long dp[][] = new long[n][n];//记录方案数

    public static void main(String[] args) {
        int cur = 1; //307 2-2019有307个质数
        for (int i = 2; i < 2019; i++) {
            if (ispre(i)) {
                arr[cur++] = i;
            }
        }
        //开始01背包
        dp[0][0] = 1;//容量为0也是一种方案
        for (int i = 1; i < cur; i++) { //[物品]质数个数
            for (int j = 0; j <= 2019; j++) { //[背包容量]最小为0,所以从0开始
                dp[i][j] = dp[i - 1][j];  //不选i的情况,填充上一个
                if (arr[i] <= j) { //是否超过当前背包总容量
                    /**
                     *  按01背包的术语来讲 arr[i]就是存进j背包花费的空间!! 这边价值总和就是2019
                     *  这个状态转移方程 与当前行无关,与上一行有关
                     *  f[ i] [j]=max(f [i−1] [j],f[i−1] [j−c[i]]+w[i])
                     *  这里直接 f[i][j] = f[i-1][j-c[i]]了
                     */
                    dp[i][j] += dp[i - 1][j - arr[i]]; //如果当前能容下i 选第i个数
                    //dp[1][2] += dp[0][0](1) = 2;  dp[1][3] += dp[0][1];
                    //dp[2][5] += dp[1][2](2) = 3
                }
            }
        }
        System.out.println(dp[cur - 1][2019]);
    }

    public static boolean ispre(int n) {
        for (int i = 2; i <= Math.sqrt(n); i++) {
            if (n % i == 0) {
                return false;
            }
        }
        return true;
    }

}

你可能感兴趣的:(蓝桥杯,蓝桥杯,职场和发展,学习,java,数据结构)