第七届蓝桥杯(2016年)JavaA组省赛真题解析

Posted nuist__NJUPT

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第七届蓝桥杯(2016年)JavaA组省赛真题解析相关的知识,希望对你有一定的参考价值。

第七届蓝桥杯(2016年)JavaA组省赛真题解析

  • 1.煤球数量
  • 有一堆煤球,堆成三角堆形,具体如下:
  • 第一层放1个
  • 第二层放3个
  • 第三层放6个
  • 第四层放10个
  • 如果一共有100层,一共多少个煤球?
/**
 * 1.煤球数量
 * 有一堆煤球,堆成三角堆形,具体如下:
 * 第一层放1个
 * 第二层放3个
 * 第三层放6个
 * 第四层放10个
 * ...
 * 如果一共有100层,一共多少个煤球?
 */
public class Main 
    /**
     * 注意:求得是总的煤球数目,不是第100层的煤球数目
     * 总的煤球数量等于每一层的煤球数量之和
     * 每一层的煤球数量=上一层的煤球数量+当前的层数
     */
    static int sum = 0, count = 0;
    public static void main(String[] args) 
        for(int level=1; level<=100; level++) //level代表层
            count = (count + level) ;//每层的煤球数量
            sum += count ; //总的煤球数量
        
        System.out.println(sum);
    


2.生日蜡烛

  • 某君从某年开始,每年都会举办一次生日party,并且每年都要吹熄与年龄相同根树的蜡烛
  • 到2016年,他一共吹熄了236根蜡烛,请问他从多少岁开始过生日party的,
  • 请给出他开始过生日的年龄数。
/**
 * 2.生日蜡烛
 * 某君从某年开始,每年都会举办一次生日party,并且每年都要吹熄与年龄相同根树的蜡烛
 * 到2016年,他一共吹熄了236根蜡烛,请问他从多少岁开始过生日party的,
 * 请给出他开始过生日的年龄数。
 */
public class Main 
    static int sum = 0;
    public static void main(String[] args) 
        for (int j = 1; j <= 100; j++)  //假设从1岁-100岁开始过生日
            for (int i = j; sum < 250; i++) 
                sum += i;
                if(sum == 236) //找到吹灭蜡烛数量为236的
                    System.out.println(j); //输出过生日的年龄
                    break ;
                
            
            sum = 0 ;
        
    


3.搭积木

  • 小明最近喜欢搭数字积木
  • 一共有10块积木,每个积木上有一个数字,0-9
  • 搭积木规则:
  • 每个积木放到其它两个积木的上面,并且一定比下面两个积木数字小。
  • 最后搭成4层的金字塔,必须用完所有的积木
  • 请你计算这样的搭建方法一共有多少种?

方法1:暴力筛选


import java.util.Set;
import java.util.TreeSet;

/**
 * 3.搭积木
 * 小明最近喜欢搭数字积木
 * 一共有10块积木,每个积木上有一个数字,0-9
 * 搭积木规则:
 * 每个积木放到其它两个积木的上面,并且一定比下面两个积木数字小。
 * 最后搭成4层的金字塔,必须用完所有的积木
 * 请你计算这样的搭建方法一共有多少种?
 *
 */
public class Main 
    static Set<Integer> set ;
    static int count = 0 ;
    public static void main(String[] args) 
        set = new TreeSet<>() ;
        for(int a=1; a<=9; a++)
            for(int b=1; b<=9; b++)
                for(int c=1; c<=9; c++)
                    for(int d=1; d<=9; d++)
                        for(int e=1; e<=9; e++)
                            for(int f=1; f<=9; f++)
                                for(int g=1; g<=9; g++)
                                    for(int h=1; h<=9; h++)
                                        for(int i=1; i<=9; i++)
                                            if(a < c && a < d && b<d && b < e)
                                                if(c < f && c < g && d < g && d < h && e < h && e < i)
                                                    int [] res = a,b,c,d,e,f,g,h,i ;
                                                    for(int j=0; j<res.length; j++) 
                                                        set.add(res[j]);
                                                
                                                    if(set.size() == 9)
                                                        count ++ ;
                                                        set.clear();
                                                    else
                                                        set.clear();
                                                    
                                                
                                            
                                        
                                    
                                
                            
                        
                    
                
            
        
        System.out.println(count);
    


方法2:全排列剪枝

/**
 * 3.搭积木
 * 小明最近喜欢搭数字积木
 * 一共有10块积木,每个积木上有一个数字,0-9
 * 搭积木规则:
 * 每个积木放到其它两个积木的上面,并且一定比下面两个积木数字小。
 * 最后搭成4层的金字塔,必须用完所有的积木
 * 请你计算这样的搭建方法一共有多少种?
 *
 */
public class Main1 
    static int [] arr = 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ;
    static int count = 0;
    public static void main(String[] args) 
        f(0) ;
        System.out.println(count);
    

    /**
     * 全排列,剪枝法
     * @param k
     */
    private static void f(int k)
        if(k == 10)
            count ++ ;
        
        for(int i=k; i<10; i++)
            swap(i, k) ;
            if((k == 1 && arr[1]<arr[0])
                    || (k == 2 && arr[2]<arr[0])
                    || (k==3 && arr[3]<arr[1])
                    || (k==4 && (arr[4]<arr[1] || arr[4]<arr[2]))
                    || (k==5 && arr[5]<arr[2])
                    || (k==6 && arr[6]<arr[3])
                    || (k==7 && (arr[7]<arr[3] || arr[7]<arr[4]))
                    || (k==8 && (arr[8]<arr[4] || arr[8]<arr[5]))
                    || (k==9 && arr[9]<arr[5]))
                swap(i, k) ;
                continue ;
            
            f(k+1) ;
            swap(i,k);
        
    
    private static void swap(int i, int k)
        int t = arr[i] ;
        arr[i] = arr[k] ;
        arr[k] = t ;
    


