蓝桥杯之全部基础练习答案及思路(java)

基础练习

第一题 数列排序

资源限制
时间限制:1.0s 内存限制:512.0MB
问题描述
给定一个长度为n的数列,将这个数列按从小到大的顺序排列。1<=n<=200
输入格式
第一行为一个整数n。
第二行包含n个整数,为待排序的数,每个整数的绝对值小于10000。
输出格式
输出一行,按从小到大的顺序输出排序后的数列。
样例输入
5
8 3 6 4 9
样例输出
3 4 6 8 9

思路:对于数列排序在java中有对应的Arrays包,里面提供对数列升序排序的方法,也就是Arrays.sort()函数,

import java.util.Arrays;
import java.util.Scanner;
public class Main{
	public static void main(String[] args) {
		Scanner input=new Scanner(System.in);
		int n=input.nextInt();
		int[] a=new int[n];
		for(int i=0;i;i++) {
			a[i]=input.nextInt();
		}
		Arrays.sort(a);
		for(int i=0;i;i++) {
			System.out.print(a[i]+" ");
		}
	}
}

第二题 十六进制转八进制

资源限制
时间限制:1.0s 内存限制:512.0MB
问题描述
给定n个十六进制正整数,输出它们对应的八进制数。
输入格式
输入的第一行为一个正整数n (1<=n<=10)。
接下来n行,每行一个由0-9、大写字母A-F组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度不超过100000。
输出格式
输出n行,每行为输入对应的八进制正整数。
【注意】
输入的十六进制数不会有前导0,比如012A。
输出的八进制数也不能有前导0。
样例输入
2
39
123ABC
样例输出
71
4435274
【提示】
先将十六进制数转换成某进制数,再由某进制数转换成八进制。

最开始看到进制转换问题,我就以为是一个简单的问题,我相信大多人都和我一样,但将我在eclipse上实现的代码放入蓝桥杯练习系统中提交,结果是得了0分。题目中有一个很关键的话,每个十六进制长度不超过100000,这个说如果用int或long解决都是不够的,因为她们的位数远没有那么多,于是只能使用字符串型。字符串型不仅能连接字符而且还有许多重要的方法。

思路:题目中提示:先将十六进制转化为某进制,再由某进制数转化为八进制。所以那个中间进制是连接十六进制和八进制的桥梁,那就是二进制。先把十六进制转化为二进制,每位十六进制数正好转化为四个二进制位数,再把二进制数转为八进制数,每三位二进制数可转化为一位八进制数。代码如下:

import java.util.Scanner;
public class Main{
	public static String toBinary(String str_Hex) {
		StringBuffer str_Bin=new StringBuffer();
		for(int i=0;ilength();i++) {
			switch(str_Hex.charAt(i)) {
			case '0':str_Bin.append("0000");break;
			case '1':str_Bin.append("0001");break;
			case '2':str_Bin.append("0010");break;
			case '3':str_Bin.append("0011");break;
			case '4':str_Bin.append("0100");break;
			case '5':str_Bin.append("0101");break;
			case '6':str_Bin.append("0110");break;
			case '7':str_Bin.append("0111");break;
			case '8':str_Bin.append("1000");break;
			case '9':str_Bin.append("1001");break;
			case 'A':str_Bin.append("1010");break;
			case 'B':str_Bin.append("1011");break;
			case 'C':str_Bin.append("1100");break;
			case 'D':str_Bin.append("1101");break;
			case 'E':str_Bin.append("1110");break;
			case 'F':str_Bin.append("1111");break;
			default: break;
			}
		}
		return str_Bin.toString();
	}
	public static String toOctal(String str_Bin) {
		StringBuffer str_Octal=new StringBuffer();
		int k=0;
		if(str_Bin.substring(0,3).equals("000")) k=3;
		for(int i=k;ilength()-2;i=i+3) {
			switch(str_Bin.substring(i,i+3)) {
			case "000":str_Octal.append("0");break;
			case "001":str_Octal.append("1");break;
			case "010":str_Octal.append("2");break;
			case "011":str_Octal.append("3");break;
			case "100":str_Octal.append("4");break;
			case "101":str_Octal.append("5");break;
			case "110":str_Octal.append("6");break;
			case "111":str_Octal.append("7");break;
			default:break;
			}
		}
		return str_Octal.toString();
	}
	public static void main(String[] args) {
		Scanner input=new Scanner(System.in);
		int n=input.nextInt();
		String[] str_Hex=new String[n];
		String str_Bin="";
		String str_Octal="";
		for(int i=0;i;i++) {
			str_Hex[i]=input.next();
		}
		for(int i=0;i;i++) {
			str_Bin=toBinary(str_Hex[i]);
			if(str_Bin.length()%3==1) {
				str_Bin="00"+str_Bin;
			}
			else if(str_Bin.length()%3==2) {
				str_Bin="0"+str_Bin;
			}
			str_Octal=toOctal(str_Bin);
			System.out.println(str_Octal);
		}
	}
}

