第七届蓝桥杯(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组省赛真题解析