小言_互联网的博客

2016第七届蓝桥杯省赛JAVA B组真题解析(带源码及解析)

292人阅读  评论(0)

蓝桥杯历年真题及解析.

A:煤球数目(难度:★).

有一堆煤球,堆成三角棱锥形。具体:
第一层放1个,
第二层3个(排列成三角形),
第三层6个(排列成三角形),
第四层10个(排列成三角形),

如果一共有100层,共有多少个煤球?

请填表示煤球总数目的数字。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。

分析:

观察得出规律,
第n层比第n-1层多出n个
ans=171700

AC代码:
public class A煤球数目 {
	public static void main(String[] args) {
		long ans=0;
		long t=0;
		for(int i=0;i<101;i++){
			t+=i;
			ans+=t;
		}
		System.out.println(ans);
	}
}

B:生日蜡烛(难度:★).

某君从某年开始每年都举办一次生日party,并且每次都要吹熄与年龄相同根数的蜡烛。

现在算起来,他一共吹熄了236根蜡烛。

请问,他从多少岁开始过生日party的?

请填写他开始过生日party的年龄数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。

分析:

无法直接得知开始生日的年龄
暴力枚举刚生日的那一年,一只向后加就OK
ans=26

AC代码:
public class B生日蜡烛 {
	public static void check(int i,int j){
		int ans=0;
		int n=i;
		while(i<=j){
			ans+=i;
			i++;
		}
		if(ans==236){
			System.out.println(n+" "+j);
		}
	}
	public static void main(String[] args) {
		for(int i=0;i<200;i++){
			for(int j=i;j<200;j++){
				check(i,j);
			}
		}
	}
}

C:凑算式(难度:★★).


这个算式中A~ I代表1~9的数字,不同的字母代表不同的数字。

比如:
6+8/3+952/714 就是一种解法,
5+3/1+972/486 是另一种解法。

这个算式一共有多少种解法?

注意:你提交应该是个整数,不要填写任何多余的内容或说明性文字。

分析:

对1~9进行全排列,
对于全排列得到的每一组结果进行check()
符合条件计数+1;
ans=29

AC代码:
package JB2016;

import java.util.Arrays;

public class C凑算式 {
	public static double arr[]={1,2,3,4,5,6,7,8,9};
	public static int count=0;
	public static void check(){
		double ans1=arr[0];
		double ans2=arr[1]/arr[2];
		double ans3=(arr[3]*100+arr[4]*10+arr[5])/(arr[6]*100+arr[7]*10+arr[8]);
		if(Math.abs(ans1+ans2+ans3-10)<0.00001){
			count++;
		}
	}
	
	public static void qpl(int k){
		if(k==9)check();
		else{
			for(int i=k;i<arr.length;i++){
				double t=arr[i];arr[i]=arr[k];arr[k]=t;
				qpl(k+1);
				t=arr[i];arr[i]=arr[k];arr[k]=t;
			}
		}
	}
	public static void main(String[] args) {
		qpl(0);
		System.out.println(count);
	}
}

D:分小组(难度:★★★).

9名运动员参加比赛,需要分3组进行预赛。
有哪些分组的方案呢?

我们标记运动员为 A,B,C,… I
下面的程序列出了所有的分组方法。

该程序的正常输出为:
ABC DEF GHI
ABC DEG FHI
ABC DEH FGI
ABC DEI FGH
ABC DFG EHI
… (以下省略,总共560行)。

仔细阅读代码,填写划线部分缺少的内容。

注意:不要填写任何已有内容或说明性文字。

分析:

题目要求分三组,
通过阅读源码,发现main函数内已经完成了第一组的分配,
remain(int a[])完成的是第三组的分配,
而第二组则与f函数内部三层循环的i,j,k,相关

s+" “+(char)(i+‘A’)+(char)(j+‘A’)+(char)(k+‘A’)+” "+remain(a)

AC代码:
package JB2016;

import java.util.Arrays;

public class D分小组
{
	public static String remain(int[] a)
	{
		String s = "";
		for(int i=0; i<a.length; i++){
			if(a[i] == 0) s += (char)(i+'A');
		}	
		return s;
	}
	
