JAVA蓝桥杯真题笔记(2013年B组)


1. 标题: 世纪末的星期

同A组: JAVA蓝桥杯真题笔记(2013年A组)

2. 标题: 马虎的算式

小明是个急性子,上小学的时候经常把老师写在黑板上的题目抄错了。

有一次,老师出的题目是:36 x 495 = ?

他却给抄成了:396 x 45 = ?

但结果却很戏剧性,他的答案竟然是对的!!

因为 36 * 495 = 396 * 45 = 17820

类似这样的巧合情况可能还有很多,比如:27 * 594 = 297 * 54

假设 a b c d e 代表1~9不同的5个数字(注意是各不相同的数字,且不含0)

能满足形如: ab * cde = adb * ce 这样的算式一共有多少种呢?

请你利用计算机的优势寻找所有的可能,并回答不同算式的种类数。

满足乘法交换律的算式计为不同的种类,所以答案肯定是个偶数。

答案直接通过浏览器提交。

注意:只提交一个表示最终统计种类数的数字,不要提交解答过程或其它多余的内容。


满足乘法交换律的算式计为不同的种类,所以答案肯定是个偶数。
注意这句话的意思,27 * 594 = 297 * 54 和 54 * 297 = 594 * 27是两个不同的式子,可能会误导你在计算的结果上乘2,但是仔细考虑,此处不用乘2。
答案: 142

package B13;

public class Demo02 {
    
    

    public static void main(String[] args) {
    
    

        // ab * cde = adb * ce

        int count = 0;

        // 要保证a,b,c,d,e不重复
        for (int a = 1; a < 10; a++) {
    
    
            for (int b = 1; b < 10; b++) {
    
    
                if (a == b){
    
      // 保证a和b不相等
                    continue;
                }
                for (int c = 1; c < 10; c++) {
    
    
                    if (c==a || c==b){
    
      // 保证a,b,c不相等
                        continue;
                    }
                    for (int d = 1; d < 10; d++) {
    
    
                        if (d==a || d == b || d == c){
    
      // 保证a,b,c,d不相等
                            continue;
                        }
                        for (int e = 1; e < 10; e++) {
    
    
                            if (e == a || e == b || e == c || e == d){
    
      // 保证a,b,c,d, e不相等
                                continue;
                            }

                            if ((a*10+b)*(c*100+d*10+e) == (a*100+d*10+b)*(c*10+e)){
    
    
                                count++;
                            }
                        }
                    }
                }
            }
        }
        System.out.println(count);
    }
}

3. 标题: 振兴中华

同A组: JAVA蓝桥杯真题笔记(2013年A组) 第二题

4. 标题: 黄金连分数

黄金分割数0.61803… 是个无理数,这个常数十分重要,在许多工程问题中会出现。
有时需要把这个数字求得很精确。
对于某些精密工程,常数的精度很重要。
也许你听说过哈勃太空望远镜,它首次升空后就发现了一处人工加工错误,
对那样一个庞然大物,其实只是镜面加工时有比头发丝还细许多倍的一处错误而已,
却使它成了“近视眼”!!

言归正传,我们如何求得黄金分割数的尽可能精确的值呢?有许多方法。
比较简单的一种是用连分数:

                 1
    黄金数 = ---------------------
                        1
             1 + -----------------
                          1
                 1 + -------------
                            1
                     1 + ---------
                          1 + ...

这个连分数计算的“层数”越多,它的值越接近黄金分割数。
请你利用这一特性,求出黄金分割数的足够精确值,要求四舍五入到小数点后100位。

小数点后3位的值为:0.618
小数点后4位的值为:0.6180
小数点后5位的值为:0.61803
小数点后7位的值为:0.6180340
(注意尾部的0,不能忽略)

你的任务是:写出精确到小数点后100位精度的黄金分割值。

注意:尾数的四舍五入! 尾数是0也要保留!

显然答案是一个小数,其小数点后有100位数字,请通过浏览器直接提交该数字。
注意:不要提交解答过程,或其它辅助说明类的内容。


1. 化为求斐波那契相邻两项的比值,求多少项? 当 n/n+1再中的n再往上增时,这个比值小数点后101位是稳定的,此时可以取小数点后100项
2. double无法满足表示100位小数,用BigInteger和BigDecimal

在这里插入图片描述

在这里插入图片描述

package B13;

import java.math.BigDecimal;

public class Demo04 {
    
    