在实现的过程中我发现几个问题:
1、equals与==的区别辨别:equals比较的是值是否相同,而 = = == ==比较的是地址。
2、String、StringBuffer和StringBuilder的区别:
①String:适用于少量的字符串操作的情况
②StringBuilder:适用于单线程下在字符缓冲区进行大量操作的情况
③StringBuffer:适用多线程下在字符缓冲区进行大量操作的情况
3、StringBuffer转换为String时使用.toString()函数

拓展:使用JAVA自带函数进行进制转换
1、十进制转化为N进制
Integer.toBinaryString(int i)//返回的是i的二进制表示,返回类型为String
Integer.toString(int i,int radix)//返回的是i的二进制表示,返回类型为String,但是负数不适用。
Integer.toHexString(int i)//返回16进制
Integer.toOctalString(int i)//返回8进制
2、N进制转化为十进制
Integer.parseInt(String s,int radix)
Integer.valueOf(String s,int radix)

第三题 十六进制转十进制

资源限制
时间限制:1.0s 内存限制:512.0MB
问题描述
从键盘输入一个不超过8位的正的十六进制数字符串,将它转换为正的十进制数后输出。
注:十六进制数中的10~15分别用大写的英文字母A、B、C、D、E、F表示。
样例输入
FFFF
样例输出
65535

思路:这一题相比于上一题,容易许多,由于题目要求不超过8位的十六进制字符串,所以可以使用long封装类中的parseLong(String s)函数.

import java.util.Scanner;
public class Main{
	public static void main(String[] args) {
		Scanner input=new Scanner(System.in);
		String hex=input.next();
		long decimal=Long.parseLong(hex,16);
		System.out.print(decimal);
	}
}

我也发现关于int等变量类型的范围等涉及到了许多次,于是我查阅了具体的资料:
1、
基本类型:short 二进制位数:16
包装类:java.lang.Short
最小值:Short.MIN_VALUE=-32768 (-2的15次方)
最大值:Short.MAX_VALUE=32767 (2的15次方-1)
2、
基本类型:int 二进制位数:32
包装类:java.lang.Integer
最小值:Integer.MIN_VALUE= -2147483648 (-2的31次方)
最大值:Integer.MAX_VALUE= 2147483647 (2的31次方-1)
3、
基本类型:long 二进制位数:64
包装类:java.lang.Long
最小值:Long.MIN_VALUE=-9223372036854775808 (-2的63次方)
最大值:Long.MAX_VALUE=9223372036854775807 (2的63次方-1)
4、
基本类型:float 二进制位数:32
包装类:java.lang.Float
最小值:Float.MIN_VALUE=1.4E-45 (2的-149次方)
最大值:Float.MAX_VALUE=3.4028235E38 (2的128次方-1)
5、
基本类型:double 二进制位数:64
包装类:java.lang.Double
最小值:Double.MIN_VALUE=4.9E-324 (2的-1074次方)
最大值:Double.MAX_VALUE=1.7976931348623157E308 (2的1024次方-1)

