2013年第四届蓝桥杯Java B组初赛真题个人题解

A-世纪末的星期

世纪末的星期-蓝桥杯题目链接

题目描述

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

曾有邪教称 1999 年 12 月 31 日是世界末日。当然该谣言已经不攻自破。
还有人称今后的某个世纪末的 12 月 31 日,如果是星期一则会....
有趣的是,任何一个世纪末的年份的 12 月 31 日都不可能是星期一!
于是,“谣言制造商”又修改为星期日......
1999 年的 12 月 31 日是星期五,请问:未来哪一个离我们最近的一个世纪末年(即 xx99 年)的 12 月 31 日正好是星期天(即星期日)?
请回答该年份(只写这个 4 位整数,不要写 12 月 31 等多余信息)

答案:

2299

 代码:

package _2013._真题;

import java.time.LocalDate;

public class _001世纪末的星期 {
    public static void main(String args[]){
        boolean flag=true;
        LocalDate date=LocalDate.now();
        date=date.withYear(1999);
        date=date.withMonth(12);
        date=date.withDayOfMonth(31);
        while (flag){
            date=date.plusYears(100);
            if(date.getDayOfWeek().toString().equals("SUNDAY")){
                System.out.println(date.getYear());
                flag=false;
            }
        }
    }
}

B-马虎的算式

马虎的算式-蓝桥杯题目链接

题目描述

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

小明是个急性子,上小学的时候经常把老师写在黑板上的题目抄错了。
有一次,老师出的题目是: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 这样的算式一共有多少种呢?
请你利用计算机的优势寻找所有的可能,并回答不同算式的种类数。
满足乘法交换律的算式计为不同的种类,所以答案肯定是个偶数。

答案:

142

 分析

       我这里用了全排列枚举了每种情况,然后判断每种情况是否符合条件,符合条件res++,用了全排列的模板

 代码

package _2013._真题;

public class _002马虎的算式 {
    static int[] a ={1,2,3,4,5,6,7,8,9};
    static int res=0;
    public static boolean check(){
        int x1=a[0]*10+a[1];
        int x2=a[2]*100+a[3]*10+a[4];
        int x3=a[0]*100+a[3]*10+a[1];
        int x4=a[2]*10+a[4];
        if(x1*x2==x3*x4)
            return true;
        return false;
    }
    public static void dfs(int n){
        if(n==5){
            if(check()){
                res++;
            }
        }
        for(int i=n;i<9;i++){
            int temp=a[n];
            a[n]=a[i];
            a[i]=temp;
            dfs(n+1);
            int temp1=a[n];
            a[n]=a[i];
            a[i]=temp1;
        }
    }
    public static void main(String args[]){
        dfs(0);
        System.out.println(res);
    }
}

C-振兴中华

振兴中华-蓝桥杯题目链接

小明参加了学校的趣味运动会,其中的一个项目是:跳格子。
地上画着一些格子,每个格子里写一个字,如下所示:

比赛时,先站在左上角的写着“从”字的格子里,可以横向或纵向跳到相邻的格子里,但不能跳到对角的格子或其它位置。一直要跳到“华”字结束。
要求跳过的路线刚好构成“从我做起振兴中华”这句话。
请你帮助小明算一算他一共有多少种可能的跳跃路线呢?

答案:

35

 分析:

        本题规模较小,我直接用了dfs从左上角至右下角,只能向下和向右移动,移动到右下角时进行判断,本题我将"从我做起振兴中华"用abcdefgh代替,因此输入运行代码输入下列语句即可得到答案。

abcde
bcdef
cdefg
defgh

代码:

package _2013._真题;
import java.util.Scanner;
//用例
//abcde
//bcdef
//cdefg
//defgh
public class _003振兴中华 {
    static int res=0;
    static char c[][]=new char[4][5];
    static int dx[]={1,0};
    static int dy[]={0,1};
    public static void dfs(int x,int y,String s){
        if(x<0||x>3||y<0||y>4)
            return;
        if(x==3&&y==4){
            if(s.equals("abcdefgh")){
                res++;
            }
        }
        for(int i=0;i<2;i++){
            int x1=x+dx[i];
            int y1=y+dy[i];
            if(x1>=0&&x1<=3&&y1>=0&&y1<=4)
                dfs(x1,y1,s+c[x1][y1]);
        }
    }
    public static void main(String args[]){
        Scanner sc=new Scanner(System.in);
        for(int i=0;i<4;i++){
            c[i]=sc.next().toCharArray();
        }
        dfs(0,0,c[0][0]+"");
        System.out.println(res);
    }
}

D-黄金连分数

黄金连分数-蓝桥杯题目链接

题目描述

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

黄金分割数 0.61803.... 是个无理数,这个常数十分重要,在许多工程问题中会出现。有时需要把这个数字求得很精确。
对于某些精密工程,常数的精度很重要。也许你听说过哈勃太空望远镜,它首次升空后就发现了一处人工加工错误,对那样一个庞然大物,其实只是镜面加工时有比头发丝还细许多倍的一处错误而已,却使它成了“近视眼”!
言归正传,我们如何求得黄金分割数的尽可能精确的值呢?有许多方法。
比较简单的一种是用连分数:

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

这个连分数计算的“层数”越多,它的值越接近黄金分割数。
请你利用这一特性,求出黄金分割数的足够精确值,要求四舍五入到小数点后 100100 位。
小数点后3位的值为:0.618;
小数点后4位的值为:0.6180;
小数点后5位的值为:0.61803;
小数点后7位的值为:0.6180340; (注意尾部的 0,不能忽略)
你的任务是:写出精确到小数点后 100 位精度的黄金分割值。
注意:尾数的四舍五入! 尾数是 0 也要保留!

答案:

0.6180339887498948482045868343656381177203091798057628621354486227052604628189024497072072041893911375

分析:

        本题关键是要发现规律,当只有一层的时候为1,两层的时候为1/2,三层的时候为2/3,四层为3/5,五层为5/8.......由此可以发现规律,后一项的分子为前一项的分母,分母为前一项的分子+分母,此外,由于要计算小数点后100位,要用到Java中的BigDecimal类,然后不断增加层数使结果更加稳定至小数点后100位稳定,不断调整n的大小发现到300层后,最终结果小数点后100位即保持不变

代码:

package _2013._真题;
//找规律
//1,2/3,3/5,5/8,8/13·······
//保证精度问题用BigDecimal、确保小数点后100位不变
import java.math.BigDecimal;

public class _004黄金连分数 {
    public static void main(String args[]){
        BigDecimal b1=BigDecimal.valueOf(1);
        BigDecimal b2=BigDecimal.valueOf(2);
        int n=400;
        //不断调试大小使之小数点后100位稳定
        for(int i=0;i<=n;i++){
            BigDecimal temp=b1.add(b2);
            b1=b2;
            b2=temp;
        }
        BigDecimal res=b1.divide(b2,100,BigDecimal.ROUND_HALF_UP);
        System.out.println(res);
    }
}

E,F两题为代码填空题,已经不考了,我也没做

G-错误票据

错误票据-蓝桥杯题目链接

题目描述

某涉密单位下发了某种票据,并要在年终全部收回
每张票据有唯一的 ID 号。全年所有票据的 ID 号是连续的,但 ID 的开始数码是随机选定的
因为工作人员疏忽,在录入 ID 号的时候发生了一处错误,造成了某个 ID 断号,另外一个 ID 重号
你的任务是通过编程,找出断号的 ID 和重号的 ID 
假设断号不可能发生在最大和最小号

输入描述