    public static void main(String[] args) {
    
    

        BigDecimal a = BigDecimal.ONE;
        BigDecimal b = BigDecimal.ONE;
        BigDecimal t;

        for (int i = 0; i < 400; i++) {
    
    
            t = b;
            b = a.add(b);
            a = t;
        }

//        System.out.println(a.divide(b, 101, BigDecimal.ROUND_HALF_UP));

        System.out.println(a.divide(b, 100, BigDecimal.ROUND_HALF_UP));

// 0.61803398874989484820458683436563811772030969980941182649362912941520163540937291916173851894971905630
// 0.61803398874989484820458683436563811772030917980576286213544862270526046281890244970803605876859146255
// 0.61803398874989484820458683436563811772030917980576286213544862270526046281890244970720720418939113748
// 0.61803398874989484820458683436563811772030917980576286213544862270526046281890244970720720418939113748
// 0.6180339887498948482045868343656381177203091798057628621354486227052604628189024497072072041893911375
    }
}

在这里插入图片描述
a.divide(b, 100, BigDecimal.ROUND_HALF_UP) 中的第二个参数代表小数点后精确到的尾数,第三个参数是指用四舍五入方式精确

5. 标题: 有理数类

问题描述

有理数就是可以表示为两个整数的比值的数字。一般情况下,我们用近似的小数表示。
但有些时候,不允许出现误差,必须用两个整数来表示一个有理数。

这时,我们可以建立一个“有理数类”,下面的代码初步实现了这个目标。为了简明,
它只提供了加法和乘法运算。

class Rational
{
    
    
    private long ra;
    private long rb;
    
    private long gcd(long a, long b){
    
    
        if(b==0) return a;
        return gcd(b,a%b);
    }
    public Rational(long a, long b){
    
    
        ra = a;
        rb = b;    
        long k = gcd(ra,rb);
        if(k>1){
    
     //需要约分
            ra /= k;  
            rb /= k;
        }
    }
    // 加法
    public Rational add(Rational x){
    
    
        return ________________________________________;  //填空位置
    }
    // 乘法
    public Rational mul(Rational x){
    
    
        return new Rational(ra*x.ra, rb*x.rb);
    }
    public String toString(){
    
    
        if(rb==1) return "" + ra;
        return ra + "/" + rb;
    }
}

使用该类的示例:
Rational a = new Rational(1,3);
Rational b = new Rational(1,6);
Rational c = a.add(b);
System.out.println(a + “+” + b + “=” + c);

请分析代码逻辑,并推测划线处的代码,通过网页提交。
注意:仅把缺少的代码作为答案,千万不要填写多余的代码、符号或说明文字!!

new Rational(ra * x.rb + x.ra * rb, rb * x.rb) // 填空位置

6. 标题: 三部排序

同A组: JAVA蓝桥杯真题笔记(2013年A组) 第5题

7. 标题: 错误票据

同A组: JAVA蓝桥杯真题笔记(2013年A组) 第7题

8. 标题: 幸运数

问题描述

幸运数是波兰数学家乌拉姆命名的。它采用与生成素数类似的“筛法”生成。

首先从1开始写出自然数1,2,3,4,5,6,…

1 就是第一个幸运数。
我们从2这个数开始。把所有序号能被2整除的项删除,变为:

1 _ 3 _ 5 _ 7 _ 9 …

把它们缩紧,重新记序,为:

1 3 5 7 9 … 。这时,3为第2个幸运数,然后把所有能被3整除的序号位置的数删去。注意,是序号位置,不是那个数本身能否被3整除!! 删除的应该是5,11, 17, …

此时7为第3个幸运数,然后再删去序号位置能被7整除的(19,39,…)

最后剩下的序列类似:
1, 3, 7, 9, 13, 15, 21, 25, 31, 33,
37, 43, 49, 51, 63, 67, 69, 73, 75, 79, …

本题要求:
输入两个正整数m n, 用空格分开 (m < n < 1000*1000)
程序输出 位于m和n之间的幸运数的个数(不包含m和n)。

例如:
用户输入:
1 20
程序输出:
5

例如:
用户输入:
30 69
程序输出:
8

资源约定:
峰值内存消耗(含虚拟机) < 64M
CPU消耗 < 2000ms

请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。

所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意:不要使用package语句。不要使用jdk1.6及以上版本的特性。
注意:主类的名字必须是:Main,否则按无效代码处理。


暴搜 + 优化
可以将偶数去除掉,默认从3为幸运数开始搜索
初始化数组时将0位置占位,不进行初始化,保证 下标=位置,遍历数组,从幸运数的后面位置开始,删除幸运数倍数位置的数(将后面的数挪前来覆盖要删除位置的数),当搜索时碰到第一个大于等于n的数时,可提前终止循环,重复删除过程,当幸运数大于等于n时,可结束程序,然后统计区间的幸运数。(注意每次最新的幸运数的位置发送变化 L++)
难点在于覆盖坑位和优化

package B13;

import java.util.Scanner;