第四题 十进制转十六进制

资源限制
时间限制:1.0s 内存限制:512.0MB
问题描述
十六进制数是在程序设计时经常要使用到的一种整数的表示方式。它有0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F共16个符号,分别表示十进制数的0至15。十六进制的计数方法是满16进1,所以十进制数16在十六进制中是10,而十进制的17在十六进制中是11,以此类推,十进制的30在十六进制中是1E。
给出一个非负整数,将它表示成十六进制的形式。
输入格式
输入包含一个非负整数a,表示要转换的数。0<=a<=2147483647
输出格式
输出这个整数的16进制表示
样例输入
30
样例输出
1E

思路:正如上面一样,使用java自带的类函数Integer.toHexString(),但输出发现十六进制的字母部分是小写表示,所以又使用了Integer类自带的toUpperCase()函数。

import java.util.Scanner;
public class Main{
	public static void main(String[] args) {
		Scanner input=new Scanner(System.in);
		int x=input.nextInt();
		System.out.print(Integer.toHexString(x).toUpperCase());
	}
}

第五题 特殊回文数

资源限制
时间限制:1.0s 内存限制:512.0MB
问题描述
123321是一个非常特殊的数,它从左边读和从右边读是一样的。
输入一个正整数n, 编程求所有这样的五位和六位十进制数,满足各位数字之和等于n 。
输入格式
输入一行,包含一个正整数n。
输出格式
按从小到大的顺序输出满足条件的整数,每个整数占一行。
样例输入
52
样例输出
899998
989989
998899
数据规模和约定
1<=n<=54。

思路:根据题目要求我想到的是暴力枚举法,从五位数10000到六位数999999,找出符合两个条件的数。两个条件为:①各位数字之和等于n;②是回文数。所以可以使用两个函数来找出符合条件的数。在实施的过程中我在写判断回文的函数时出了一些问题,我使用了两个for函数分别从数的两端检查是否是回文,但第二个循环检查的是所有从后往前的数,所以运行不出来。后来我使用字符串的总长度和i的关系,解决了这个问题。

import java.util.Scanner;
public class Main {
	public static void main(String[] args) {
		Scanner input = new Scanner(System.in);
		int n = input.nextInt(); 
		for(int i=10000;i<1000000;i++)
		{
			if(isHuiWen(i) && is(i,n))
				System.out.println(i);
		}
	}
	public static boolean isHuiWen(int x)
	{
		String s=x+"";                                  //也可使用Integer.toString(x)
		for(int i=0;ilength()/2+1;i++)
		{
			if(s.charAt(i)!=s.charAt(s.length()-1-i))
				return false;
		}
		return true;
	}
	public static boolean is(int x,int n)
	{
		int k=0;
		while(x>0)
		{
			k+=x%10;
			x/=10;
		}
		if(k==n)
			return true;
		else
			return false;
	}
}

第六题 回文数

资源限制
时间限制:1.0s 内存限制:512.0MB
问题描述
1221是一个非常特殊的数,它从左边读和从右边读是一样的,编程求所有这样的四位十进制数。
输出格式
按从小到大的顺序输出满足条件的四位十进制数。

思路:和上一题特殊回文数大同小异

public class Main {
	public static void main(String[] args) {
		for(int i=1000;i<10000;i++)
		{
			if(isHuiWen(i))
				System.out.println(i);
		}
	}
	
	public static boolean isHuiWen(int x)
	{
		String s=x+"";          
		for(int i=0;ilength()/2+1;i++)
		{
			if(s.charAt(i)!=s.charAt(s.length()-1-i))
				return false;
		}
		return true;
	}
	
}