	public static void f(String s, int[] a)
	{
		for(int i=0; i<a.length; i++){
			if(a[i]==1) continue;
			a[i] = 1;
			for(int j=i+1; j<a.length; j++){
				if(a[j]==1) continue;
				a[j]=1;
				for(int k=j+1; k<a.length; k++){
					if(a[k]==1) continue;
					a[k]=1;
//					System.out.println(__________________________________);  //填空位置
					System.out.println(s+" "+(char)(i+'A')+(char)(j+'A')+(char)(k+'A')+" "+remain(a));
					a[k]=0;
				}
				a[j]=0;
			}
			a[i] = 0;
		}
	}
	
	public static void main(String[] args)
	{
		int[] a = new int[9];		
		a[0] = 1;
		
		for(int b=1; b<a.length; b++){
			a[b] = 1;
			for(int c=b+1; c<a.length; c++){
				a[c] = 1;
				String s = "A" + (char)(b+'A') + (char)(c+'A');
				f(s,a);
				a[c] = 0;
			}
			a[b] = 0;
		}
	}
	
}

E:抽签(难度:★★).

X星球要派出一个5人组成的观察团前往W星。
其中:
A国最多可以派出4人。
B国最多可以派出2人。
C国最多可以派出2人。

那么最终派往W星的观察团会有多少种国别的不同组合呢?

下面的程序解决了这个问题。
数组a[] 中既是每个国家可以派出的最多的名额。
程序执行结果为:
DEFFF
CEFFF
CDFFF
CDEFF

(以下省略,总共101行)

仔细阅读代码,填写划线部分缺少的内容。

注意:不要填写任何已有内容或说明性文字。

分析:

很明显的递归调用问题,
a表示数据数组,不需要改变
每次调用k+1,讨论下一个国家出人数的问题
n-i表示本来差n个人,来了i人之后,还差n-i人
用s2代替之前的s
ans=f(a,k+1,n-i,s2);

AC代码:
package JB2016;

public class E抽签
{
	public static void f(int[] a, int k, int n, String s)
	{
		if(k==a.length){ 
			if(n==0) System.out.println(s);
			return;
		}
		
		String s2 = s;
		for(int i=0; i<=a[k]; i++){
			f(a,k+1,n-i,s2);
//			_____________________________;   //填空位置
			s2 += (char)(k+'A');
		}
	}
	
	public static void main(String[] args)
	{
		int[] a = {4,2,2,1,1,3};
		
		f(a,0,5,"");
	}
}


F:方格填数(难度:★★★★).

如下的10个格子

填入0~9的数字。要求:连续的两个数字不能相邻。
(左右、上下、对角都算相邻)

一共有多少种可能的填数方案?

请填写表示方案数目的整数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。

分析:

全排列出所有的填数情况,
对每种情况进行检查,
符合条件计数+1;
ans=1580

AC代码:
package JB2016;

public class F方格填数 {
	public static int count=0;
	public static int arr[]={0,1,2,3,4,5,6,7,8,9};
	public static void check(){
		int buf[][]=new int[3][4];
		buf[0][0]=1000;buf[2][3]=1000;
		int k=0;
		for(int i=0;i<3;i++){
			for(int j=0;j<4;j++){
				if((i==0&&j==0)||(i==2&&j==3))continue;
				buf[i][j]=arr[k];
				k++;
			}
		}
		for(int x=0;x<3;x++){
			for(int y=0;y<4;y++){
				for(int i=-1;i<2;i++){
					for(int j=-1;j<2;j++){
						if(x+i>=0&&y+j>=0&&x+i<3&&y+j<4&&Math.abs(buf[x+i][y+j]-buf[x][y])==1){
							return ;
						}
					}
				}
			}
		}
		count++;
		
	}
	public static void qpl(int k){
		if(k==10)check();
		else{
			for(int i=k;i<arr.length;i++){
				int t=arr[k];arr[k]=arr[i];arr[i]=t;
				qpl(k+1);
				t=arr[k];arr[k]=arr[i];arr[i]=t;
			}
		}
	}
	public static void main(String[] args) {
		qpl(0);
		System.out.println(count);
	}
}

G:剪邮票(难度:★★★★★).

如:

有12张连在一起的12生肖的邮票。
现在你要从中剪下5张来,要求必须是连着的。
(仅仅连接一个角不算相连)
比如,

粉红色所示部分就是合格的剪取。