/*
首先从1开始写出自然数1,2,3,4,5,6,....

1 就是第一个幸运数。
我们从2这个数开始。把所有序号能被2整除的项删除,变为:

1 _ 3 _ 5 _ 7 _ 9 ....

把它们缩紧,重新记序,为:

1 3 5 7 9 .... 。这时,3为第2个幸运数,然后把所有能被3整除的序号位置的数删去。注意,是序号位置,不是那个数本身能否被3整除!! 删除的应该是5,11, 17, ...

此时7为第3个幸运数,然后再删去序号位置能被7整除的(19,39,...)

最后剩下的序列类似:
1, 3, 7, 9, 13, 15, 21, 25, 31, 33,
37, 43, 49, 51, 63, 67, 69, 73, 75, 79, ...
 */
public class Demo08 {
    
    

    public static void main(String[] args) {
    
    

        Scanner scan = new Scanner(System.in);

        int m = scan.nextInt();
        int n = scan.nextInt();

        int[] a = new int[n+1];  // 0位置空出来

        for (int i = 1; i <= n; i++) {
    
      // 默认去除偶数项
            a[i] = i * 2 - 1;
        }

        int l = 2;  // 记录每一轮的幸运数的下标

        while (true){
    
    
            int p = l + 1;  // p用来记录真实的位置

            for (int i = l + 1; i <= n; i++) {
    
    
                if (a[i] >= n) break;

                if (i % a[l] == 0){
    
    }
                else {
    
    
                    a[p] = a[i];
                    p++;
                }
            }

            l++;  // 改变幸运数的位置
            if(a[l]*2 >= n) break;  // 如果在n范围内已经没有幸运数的倍数,则跳出循环

//            for (int i = 1; i <= n; i++) {
    
    
//                System.out.print(a[i] + " ");
//            }
//            System.out.println();
        }

        int ans = 0;

        for (int i = 1; i <= n; i++) {
    
    
            if (a[i] - a[i-1] <= 0) break;
            if (a[i] > m) ans++;

        }
        System.out.println(ans);
    }
}

在这里插入图片描述

9. 标题: 带分数

同A组: JAVA蓝桥杯真题笔记(2013年A组) 第8题

10. 标题: 连号区间数

问题描述

小明这些天一直在思考这样一个奇怪而有趣的问题:

在1~N的某个全排列中有多少个连号区间呢?这里所说的连号区间的定义是:

如果区间[L, R] 里的所有元素(即此排列的第L个到第R个元素)递增排序后能得到一个长度为R-L+1的“连续”数列,则称这个区间连号区间。

当N很小的时候,小明可以很快地算出答案,但是当N变大的时候,问题就不是那么简单了,现在小明需要你的帮助。

输入格式:
第一行是一个正整数N (1 <= N <= 50000), 表示全排列的规模。
第二行是N个不同的数字Pi(1 <= Pi <= N), 表示这N个数字的某一全排列。

输出格式:
输出一个整数,表示不同连号区间的数目。

示例:
用户输入:
4
3 2 4 1

程序应输出:
7

用户输入:
5
3 4 2 5 1

程序应输出:
9

解释:
第一个用例中,有7个连号区间分别是:[1,1], [1,2], [1,3], [1,4], [2,2], [3,3], [4,4]
第二个用例中,有9个连号区间分别是:[1,1], [1,2], [1,3], [1,4], [1,5], [2,2], [3,3], [4,4], [5,5]

资源约定:
峰值内存消耗(含虚拟机) < 64M
CPU消耗 < 5000ms

请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。

所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意:不要使用package语句。不要使用jdk1.6及以上版本的特性。
注意:主类的名字必须是:Main,否则按无效代码处理。


一个区间内 max - min = right - left 时, 此区间连续,如: [7,10,9, 8] 中 max = 10,min = 7,right = 4,left = 1,此时10 - 7 = 4 - 1,所以连续

package B13;

import java.util.Scanner;

public class Demo10 {
    
    

    public static void main(String[] args) {
    
    

        Scanner scan = new Scanner(System.in);

        int n = scan.nextInt();

        int[] a = new int[n + 1];  // 0位置空出来

        for (int i = 1; i < n + 1; i++) {
    
    
            a[i] = scan.nextInt();
        }

        int ans = 0;
        int max;
        int min;
        for (int i = 1; i <= n; i++) {
    
    
            max = a[i];
            min = a[i];

            for (int j = i; j <= n; j++) {
    
    

                if (i==j) {
    
      // [1, 1], [2, 2], [3, 3], [4, 4]......
                    ans++;
                    continue;
                }

                if (a[j] > max) max = a[j];  // 当前区间内的最大值
                if (a[j] < min) min = a[j];  // 当前区间内的最小值

                if (max - min == j - i) ans++;
            }
        }

        System.out.println(ans);
    }
}

在这里插入图片描述

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_46456049/article/details/114869429