第七题 特殊的数

资源限制
时间限制:1.0s 内存限制:512.0MB
问题描述
153是一个非常特殊的数,它等于它的每位数字的立方和,即153=1 * 1 * 1+5 * 5 * 5+3 * 3 * 3。编程求所有满足这种条件的三位十进制数。
输出格式
按从小到大的顺序输出满足条件的三位十进制数,每个数占一行。

思路:题目很明确,是寻找所有特殊的三位数(该数的每位数字的立方和等于该数字)

public class Main{
	public static void main(String[] args) {
		for(int i=100;i<1000;i++) {
			if(isSpecial(i)) {
				System.out.println(i);
			}
		}
	}
	public static boolean isSpecial(int n) {
		int sum=0;
		int yuanShu=n;
		while(n>0){
			int wei=n%10;
			sum=wei*wei*wei+sum;
			n=n/10;
		}
		if(sum==yuanShu) {
			return true;
		}
		else
			return false;
	}
	
}

第八题 查找整数

资源限制
时间限制:1.0s 内存限制:256.0MB
问题描述
给出一个包含n个整数的数列,问整数a在数列中的第一次出现是第几个。
输入格式
第一行包含一个整数n。
第二行包含n个非负整数,为给定的数列,数列中的每个数都不大于10000。
第三行包含一个整数a,为待查找的数。
输出格式
如果a在数列中出现了,输出它第一次出现的位置(位置从1开始编号),否则输出-1。
样例输入
6
1 9 4 8 3 9
9
样例输出
2
数据规模与约定
1 <= n <= 1000。

思路:话说这道题不是很难,但我卡在了怎样输出-1上面。

import java.util.Scanner;
public class Main {
	public static void main(String[] args) {
		Scanner input=new Scanner(System.in);
		int n=input.nextInt();
		int[] numbers=new int[n];
		for(int i=0;i;i++) {
			numbers[i]=input.nextInt();
		}
		int a=input.nextInt();
		for(int i=0;i;i++) {
			if(a==numbers[i]) {
				System.out.println(i+1);
				return;
			}
		}
			System.out.println(-1);
	}
}

第九题 数列特征

资源限制
时间限制:1.0s 内存限制:256.0MB
问题描述
给出n个数,找出这n个数的最大值,最小值,和。
输入格式
第一行为整数n,表示数的个数。
第二行有n个数,为给定的n个数,每个数的绝对值都小于10000。
输出格式
输出三行,每行一个整数。第一行表示这些数中的最大值,第二行表示这些数中的最小值,第三行表示这些数的和。
样例输入
5
1 3 -2 4 5
样例输出
5
-2
11
数据规模与约定
1 <= n <= 10000。

思路:将数列排序,从而找到最大最小的数。

import java.util.Arrays;
import java.util.Scanner;
public class Main {
	public static void main(String[] args) {
		Scanner input=new Scanner(System.in);
		int n=input.nextInt();
		int[] numbers=new int[n];
		int sum=0;
		for(int i=0;i;i++) {
			numbers[i]=input.nextInt();
			sum=sum+numbers[i];
		}
		Arrays.sort(numbers);
		System.out.println(numbers[n-1]);
		System.out.println(numbers[0]);
		System.out.println(sum);
		
	}
}

第十题 字母图形

资源限制
时间限制:1.0s 内存限制:256.0MB
问题描述
利用字母可以组成一些美丽的图形,下面给出了一个例子:
ABCDEFG
BABCDEF
CBABCDE
DCBABCD
EDCBABC
这是一个5行7列的图形,请找出这个图形的规律,并输出一个n行m列的图形。
输入格式
输入一行,包含两个整数n和m,分别表示你要输出的图形的行数的列数。
输出格式
输出n行,每个m个字符,为你的图形。
样例输入
5 7
样例输出
ABCDEFG
BABCDEF
CBABCDE
DCBABCD
EDCBABC
数据规模与约定
1 <= n, m <= 26。