4,5代码填空题,略

6.寒假作业

public class Main1 
    static int [] arr = 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13 ;
    static int count = 0;
    public static void main(String[] args) 
        f(0) ;
        System.out.println(count);
    

    /**
     * 全排列,剪枝法
     * @param k
     */
    private static void f(int k)
        if(k == 13) //13个全排列,最后一个不要就可以了
            count++;
        
        for(int i=k; i<13; i++)
            swap(i, k) ;
           if(k==2 && arr[0] + arr[1] != arr[2]
                    || k==5 && arr[3] - arr[4] != arr[5]
                    || k==8 && arr[6] * arr[7] != arr[8]
                    || k==11 && ((arr[9] / arr[10] != arr[11]) || (arr[9] % arr[10] != 0)))//取余保证除的都是整除
               swap(i, k);
               continue;
           
            f(k+1) ;
            swap(i,k);
        
    
    private static void swap(int i, int k)
        int t = arr[i] ;
        arr[i] = arr[k] ;
        arr[k] = t ;
    



7.剪邮票

  • 有12张连在一起的12生肖的邮票,现在你要从中剪下5张,要求必须是连着的
  • 仅仅连一个角不算连,请你计算一共有多少种不同的剪取方法。
/**
 * 7.剪邮票
 * 有12张连在一起的12生肖的邮票,现在你要从中剪下5张,要求必须是连着的
 * 仅仅连一个角不算连,请你计算一共有多少种不同的剪取方法。
 */

/**
 * 算法思想:枚举所有5张牌的组合,检查它们是否是一个连通块。
 * 12选5的过程可以用全排列去做。
 * 也就是用全排列随机的抽取5个格子,然后做连通性检查
 * 本题是带有重复元素的全排列,需要将重复的排列规避掉
 */
public class Main 
    static int [] a = 0,0,0,0,0,0,0,1,1,1,1,1 ; //每个排列代表着12选5的一个方案
    static int ans ;
    static boolean [] vis = new boolean [12] ;
    static void f(int k, int [] path)
        if(k == 12)
            if(check(path))
                ans ++ ;
            
        
        for(int i=0; i<12; i++)
            if(i>0 && a[i] == a[i-1] && !vis[i-1]) //当前选中的元素与上一个元素相同,且上一个元素未被用到
                continue;
            
            if(!vis[i]) //没有被用过的元素可以加入到path
                vis[i] = true ; //标记被使用过
                path[k] = a[i] ;//将a[i]存到path[k]中
                f(k+1, path) ;//递归
                vis[i] = false ; //回溯
            
        
    
    static boolean check(int [] path)
        int [][] g = new int [3][4] ;
        //将某个排列映射到二维矩阵上
        for(int i=0; i<3; i++)
            for(int j=0; j<4; j++)
                if(path[4*i+j] == 1)
                    g[i][j] = 1 ;
                else
                    g[i][j] = 0 ;
                
            
        
        int cnt = 0 ;
        for(int i=0; i<3; i++)
            for(int j=0; j<4; j++)
                if(g[i][j] == 1)
                   dfs(g, i, j) ;
                    cnt ++ ; //一次走完,如果没走完则说明不是联通的
                
            
        
        return cnt == 1;
    

    private static void dfs(int[][] g, int i, int j)  //向着四个方向搜索
        g[i][j] = 0 ;
        if(i-1>=0 && g[i-1][j]==1)
            dfs(g, i-1, j) ;
        
        if(i+1<=2 && g[i+1][j]==1)
            dfs(g, i+1, j) ;
        
        if(j-1>=0 && g[i][j-1]==1)
            dfs(g, i, j-1) ;
        
        if(j+1<=3 && g[i][j+1]==1)
            dfs(g, i, j+1) ;
        
    

    public static void main(String[] args) 
        int [] path = new int [12] ;
        f(0, path) ;
        System.out.println(ans);
    


8.取秋博弈

  • 两个人取球得游戏,一共有N给球,每人轮流取球,每次可取集合n1,n2,n3中得任何一个数目
  • 如果无法继续取球,则游戏结束
  • 此时持有奇数个球得人获胜,如果连个都是奇数,则是平局
  • 每次都用最聪明得取法

方法1:递归法

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

/**
 * 8.取秋博弈
 * 两个人取球得游戏,一共有N给球,每人轮流取球,每次可取集合n1,n2,n3中得任何一个数目
 * 如果无法继续取球,则游戏结束
 * 此时持有奇数个球得人获胜,如果连个都是奇数,则是平局
 * 每次都用最聪明得取法
 *
 * 算法思想:只要找出这个最聪明得取法得规律就可以解题
 */
public class Main 
    static int [] n = new int [3] ;
    static 第八届蓝桥杯(2017年)JavaA组省赛真题解析

蓝桥日记③2016第七届省赛(软件类)JavaA组✿答案解析

第七届蓝桥杯本科B组省赛

第七届蓝桥杯CC++B组省赛题目——方格填数

第九届蓝桥杯JavaA组(2018年)省赛真题解析

蓝桥真题——2021年蓝桥python组省赛真题+解析+代码(通俗易懂版)