要求程序首先输入一个整数 N\(N<100)表示后面数据行数。
接着读入 N 行数据。
每行数据长度不等,是用空格分开的若干个(不大于 100 个)正整数(不大于10^5

输出描述

要求程序输出 1 行,含两个整数 m,n 用空格分隔。
其中,m 表示断号 ID,n 表示重号 ID

分析

       这题就简单的处理一下输入,将数据全部存入一个list中,进行排序,排序后统计每个元素出现的次数,若为0则表示断号,为2则表示重号.需要注意的是断号和重号的位置是相对于list中第一个元素(最小元素)来说,因此最终结果需要加上list第一个元素。

代码

package _2013._真题;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;

public class _007错误票据 {
    public static void main(String args[]){
        Scanner sc=new Scanner(System.in);
        List<Integer>list=new ArrayList<>();
        int n=Integer.valueOf(sc.nextLine());
        for(int i=0;i<n;i++){
            String s=sc.nextLine();
            String a[]=s.split(" ");
            for(String x:a){
                list.add(Integer.valueOf(x));
            }
        }
        //排序
        Collections.sort(list);
        //统计每个元素出现的次数
        int b[]=new int[list.size()];
        //最小元素
        int m=list.get(0);
        for(int i=0;i<list.size();i++){
            b[list.get(i)-m]++;
        }
        int res1=0;
        int res2=0;
        for(int i=0;i<b.length;i++){
            if(b[i]==0){
                res1=m+i;
            }
            if(b[i]==2){
                res2=m+i;
            }
        }
        System.out.println(res1+" "+res2);
    }
}

H-幸运数

幸运数-蓝桥杯题目链接

题目描述

幸运数是波兰数学家乌拉姆命名的。它采用与生成素数类似的"筛法"生成。
首先从 1 开始写出自然数 1,2,3,4,5,6, \cdots
1 就是第一个幸运数。
我们从 2 这个数开始。把所有序号能被 2 整除的项删除,变为:
1 \ 3 \ 5 \ 7 \ 9 \cdots
把它们缩紧,重新记序,为:
1 \ 3 \ 5 \ 7 \ 9 \cdots
这时,3 为第 2个幸运数,然后把所有能被 3 整除的序号位置的数删去。注意,是序号位置,不是那个数本身能否被 3 整除!!删除的应该是 5,11, 17, \cdots
此时 7 为第 3 个幸运数,然后再删去序号位置能被 7 整除的( 19,39,\cdots)
最后剩下的序列类似:
1, 3, 7, 9, 13, 15, 21, 25, 31, 33, 37, 43, 49, 51, 63, 67, 69, 73, 75, 79, \cdots

输入描述

输入两个正整数 m,n, 用空格分开 (m < n < 10^6)

输出描述

输出位于 m 和 n 之间的幸运数的个数(不包含 m 和 n )

输入输出样例

输入

1 20

输出

5

分析

          本题用了两个list列表不断消除非幸运数字,大家看下注释能够明白

代码

package _2013._真题;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class _008幸运数 {
    public static void main(String args[]){
        Scanner sc=new Scanner(System.in);
        int m=sc.nextInt();
        int n=sc.nextInt();
        List<Integer>list1=new ArrayList<>();
        List<Integer>list2=new ArrayList<>();
        list1.add(0);
        for(int i=1;i<=n;i++){
            if(i%2!=0){
                list1.add(i);
            }
        }
        int k=2;
        int lucky=0;
        while (lucky<list1.size()){
            //获取新的lucky值
            lucky=list1.get(k);
            k++;
            list2.add(0);
            //消除非幸运数字
            for(int i=1;i<list1.size();i++){
                if(i%lucky!=0){
                    list2.add(list1.get(i));
                }
            }
            list1.clear();
            //将list2复制到list1,进行下一次循环
            for(int i=0;i< list2.size();i++){
                list1.add(list2.get(i));
            }
            list2.clear();
        }
        int res=0;
        for(int i=0;i< list1.size();i++){
            if(list1.get(i)>m&&list1.get(i)<n){
                res++;
            }
        }
        System.out.println(res);
    }
}

I-带分数

带分数-蓝桥杯题目链接

题目描述

100 可以表示为带分数的形式:100 = 3 + 69258 / 714
还可以表示为:100 = 82 + 3546 / 197
注意特征:带分数中,数字 1~9 分别出现且只出现一次(不包含 0 )
类似这样的带分数,100 有 11 种表示法

输入描述

从标准输入读入一个正整数 N\ (N<1000 \times 1000)

输出描述

程序输出该数字用数码 1~9 不重复不遗漏地组成带分数表示的全部种数。
注意:不要求输出每个表示,只统计有多少表示法!

输入输出样例

输入

100

输出

11

分析

        这里我还是用了dfs进行全排序,做法和第二题马虎的算式类似,此题需要额外判断+的位置和/的位置,定义了一个getnum()方法,判断是否其和是否为n,可详见注释部分

代码

package _2013._真题;

import java.util.Scanner;

public class _009带分数 {
    static int a[]={1,2,3,4,5,6,7,8,9};
    static int res=0;
    static int n;
    //求得从下标为x开始,长度为y的数值
    public static int getnum(int x,int y){
        int t=1;
        int res=0;
        for(int i=x+y-1;i>=x;i--){
            res+=a[i]*t;
            t*=10;
        }
        return res;
    }
    public static boolean check(){
        //放+号位置
        for(int i=1;i<=7;i++){
            int n1=getnum(0,i);
            //放/号位置
            for(int j=1;j<=8-i;j++){
                int n2=getnum(i,j);
                int n3=getnum(i+j,9-i-j);
                if(n2%n3==0&&n1+(n2/n3)==n)
                    return true;
            }
        }
        return false;
    }
    //全排列
    public static void dfs(int n){
        if(n==9){
            if(check()){
                res++;
            }
        }
        for(int i=n;i<9;i++){
            int t=a[n];
            a[n]=a[i];
            a[i]=t;
            dfs(n+1);
            int t1=a[n];
            a[n]=a[i];
            a[i]=t1;
        }
    }
    public static void main(String args[]){
        Scanner sc=new Scanner(System.in);
        n=sc.nextInt();
        dfs(0);
        System.out.println(res);
    }
}

G-连号区间数

连号区间数-蓝桥杯题目链接

题目描述

小明这些天一直在思考这样一个奇怪而有趣的问题:
在 1 ~ N 的某个全排列中有多少个连号区间呢?
这里所说的连号区间的定义是:
如果区间 [L, R] 里的所有元素(即此排列的第 L 个到第 R 个元素)递增排序后能得到一个长度为 R-L+1 的"连续"数列,则称这个区间连号区间。
当 N 很小的时候,小明可以很快地算出答案,但是当 N 变大的时候,问题就不是那么简单了,现在小明需要你的帮助。

输入描述

第一行是一个正整数 N (1 \leq N \leq 50 \times 10^4), 表示全排列的规模。
第二行是 N 个不同的数字P_i\ (1 \leq P_i \leq N),表示这 N 个数字的某一全排列。

输出描述

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

输入输出样例

输入

4
3 2 4 1

输出

7

分析

        本题关键是理解连号区间数的含义,要想判断该区间是否为连号区间数,只需要判断该区间中的最大值和最小值的差是否等于该区间长度即可.

代码

package _2013._真题;

import java.util.Scanner;

public class _010连号区间数 {
    public static void main(String args[]){
        Scanner sc=new Scanner(System.in);
        int n=sc.nextInt();
        int a[]=new int[n+1];
        for(int i=1;i<=n;i++){
            a[i]=sc.nextInt();
        }
        int res=0;
        for(int i=1;i<=n;i++){
            int min=a[i];
            int max=a[i];
            for(int j=i;j<=n;j++){
                if(a[j]>max) max=a[j];
                if(a[j]<min) min=a[j];
                if(max-min==j-i){
//                    System.out.printf("[%d,%d]\n",i,j);
                    res++;
                }
            }
        }
        System.out.println(res);
    }
}

大家有问题可以评论,作者看到后会第一时间进行回复!

陆续还会更新历届的蓝桥杯真题,大家可以点点关注~

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值