2015年javaB组1-4题解析与理解

第一题:
标题:分机号

X老板脾气古怪,他们公司的电话分机号都是3位数,老板规定,所有号码必须是降序排列,且不能有重复的数位。比如:

751,520,321 都满足要求,而,
766,918,201 就不符合要求。

现在请你计算一下,按照这样的规定,一共有多少个可用的3位分机号码?

请直接提交该数字,不要填写任何多余的内容。
自己发现蓝桥杯比较喜欢靠全排列这种东西,所以建议读者们去看看
这里其实题目意思很简单就是排三位数,三位数必选降序排列,其中又不能出现重复的位数,所以最简单的方法就是用三层for循环从0到9来开始,但是如果仔细想想其实是可以缩小一部分范围的,就比如最高位最低也要取2,这样210才成立,如果取2以下的,那么第三位就怎么也取不到了,又因为是降序无法重复,所以,第二层循环就要从前一层循环-1开始,依次这样,就可以缩短部分的范围,节省一部分的时间,思路就是这样,下面附上源代码:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;

public class num01 {
	public static boolean panduan(int i,int j,int k)
	{
		boolean result=false;
		if(i>j&&j>k)
			result=true;
		return result;
	}
	public static void main(String[] args) throws IOException {
		StreamTokenizer in=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
		PrintWriter out=new PrintWriter(new OutputStreamWriter(System.out));
		int count=0;
		for(int i=9;i>1;i--)
		{
			for(int j=i-1;j>0;j--)
			{
				for(int k=j-1;k>-1;k--)
				{
					if(panduan(i, j, k))
					{
						//out.println(i+""+j+""+k);
						count++;
					}
				}
			}
		}
		out.println(count);
		out.flush();
	}
}

第二题:

标题:五星填数

如【图1.png】的五星图案节点填上数字:1~12,除去7和11。
要求每条直线上数字和相等。

如图就是恰当的填法。

请你利用计算机搜索所有可能的填法有多少种。
注意:旋转或镜像后相同的算同一种填法。

请提交表示方案数目的整数,不要填写任何其它内容。
在这里插入图片描述
这里我们的主要思路就是用数组来存储这些数据,但是该用怎样的数组呢,这里我们可以考虑用一维数组来存储,这里我们就需要理解如何来存储呢,我们不妨用下面的图标来存储,我在上面标注就是该数在数组中的下标
在这里插入图片描述
这样我们就可以定向的通过下标求和来判断是否符合题意,接下来的一步就是又像第一题一样,又要进行全排列了,这里的全排列就是比较标准的全排列了,这里作者就直接贴源代码解释了

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;

public class num02 {
	public static int count=0;
	public static int []num= {1,2,3,4,5,6,8,9,10,12};
	public static void fullsort(int []num,int i)
	{
		if(i==num.length)
		{
			if(panduan(num))
				count++;
			return;
		}
		for(int j=i;j<num.length;j++)
		{
			swap(num, i, j);
			fullsort(num, i+1);
			swap(num, i, j);
		}
	}
	public static boolean panduan(int []num)
	{
		boolean result=true;
		int []sum=new int [5];
		sum[0]=num[0]+num[2]+num[5]+num[8];
		sum[1]=num[0]+num[3]+num[6]+num[9];
		sum[2]=num[1]+num[2]+num[3]+num[4];
		sum[3]=num[1]+num[5]+num[7]+num[9];
		sum[4]=num[4]+num[6]+num[7]+num[8];
		for(int i=0;i<4;i++)
		{
			if(sum[i]!=sum[i+1])
			{
				result=false;
				break;
			}
		}
		return result;
	}
	public static void swap(int []num,int i,int j)
	{
		int temp=num[i];
		num[i]=num[j];
		num[j]=temp;
	}
	public static void main(String[] args) throws IOException {
		StreamTokenizer in=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
		PrintWriter out=new PrintWriter(new OutputStreamWriter(System.out));
		fullsort(num, 0);
		out.println(count/10);//圈重点了,这里一开始自己只是/5主要因为自己当时只想到了五角星的旋转,那样的话,一组值可以旋转5次,那样其实都是重复的
		                      //但之后才知道/10的意思,意思是一个五角星可以有五个顶点,每个顶点都有两条边,这两条边进行镜像只够又能形成一个,但是形成之后的哪一个是不算的
		                      //所以这样算起来的确应该/10
		out.flush();
	}
}