思路:话术这道题想了一会规律,但却没有找出来,有想到使用二维数组,但没有想到抓住关键,第i行i列的字符都是‘A’。所以该题的规律就在于,行与列之差的绝对值和对‘A’偏移有关。代码如下:

import java.util.Scanner;
public class Main {
	public static void main(String[] args) {
		Scanner input=new Scanner(System.in);
		int n=input.nextInt();
		int m=input.nextInt();
		char[][] ch=new char[n][m];
		for(int i=0;i;i++) {
			for(int j=0;j;j++) {
				if(i==j) {
					ch[i][j]='A';
				}
				else {
					ch[i][j]=(char)('A'+Math.abs(i-j));
				}
				System.out.print(ch[i][j]);
			}
		System.out.println();	
		}
	}
}

第十一题 01字串

资源限制
时间限制:1.0s 内存限制:256.0MB
问题描述
对于长度为5位的一个01串,每一位都可能是0或1,一共有32种可能。它们的前几个是:
00000
00001
00010
00011
00100
请按从小到大的顺序输出这32种01串。
输入格式
本试题没有输入。
输出格式
输出32行,按从小到大的顺序每行一个长度为5的01串。
样例输出
00000
00001
00010
00011
<以下部分省略>

思路:我用的方法是将正整数转换为二进制字符串,在操作的过程中我发现,Integer.toBinaryString()转换的二进制数的位数是不同的,故我搜索了将数字补位0的方法,从而解决了问题。

public class Main {
	public static void main(String[] args) {
		byte n=0;
		String bi=Integer.toBinaryString(n);
		String s=bi;
		for(int i=1;i<=32;i++) {
			s=String.format("%5s", bi).replace(" ","0");
			System.out.println(s);
			bi=Integer.toBinaryString(++n);
		}
	}
}

下面是我找到的几种补位的方法:
1)数字补位:
①使用System.out.printf(“%0+总位数+d”,整数型(printf()左对齐是前面加“-”,右对齐什么都不加);如System.out.printf("%05d",1); //输出00001
②使用String.format("%0+总位数+d",整数型);如String.format("%05d",1); //输出00001
2)字符串补位:
①使用字符串方法,将空格处换为0位:使用String.format("%总位数+s",字符串).replace(" ",“0”).例如:

	String s=String.format("%5s", 1).replace(" ","0");
	System.out.printf(s);\\输出00001

②可使用Integer.parseInt()等类似函数,将字符串类型转换为整型,再使用上述数字补位方法。
补充:Integer.parseInt()方法最后得到的是基本数据类型,而Integer.valueOf()可返回的是对应的对象类型,且会调用parseInt().

第十二题 闰年判断

资源限制
时间限制:1.0s 内存限制:256.0MB
问题描述
给定一个年份,判断这一年是不是闰年。
当以下情况之一满足时,这一年是闰年:
1.年份是4的倍数而不是100的倍数;
2.年份是400的倍数。
其他的年份都不是闰年。
输入格式
输入包含一个整数y,表示当前的年份。
输出格式
输出一行,如果给定的年份是闰年,则输出yes,否则输出no。
说明:当试题指定你输出一个字符串作为结果(比如本题的yes或者no,你需要严格按照试题中给定的大小写,写错大小写将不得分。
样例输入
2013
样例输出
no
样例输入
2016
样例输出
yes
数据规模与约定
1990 <= y <= 2050。

思路:这道题很基础的题,使用if语句直接将闰年满足的条件表示出来即可。

import java.util.Scanner;
public class Main {
	public static void main(String[] args) {
		Scanner input=new Scanner(System.in);
		int year=input.nextInt();
		if((year%4==0 && year%100!=0) || (year%400==0)) {
			System.out.println("yes");
		}
		else
			System.out.println("no");		
	}
}

你可能感兴趣的:(java)