请你计算,一共有多少种不同的剪取方法。

请填写表示方案数目的整数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。

分析:

暴力枚举5个位置,
对这五个位置所组成的状态进行DFS,
《参考水洼数目》
如果五个位置是连接的,则一次深搜即可扫描五个位置
否则即为不连接
ans=116

AC代码:
package JB2016;

import java.util.Collections;
import java.util.HashSet;

public class G剪邮票 {
	public static int count=0;
	public static int arr[][]=new int [3][4];
	public static void dfs(int x,int y,int step){
		arr[x][y]=0;
		if(step==5){
			return;
		}
		if(x-1>=0&&x-1<3&&arr[x-1][y]==1){
			dfs(x-1,y,step+1);
		}
		if(x+1>=0&&x+1<3&&arr[x+1][y]==1){
			dfs(x+1,y,step+1);
		}
		if(y-1>=0&&y-1<4&&arr[x][y-1]==1){
			dfs(x,y-1,step+1);
		}
		if(y+1>=0&&y+1<4&&arr[x][y+1]==1){
			dfs(x,y+1,step+1);
		}
	}
	public static void check(HashSet<Integer> set){
		
		int i=-1,j=-1;
		for(int x:set){
			arr[x/4][x%4]=1;
			i=x/4;
			j=x%4;
		}
		dfs(i,j,1);
		boolean flag=true;
		for(i=0;i<3;i++){
			for(j=0;j<4;j++){
				if(arr[i][j]==1){
					flag=false;
					arr[i][j]=0;
				}
			}
		}
		if(flag){
			count++;
		}
	}
	public static void insert(HashSet set,int k){
		if(set.size()==5){
			check(set);
		}
		else{
			for(int i=k;i<12;i++){
				set.add(i);
				insert(set,i+1);
				set.remove(i);
			}
		}
	}
	public static void main(String[] args) {
		HashSet<Integer> set=new HashSet<Integer>();
		insert(set,0);
		System.out.println(count);
	}

}

H:四平方和(难度:★★★).

四平方和定理,又称为拉格朗日定理:
每个正整数都可以表示为至多4个正整数的平方和。
如果把0包括进去,就正好可以表示为4个数的平方和。

比如:
5 = 0^2 + 0^2 + 1^2 + 2^2
7 = 1^2 + 1^2 + 1^2 + 2^2
(^符号表示乘方的意思)

对于一个给定的正整数,可能存在多种平方和的表示法。
要求你对4个数排序:
0 <= a <= b <= c <= d
并对所有的可能表示法按 a,b,c,d 为联合主键升序排列,最后输出第一个表示法

程序输入为一个正整数N (N<5000000)
要求输出4个非负整数,按从小到大排序,中间用空格分开

例如,输入:
5
则程序应该输出:
0 0 1 2

再例如,输入:
12
则程序应该输出:
0 2 2 2

再例如,输入:
773535
则程序应该输出:
1 1 267 838

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

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

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

分析:

暴力枚举三层for循环,
找出四平方和的前三个,
若n减去另外三项的平方,剩余数值依旧为某数的平方 ,
即找到了四平方和的四个数

AC代码:
package JB2016;

import java.util.Scanner;

public class H四平方和 {
	public static int count=0;
	public static boolean check(int n){
		int x=(int)(Math.sqrt(n)+0.000001);
		return x*x==n;
	}
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		int n=sc.nextInt();
		for(int i=0;i<=Math.sqrt(n+1);i++){
			n-=(i*i);
			for(int j=i;j<=Math.sqrt(n+1);j++){
				n-=(j*j);
				for(int k=j;k<=Math.sqrt(n+1);k++){
					n-=(k*k);
					if(check(n)){
						System.out.println(i+" "+j+" "+" "+k +" "+(int)(Math.sqrt(n)+0.000001));
						return;
					}
					n+=(k*k);
				}
				n+=(j*j);
			}
			n+=(i*i);
		}
		System.out.println(count);
	}

}

I 取球博弈(难度:★★★★★).

分析:

取球博弈分析.

AC代码:

取球博弈AC代码.

J:压缩变换(难度:★★★★).

分析:

压缩变换分析.

AC代码:

压缩变换AC代码.


转载:https://blog.csdn.net/qq_43652327/article/details/104943888
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场