13年蓝桥杯JavaB组题解
第一题
/**
* 第一题:世纪末的星期 题目描述: 曾有邪教称1999年12月31日是世界末日。当然该谣言已经不攻自破。
* 还有人称今后的某个世纪末的12月31日,如果是星期一则会… 有趣的是,
* 任何一个世纪末的年份的12月31日都不可能是星期一!!
* 于是,“谣言制造商”又修改为星期日…
* 1999年的12月31日是星期五,
* 请问:未来哪一个离我们最近的一个世纪末年(即xx99年)的12月31日正好是星期天(即星期日)?
* 请回答该年份(只写这个4位整数,不要写12月31等多余信息)
*/
/*
* 解题思路:
* 1、定义一个for函数,从1999年开始,每次加100年进行循环
* 2、使用calendar函数中的Calendar.getInstance
* get(Calendar.DAY_OF_WEEK)判断xx99,12,31的星期,
* 3、周日-周六为1-7
*/
package lanqiao13;
import java.util.Calendar;
class Main1{
public static void main(String[] arges) {
Calendar calendar = Calendar.getInstance();//calendar函数
for(int year=1999;year<=10000;year+=100) {
calendar.set(year,11,31);//建立这个时间,以便后面获取,"0"代表一月,11代表12月
if(calendar.get(Calendar.DAY_OF_WEEK)==1) {
//获取时间进行判断,"1"代表周日,“2”代表周一....
System.out.println(year);
break;
}
}
}
}
第二题
/**
* 小明是个急性子,上小学的时候经常把老师写在黑板上的题目抄错了。
有一次,老师出的题目是:36 x 495 = ?
他却给抄成了:396 x 45 = ?
但结果却很戏剧性,他的答案竟然是对的!!
因为 36 * 495 = 396 * 45 = 17820
类似这样的巧合情况可能还有很多,比如:27 * 594 = 297 * 54
假设 a b c d e 代表1~9不同的5个数字(注意是各不相同的数字,且不含0)
能满足形如: ab * cde = adb * ce 这样的算式一共有多少种呢?
请你利用计算机的优势寻找所有的可能,并回答不同算式的种类数。
满足乘法交换律的算式计为不同的种类,所以答案肯定是个偶数。
*/
/*
* 解题思路:
* 1、5层枚举法进行for循环
* 2、五个数各不相同,每次循环结束后进行判断
*
*/
package lanqiao13;
public class Main2 {
public static void main(String[] args) {
int n = 0;
for (int a = 1; a <= 9; a++) {
for (int b = 1; b <= 9; b++) {//判断是否和前一个数相等
if (a != b) {
for (int c = 1; c <= 9; c++) {
if (c != a && c != b) {
for (int d = 1; d <= 9; d++) {
if (d != a && d != b && d != c) {
for (int e = 1; e <= 9; e++) {
if (e != a && e != b && e != c && e != d)
if ((10 * a + b) * (100 * c + 10 * d + e) == (100 * a + 10 * d + b)
* (10 * c + e)) {
n++;
}
}
}
}
}
}
}
}
}
System.out.println(n);
}
}
第三题
/**
* 小明参加了学校的趣味运动会,其中的一个项目是:跳格子。
地上画着一些格子,每个格子里写一个字,如下所示:(也可参见p1.jpg)
从我做起振
我做起振兴
做起振兴中
起振兴中华
比赛时,先站在左上角的写着“从”字的格子里,可以横向或纵向跳到相邻的格子里,但不能跳到对角的格子或其它位置。一直要跳到“华”字结束。
要求跳过的路线刚好构成“从我做起振兴中华”这句话。
请你帮助小明算一算他一共有多少种可能的跳跃路线呢?
*/
/*
* 解题思路:
* 1、递归深搜 :适合树枝分叉型进行计数
* 2、使用坐标思想,“从”坐标(0,0),“华”坐标(3,4),从00-34往左右走才能构成“从我做起振兴中华”
* 3、每到一级都有下和右两种选择向下走和向右走的所有路线加起来就是总路线
* 4、创建一个方法dsf(int i, int j),若i=3,或j=4就只有一种方向,return 1;
* 5、反之,返回坐标在进行循环
*/
package lanqiao13;
public class Main3 {
public static void main(String[] args) {
int s = dsf0.dsf(0, 0);
System.out.println(s);
}
}
//递归深搜
class dsf0 {
public static int dsf(int i, int j) {
if (i == 3 || j == 4) {
return 1;
}else {
return dsf(i + 1, j) + dsf(i, j + 1);
}
}
}
第四题
/**
* 黄金分割数0.61803… 是个无理数,这个常数十分重要,在许多工程问题中会出现。有时需要把这个数字求得很精确。
对于某些精密工程,常数的精度很重要。也许你听说过哈勃太空望远镜,它首次升空后就发现了一处人工加工错误,
对那样一个庞然大物,其实只是镜面加工时有比头发丝还细许多倍的一处错误而已,却使它成了“近视眼”!!
言归正传,我们如何求得黄金分割数的尽可能精确的值呢?有许多方法。
比较简单的一种是用连分数:
* 1
黄金数 = ------------------------------
1
1 + ---------------------
1
1 + -------------
1
1 + -------
1 + ...
这个连分数计算的“层数”越多,它的值越接近黄金分割数。
请你利用这一特性,求出黄金分割数的足够精确值,要求四舍五入到小数点后100位。
小数点后3位的值为:0.618
小数点后4位的值为:0.6180
小数点后5位的值为:0.61803
小数点后7位的值为:0.6180340
*(注意尾部的0,不能忽略)
*你的任务是:写出精确到小数点后100位精度的黄金分割值。
*注意:尾数的四舍五入! 尾数是0也要保留!
*/
/*
* 解题思路
* 1、小数点后100位,不能用double类型
* 2、要使用BigInteger和BigDecimal方法
* 3、1/2、 2/3 、 3/5 ,实际上是:1 1 2 3 5 8(斐波那锲函数),第1个数为第2个数除第1个数和第2个数的和
* 4、得出来的数最后要进行四舍五入
*/
package lanqiao13;
import static java.math.BigDecimal.ROUND_HALF_UP;
import java.math.BigDecimal;
import java.math.BigInteger;
public class Main4 {
public static void main(String[] args) {
BigInteger a = BigInteger.ONE;// 定义a =1
BigInteger b = new BigInteger("1");//BigInteger b = BigInteger.ONE;//定义b =1
BigInteger t;// BigDecimal t = new BigInteger()//只能放整形
// 斐波那契方法
for (int i = 1; i <= 900; i++) {
t = b;
b = a.add(b);
a = t;
}
BigDecimal divide = new BigDecimal(a, 110).divide(new BigDecimal(b, 110), BigDecimal.ROUND_HALF_UP);
// divide(BigDecimal) BigDecimal对象中的值相除,然后返回这个对象
// BigDecimal.ROUND_HALF_DOWN 四舍五入
System.out.println(divide.toPlainString().substring(0, 103));
// toString() 以科学计数法形式字符串输出
// toPlainString() 原值输出为字符串形式
// substring(0, 103) 限制个数:包括0和“.”
// 0.61803398874989484820458683436563811772030917980576286213544862270526046281890244970803605876859146255
// 0.61803398874989484820458683436563811772030917980576286213544862270526046281890244970720720418939113748
// 0.61803398874989484820458683436563811772030917980576286213544862270526046281890244970720720418939113748
// 0.61803398874989484820458683436563811772030917980576286213544862270526046281890244970720720418939113748
// 0.61803398874989484820458683436563811772030917980576286213544862270526046281890244970720720418939113748
}
// 斐波那锲方法
public static double re(int z) {
double x = 1.0;
double y = 1.0;
double t;
for (int i = 1; i <= z; i++) {
t = y;
y = x + y;
x = t;
}
return x / y;
}
}
package lanqiao13;
import java.math.BigDecimal;
import java.math.BigInteger;
public class Main4a {
public static void main(String[] args) {
BigInteger a = new BigInteger("1");
BigInteger b = new BigInteger("6");
BigDecimal t = new BigDecimal("1.4239999999999999999999999999");
/*
for(int i = 1;i<=600;i++) {
t = b;
b = a.add(b);
a = t;
}
BigDecimal divide = new BigDecimal(a,110).divide(new BigDecimal(b,110),BigDecimal.ROUND_HALF_UP);
System.out.println(divide.toPlainString().substring(0,103));
*/
System.out.println(b.pow(2));//乘幂
System.out.println(t.toString().substring(0,10));
}
}
package lanqiao13;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Random;
public class Main4b {
/**
* @param args
*/
public static void main(String[] args) {
Random rnd = new Random();//new 一个随机数
//生成五个范围在0 到 (2^1000 – 1)的随机整数
for (int i = 0; i < 5; i++) {
BigInteger a = new BigInteger(1000, rnd);
System.out.println(a);
}
//将数字字符串转成BigInteger,按二进制相加输出十进制
BigInteger c= new BigInteger("110",2);
System.out.println(c);//3
//将数字字符串后五位转换成BigDecimal
BigDecimal d=new BigDecimal(new BigInteger("111111"),5);
System.out.println(d.toPlainString());//0.11
//将字符转换成BigDecimal类型
BigDecimal e=new BigDecimal("2.01");
System.out.println(e.toPlainString());//2.01
//将字符数组转换成BigDecimal类型
char[] arr={'1','2'};
BigDecimal f=new BigDecimal(arr);
System.out.println(f.toPlainString());//12
//double类型直接转换成BigDecimal会失真
BigDecimal g=new BigDecimal(2.01);
System.out.println(g.toPlainString());//2.0099999999999997868371792719699442386627197265625
//double类型转换成BigDecimal
BigDecimal h= BigDecimal.valueOf(2.01);
System.out.println(h.toPlainString());//2.01
}
}
第五题
/**
* 有理数就是可以表示为两个整数的比值的数字。一般情况下,我们用近似的小数表示。但有些时候,不允许出现误差,必须用两个整数来表示一个有理数。
这时,我们可以建立一个“有理数类”,下面的代码初步实现了这个目标。为了简明,它只提供了加法和乘法运算。
*/
package lanqiao13;
class Rational
{
private long ra;
private long rb;
private long gcd(long a, long b){
if(b==0) {
return a;
}else {
return gcd(b,a%b);//递归,返回方法进行约分
//return a%b==0? b:gcb(b,a%b);
}
}
public Rational(long a, long b){
ra = a;//分子
rb = b;//分母
long k = gcd(ra,rb);//gcd求公约数
if(k>1){ //需要约分
ra /= k;
rb /= k;
}
}
// 加法
public Rational add(Rational x){
//填空位置
return new Rational(ra * x.rb + x.ra *rb, rb * x.rb);
//x代表另一个有理数,含有ra,rb,有理数的分子为ra和分母为rb
//有理数相加后:分母表示为rb乘x的分母rb(x.rb),分子为ra * x.rb + x.ra *rb
}
// 乘法
public Rational mul(Rational x){
return new Rational(ra*x.ra, rb*x.rb);
}
public String toString(){
if(rb==1) return "" + ra;
return ra + "/" + rb;
}
/*
public static void main() {
Rational a = new Rational(1, 3);
Rational b = new Rational(1, 4);
Rational c = a.add(b);
System.out.println(c);
}
*/
}
//检验测试
class Main5{
public static void main(String[] args) {
Rational a = new Rational(1, 2);
Rational b = new Rational(1, 4);
Rational c = a.add(b);
System.out.println(c);
//Rational.main();
}
}
第六题
/**
* 一般的排序有许多经典算法,如快速排序、希尔排序等。
但实际应用时,经常会或多或少有一些特殊的要求。我们没必要套用那些经典算法,可以根据实际情况建立更好的解法。
比如,对一个整型数组中的数字进行分类排序:
使得负数都靠左端,正数都靠右端,0在中部。注意问题的特点是:负数区域和正数区域内并不要求有序。可以利用这个特点通过1次线性扫描就结束战斗!!
如果给定数组:
25,18,-2,0,16,-5,33,21,0,19,-16,25,-3,0
则排序后为:
-3,-2,-16,-5,0,0,0,21,19,33,25,16,18,25
*/
package lanqiao13;
public class Main6 {
public static void main(String[] args) {
int[] x = {25,18,-2,0,16,-5,33,21,0,19,-16,25,-3,0};
Test.sort(x);
for(int i=0;i<=x.length;i++) {
System.out.print(x[i]+" ");
}
}
}
class Test{
static void sort(int[] x)
{
int p = 0;
int left = 0;//下标
int right = x.length-1;//最大下标
while(p<=right){
if(x[p]<0){
//元素大于0,将元素和left交换
int t = x[left];
x[left] = x[p];
x[p] = t;
left++;
p++;
//实质x[p] = x[left],x[p]到x[left],若x[p]<0,x[p]从左到右排
}
else if(x[p]>0){
//元素小于0,将元素和right交换
int t = x[right];
x[right] = x[p];
x[p] = t;
right--;//x[p]和 right--之后的x[right]进行交换,以此保证右边是正的
}
else{
//元素=0,不交换位置
p++; //代码填空位置
}
}
}
}