最后需要注意的就是最后的结果需要/10,原因作者也已经写在代码的注释当中了
第三题:
标题:显示二叉树

排序二叉树的特征是:
某个节点的左子树的所有节点值都不大于本节点值。
某个节点的右子树的所有节点值都不小于本节点值。

为了能形象地观察二叉树的建立过程,小明写了一段程序来显示出二叉树的结构来。

class BiTree
{
private int v;
private BiTree l;
private BiTree r;

public BiTree(int v){
	this.v = v;
}

public void add(BiTree the){
	if(the.v < v){
		if(l==null) l = the;
		else l.add(the);
	}
	else{
		if(r==null) r = the;
		else r.add(the);
	}
}

public int getHeight(){
	int h = 2;
	int hl = l==null? 0 : l.getHeight();
	int hr = r==null? 0 : r.getHeight();
	return h + Math.max(hl,hr);
}

public int getWidth(){
	int w = (""+v).length();
	if(l!=null) w += l.getWidth();
	if(r!=null) w += r.getWidth();
	return w;
}

public void show(){
	char[][] buf = new char[getHeight()][getWidth()];
	printInBuf(buf, 0, 0);
	showBuf(buf);
}

private void showBuf(char[][] x){
	for(int i=0; i<x.length; i++){
		for(int j=0; j<x[i].length; j++)
			System.out.print(x[i][j]==0? ' ':x[i][j]);
		System.out.println();
	}
}

private void printInBuf(char[][] buf, int x, int y){
	String sv = "" + v;
	
	int p1 = l==null? x : l.getRootPos(x);
	int p2 = getRootPos(x);
	int p3 = r==null? p2 : r.getRootPos(p2+sv.length());
	
	buf[y][p2] = '|';
	for(int i=p1; i<=p3; i++) buf[y+1][i]='-';
	for(int i=0; i<sv.length(); i++) ________________________________;  //填空位置
	if(p1<p2) buf[y+1][p1] = '/';
	if(p3>p2) buf[y+1][p3] = '\\';
	
	if(l!=null) l.printInBuf(buf,x,y+2);
	if(r!=null) r.printInBuf(buf,p2+sv.length(),y+2);
}

private int getRootPos(int x){
	return l==null? x : x + l.getWidth();
}

}
在这里插入图片描述
这里的重点就是先看懂这里面的几个重要的函数的意思,
这个函数是获取当前节点所在的整行的宽度:

public int getWidth(){
		int w = (""+v).length();
		if(l!=null) w += l.getWidth();
		if(r!=null) w += r.getWidth();
		return w;
	}

这个函数是用来获取当前节点的左边的宽度:

private int getRootPos(int x){
		return l==null? x : x + l.getWidth();
	}

之后我们可以通过这两行代码结合图片知道:
buf[y][p2] = ‘|’;
for(int i=p1; i<=p3; i++) buf[y+1][i]=’-’;
第y行只用来表示|符号
第y+1行用来表示/和----和根节点
p1的位置就代表左孩子结点的位置,p2代表右孩子结点的位置。
又通过分析填空之前的范围for(int i=0; i<sv.length(); i++)可以发现刚好是根节点的这个字的长度,又结合for(int i=p1; i<=p3; i++) buf[y+1][i]=’-’;可以知道原先是将整个范围内圈赋值为—,之后通过我们要填的这段代码将根节点的值赋进去所以分析得出,最后填的代码应该是;buf[y+1][p2+i]=sv.charAt(i);
接下来就是我填进去之后运行的结果:
在这里插入图片描述
第四题:
标题:穿越雷区

X星的坦克战车很奇怪,它必须交替地穿越正能量辐射区和负能量辐射区才能保持正常运转,否则将报废。
某坦克需要从A区到B区去(A,B区本身是安全区,没有正能量或负能量特征),怎样走才能路径最短?

已知的地图是一个方阵,上面用字母标出了A,B区,其它区都标了正号或负号分别表示正负能量辐射区。
例如:

坦克车只能水平或垂直方向上移动到相邻的区。

数据格式要求:
在这里插入图片描述

输入第一行是一个整数n,表示方阵的大小, 4<=n<100
接下来是n行,每行有n个数据,可能是A,B,+,-中的某一个,中间用空格分开。
A,B都只出现一次。

要求输出一个整数,表示坦克从A区到B区的最少移动步数。
如果没有方案,则输出-1

例如:
用户输入:
在这里插入图片描述

则程序应该输出:
10

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

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

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

这里的主要思想就是深搜,以及剪枝这里剪枝可以通过下标的位置是否合乎范围来剪枝就比如:

if(i<0||i>n-1||j<0||j>n-1)
			return;

之后还有一点就是,只能走自己附近的点就是上下左右,所以我们可以通过一个数组来实现即:

public static int dir[][]=new int[][]{{-1,0},{0,1},{1,0},{0,-1}};

之后就比较简单了,以下是源代码;

import java.util.Scanner;

public class num04 {
	public static int n;
	public static int i1,j1;
	public static int count=0;
	public static int min;
	public static boolean flag=false;
	public static char map[][];
	public static int visit[][];
    public static int dir[][]=new int[][]{{-1,0},{0,1},{1,0},{0,-1}};
	public static void dfs(int i,int j)
	{
		int ii,jj;
		if(map[i][j]=='B')
		{
			flag=true;
			if(count<min)
				min=count;
			return ;
		}
		if(i<0||i>n-1||j<0||j>n-1)
			return;
		for(int k=0;k<4;k++)
		{
			ii=i+dir[k][0];
			jj=j+dir[k][1];
			if(ii<0||ii>n-1||jj<0||jj>n-1)
				continue;
			if(visit[ii][jj]==0&&map[ii][jj]!=map[i][j])
				{
					visit[ii][jj]=1;
					count++;
					dfs(ii, jj);
					count--;
					visit[ii][jj]=0;
				}
		}
	}
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		n=sc.nextInt();
		sc.nextLine();
		map=new char[n][n];
		visit=new int [n][n];
		min=n*n;
		String []str1=new String[n];
		String []str2=new String[n];
		for(int i=0;i<n;i++)
		{
			for(int j=0;j<n;j++)
			{
				visit[i][j]=0;
			}
		}
		for(int i=0;i<n;i++)
		{
			str1[i]=sc.nextLine();
			str2[i]=str1[i].replace(" ", "");
		}
		for(int i=0;i<n;i++)
		{
			for(int j=0;j<n;j++)
			{
				map[i][j]=str2[i].charAt(j);
				if(map[i][j]=='A')
				{
					i1=i;
					j1=j;
					visit[i1][j1]=1;
				}
			}
		}
		dfs(i1, j1);
		if(flag)
			System.out.println(min);
		else
			System.out.println(-1);
	}
}

作者很菜,如有不足,请指教

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
2022蓝桥杯javab解析如下: 2022蓝桥杯javab从基础到进阶,难度适中,测试了参赛选手在Java编程语言方面的知识和能力。目涵盖了数、字符串处理、面向对象编程等多个知识点,考察了学生的编程思维和解决问的能力。 首先,目要求实现一个学生成绩管理系统,包括学生信息录入、成绩查询、成绩统计等功能。通过类的设计和实例化,可以实现学生对象的创建和信息存储。使用数或集合来存储多个学生对象,便于后续的查询和统计操作。 其次,目要求实现一个简单的买卖股票的交易系统。需要设计一个股票类,其中包括股票名称、日期、买入价、卖出价等属性,然后通过输入的交易数据进行统计,计算利润最大化的买入和卖出操作。可以使用循环和条件语句来实现逻辑判断和计算运算。 最后,目要求实现一个小型的计算器程序。可以通过实现不同的方法来实现加、减、乘、除等基本运算。可以使用条件语句或循环语句来判断用户输入的操作,并进行相应的计算操作。 总结来说,2022蓝桥杯javab考察了参赛选手的编程能力和应用基础知识的能力,要求实现多个功能,并考察了类的设计和对象的使用。通过解析这些真,可以提高对Java编程语言的理解和应用能力,对于参加类似的编程竞赛有一定的帮助作用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值