第八届蓝桥杯真题决赛java本科组

1 平方十位数

由0~9这10个数字不重复、不遗漏,可以组成很多10位数字。
这其中也有很多恰好是平方数(是某个数的平方)。

比如:1026753849,就是其中最小的一个平方数。

请你找出其中最大的一个平方数是多少?

注意:你需要提交的是一个10位数字,不要填写任何多余内容。
 

  • 代码
/**
*@author 杨雨婷
*@date 2019年5月23日
*/
package one_平方十位数;
 
//全排列
public class Main {
    static int a[] = {0,1, 2, 3, 4, 5, 6, 7, 8, 9};
    static long max = 0;
	public static void main(String[] args) {
		 
        dfs(0);
        System.out.println(max);
	}
	private static void dfs(int n) {
		//剪枝
		if(n == 10) {
			long t = f();
			if((long)Math.sqrt(t) * (long)Math.sqrt(t) == t) {
				if(t > max ) {
					max = t;
				}
			}
			return;
		}
		//下一跳
		for(int i = n; i < 10; i ++) {
			swap(i, n);
			dfs(n + 1);
			swap(i, n);
		}
	}
	private static long f() {
		long t = 0;
		for(int i = 0; i < 10; i ++) {
			t = t * 10 + a[i];
		}
		
		return t;
	}
	private static void swap(int i, int n) {
		int t = a[i];
		a[i] = a[n];
		a[n] = t;
	}

}
  • 答案

9814072356

  • 分析 

其实也就是全排列。此外,还可以对函数进行优化,让数组起初从9到0排列。当遇到平方数就输出既是最大数。

 

2 生命游戏

康威生命游戏是英国数学家约翰·何顿·康威在1970年发明的细胞自动机。  
这个游戏在一个无限大的2D网格上进行。

初始时,每个小方格中居住着一个活着或死了的细胞。
下一时刻每个细胞的状态都由它周围八个格子的细胞状态决定。

具体来说:

1. 当前细胞为存活状态时,当周围低于2个(不包含2个)存活细胞时, 该细胞变成死亡状态。(模拟生命数量稀少)
2. 当前细胞为存活状态时,当周围有2个或3个存活细胞时, 该细胞保持原样。
3. 当前细胞为存活状态时,当周围有3个以上的存活细胞时,该细胞变成死亡状态。(模拟生命数量过多)
4. 当前细胞为死亡状态时,当周围有3个存活细胞时,该细胞变成存活状态。 (模拟繁殖)

当前代所有细胞同时被以上规则处理后, 可以得到下一代细胞图。按规则继续处理这一代的细胞图,可以得到再下一代的细胞图,周而复始。

例如假设初始是:(X代表活细胞,.代表死细胞)
.....
.....
.XXX.
.....

下一代会变为:
.....
..X..
..X..
..X..
.....

康威生命游戏中会出现一些有趣的模式。例如稳定不变的模式:

....
.XX.
.XX.
....

还有会循环的模式:

......      ......       ......
.XX...      .XX...       .XX...
.XX...      .X....       .XX...
...XX.   -> ....X.  ->   ...XX.
...XX.      ...XX.       ...XX.
......      ......       ......


本题中我们要讨论的是一个非常特殊的模式,被称作"Gosper glider gun":

......................................
.........................X............
.......................X.X............
.............XX......XX............XX.
............X...X....XX............XX.
.XX........X.....X...XX...............
.XX........X...X.XX....X.X............
...........X.....X.......X............
............X...X.....................
.............XX.......................
......................................

假设以上初始状态是第0代,请问第1000000000(十亿)代一共有多少活着的细胞?

注意:我们假定细胞机在无限的2D网格上推演,并非只有题目中画出的那点空间。
当然,对于遥远的位置,其初始状态一概为死细胞。

注意:需要提交的是一个整数,不要填写多余内容。
 

  • 代码
/**
*@author 杨雨婷
*@date 2019年5月23日
*/
package two_生命游戏;
 
public class Main {
	static String str = ".............................................................."
			+".............................................................."
			+".............................................................."
			+".............................................................."
			+".............................................................."
			+".............................................................."
			+".............................................................."
			+".............................................................."
			+".....................................X........................"
			+"...................................X.X........................"
			+".........................XX......XX............XX............."
			+"........................X...X....XX............XX............."
			+".............XX........X.....X...XX..........................."
			+".............XX........X...X.XX....X.X........................"
			+".......................X.....X.......X........................"
			+"........................X...X................................."
			+".........................XX..................................."
			+".............................................................."
			+".............................................................."
			+".............................................................."
			+".............................................................."
			+".............................................................."
			+".............................................................."
			+".............................................................."
			+"..............................................................";
	
/*	static String str = "....."
			+"....."
			+".XXX."
			+".....";*/
	static int nc = +"..............................................................".length(), nl = 25,
			a[] = new int[1000000], T = 1, add[] = new int[100000];
	static char map[][] = new char[nl][nc];
	static char b[][] = new char[nl][nc];
	static char c[][] = new char[nl][nc];
	static int dir[][] = {{1, 0}, {-1, 0}, {0, 1}, {0 , -1}, {1, 1}, {1, -1}, {-1, 1}, {-1, -1}};

	public static void main(String[] args) {
         for(int i = 0; i < nl; i ++) {
        	 map[i] = str.substring(nc * i, (i + 1) * nc).toCharArray();
         }
         
         int num = 0;
         for(int i = 0; i < nl; i ++) {
        	 for(int j = 0; j < nc; j ++) {
        		// System.out.print(map[i][j]);
        		 b[i][j] = map[i][j];
        		 if(map[i][j] == 'X')num ++;
        	 }
        	 //System.out.println();
         }
         a[0] = num;
         f(1);
        // System.out.println("T:" + T);
         System.out.println();
         for(int i = 0; i < 100; i ++) {
        	 System.out.print(  add[i]+ " ");
         }
         System.out.println();
         String[] ch = "3 4 5 3 -7 7 -3 13 -19 6 2 4 1 1 -14 2 3 6 1 0 0 -5 11 -17 7 -3 0 3 -2 -7".split(" ");
         int len = ch.length;
         System.out.println(len);
         int zhouqi = 1000000000 / len;
         int d = 1000000000 % len;
         int start = a[0];
         int sum = a[0];
         for(int i = 0; i < zhouqi; i ++) {
        	 for(int j = 0; j < len; j ++) {
        		 sum += add[j]; 
        	 }
         }
         for(int i = 0; i < d; i ++) {
        	 sum += add[i]; 
         }
         System.out.println(sum);
	}


	private static void f(int n) {
		 
		int num = 0;
		//System.out.print(n +":");
		if(n % 2 == 1) {
			for(int i = 0; i < nl; i ++) {
	        	 for(int j = 0; j < nc; j ++) {
	        		 c[i][j] = deal(n, i, j);
	        		 if(c[i][j] == 'X') {
	        			 //System.out.println("X");
	        			 num ++;
	        		 }
	        		 
	        	 }
	        }
			/*for(int i = 0; i < nl; i ++) {
	        	 for(int j = 0; j < nc; j ++) {
	        		 System.out.print(c[i][j]);
	        		
	        	 }
	        	 System.out.println();
	         }*/
		}
		else {
			for(int i = 0; i < nl; i ++) {
	        	 for(int j = 0; j < nc; j ++) {
	        		 b[i][j] = deal(n, i, j);
	        		 if(b[i][j] == 'X') {
	        			 num ++;
	        		     
	        		 }
	        		 
	        	 }
	         }
			/*for(int i = 0; i < nl; i ++) {
	        	 for(int j = 0; j < nc; j ++) {
	        		 System.out.print(b[i][j]);
	        		 
	        	 }
	        	 System.out.println();
	         }*/
		}
		a[n] = num;
		add[n - 1] = a[n] - a[n - 1];
		int t = ( n + 1 )/ 2;
		for(int i = 0; i <( n + 1 )/ 2; i ++) {
			if(n == 0) {
				System.out.println(add[i]);
				System.out.println(add[t]);
			}
			if(add[i] != add[t])break;
			
			if(i == ( n + 1 )/ 2 - 1) {				 
				T = ( n + 1 )/ 2;
			}
			t ++;
		}
		if(n == 100)return; 
	    f(n + 1);
	 
	}


	private static char deal(int n, int lt, int ct) {
		char t = '.';
		if(n % 2 == 1) {
			int numt = 0;
			for(int i = 0; i < 8; i ++) {
				int x = lt + dir[i][0];
				int y = ct + dir[i][1];
				if(in(x, y) && b[x][y] == 'X') numt ++;
			}
			if(b[lt][ct] == 'X') {
				
				if(numt == 2 || numt == 3) t = 'X';
				 
			}
			else {
				if(numt == 3)t = 'X';
			}
		}
		else {
			int numt = 0;
			for(int i = 0; i < 8; i ++) {
				int x = lt + dir[i][0];
				int y = ct + dir[i][1];
				if(in(x, y) && c[x][y] == 'X') numt ++;
			}
			if(c[lt][ct] == 'X') {
				
				if(numt == 2 || numt == 3) t = 'X';
				 
			}
			else {
				if(numt == 3)t = 'X';
			}
		}
		return t;
	}


	private static boolean in(int x, int y) {
		if(x >= 0 && x < nl && y >= 0 && y < nc) {
			return true;
		}
		return false;
	}

}
  • 答案

运行结果:

3 4 5 3 -7 7 -3 13 -19 6 2 4 1 1 -14 2 3 6 1 0 0 -5 11 -17 7 -3 0 3 -2 -7 3 4 5 3 -7 7 -3 13 -19 6 2 4 1 1 -14 2 3 6 1 0 0 -6 10 -16 7 -3 0 3 -2 -7 3 4 5 3 -7 7 -3 13 -19 6 2 6 -4 -2 -17 2 3 6 1 0 0 -5 11 -17 7 -3 0 3 -2 -7 3 4 5 3 -7 7 -3 13 -19 6 
30
166666713

166666713

  • 分析

首先我最初错的地方是因为细胞可扩展,企图找到活细胞个数周期。其实正常情况下的细胞总体效果会增多。那么就应该找到他的递增的周期。有一点要注意的是要将定义细胞扩展范围越大越好。递增周期其实也不应该顾虑后面太多,应为细胞扩展到我们定义范围之外我们并没有计算。所以说我们只需要找到前面大部分有规律的周期即可。

 

3 树形显示

 

对用树形来形象于分类结构可以地表示。比如:文件系统就是典型的例子。

树中的结点具有父子关系。我们在显示的时候,把子项向右缩进(用空格,不是tab),并添加必要的连接线,以使其层次关系更醒目。

下面的代码就是为了这个目的的,请仔细阅读源码,并填写划线部分缺少的代码。

import java.util.*;
 
class MyTree
{
	private Map<String, List<String>>  map_ch = new HashMap<String, List<String>>();
	private Map<String,String> map_pa = new HashMap<String,String>();
	
	public void add(String parent, String child)
	{
		map_pa.put(child, parent);
		
		List<String> lst = map_ch.get(parent);
		if(lst==null){
			lst = new ArrayList<String>();
			map_ch.put(parent, lst);
		}
		lst.add(child);
	}
	
	public String get_parent(String me){
		return map_pa.get(me);
	}
	
	public List<String> get_child(String me){
		return map_ch.get(me);
	}
	
	private String space(int n)
	{
		String s = "";
		for(int i=0; i<n; i++) s += ' ';
		return s;
	}
	
	private boolean last_child(String x){
		String pa = map_pa.get(x);
		if(pa==null) return true;
		
		List<String> lst = map_ch.get(pa);
		return lst.get(lst.size()-1).equals(x);
	}
	
	public void show(String x){
		
		String s = "+--" + x;
		
		String pa = x;
		while(true){
			pa = map_pa.get(pa);
			if(pa==null) break;
			s = ___________________________________ ;  // 填空
		}
		
		System.out.println(s);
	}
	
	public void dfs(String x){
		show(x);
		
		List<String> lst = map_ch.get(x);
		if(lst==null) return;
				
		for(String it: lst){
			dfs(it);
		}
	}
}
 
public class TreeView
{
	public static void main(String[] args)
	{
		MyTree tree = new MyTree();
		tree.add("root", "dog");
		tree.add("root", "cat");
		tree.add("root", "duck");
		tree.add("dog", "AAdog");
		tree.add("dog", "BBdog");
		tree.add("dog", "CCdog");
		tree.add("AAdog", "AAdog01");
		tree.add("AAdog", "AAdog02");
		tree.add("cat", "XXcat");
		tree.add("cat", "YYcat");
		tree.add("XXcat","XXcat-oo");
		tree.add("XXcat","XXcat-qq");
		tree.add("XXcat-qq", "XXcat-qq-hahah");
		tree.add("duck", "TTduck");
		tree.add("TTduck", "TTduck-001");
		tree.add("TTduck", "TTduck-002");
		tree.add("TTduck", "TTduck-003");
		tree.add("YYcat","YYcat.hello");
		tree.add("YYcat","YYcat.yes");
		tree.add("YYcat","YYcat.me");		
		
		tree.dfs("root");
	}
}


 

对于题目中的测试数据,输出结果:
+--root
     +--dog
     |    +--AAdog
     |    |    +--AAdog01
     |    |    +--AAdog02
     |    +--BBdog
     |    +--CCdog
     +--cat
     |    +--XXcat
     |    |    +--XXcat-oo
     |    |    +--XXcat-qq
     |    |         +--XXcat-qq-hahah
     |    +--YYcat
     |         +--YYcat.hello
     |         +--YYcat.yes
     |         +--YYcat.me
     +--duck
          +--TTduck
               +--TTduck-001
               +--TTduck-002
               +--TTduck-003
               
如有平字体对齐问题,可以参见图【p1.png】

注意,只填写划线部分缺少的代码,不要抄写已有的代码或符号。
 

  •  答案

last_child(pa)? (" " + (space(4) + s )) :("|" + (space(4) + s ) )

  • 分析 

这题无套路可言,只有一步步弄懂各个变量的用处,各个函数的用处才能调试出正确的代码 

 

4 小计算器

模拟程序型计算器,依次输入指令,可能包含的指令有

1. 数字:'NUM X',X为一个只包含大写字母和数字的字符串,表示一个当前进制的数
2. 运算指令:'ADD','SUB','MUL','DIV','MOD',分别表示加减乘,除法取商,除法取余
3. 进制转换指令:'CHANGE K',将当前进制转换为K进制(2≤K≤36)
4. 输出指令:'EQUAL',以当前进制输出结果
5. 重置指令:'CLEAR',清除当前数字

指令按照以下规则给出:
数字,运算指令不会连续给出,进制转换指令,输出指令,重置指令有可能连续给出
运算指令后出现的第一个数字,表示参与运算的数字。且在该运算指令和该数字中间不会出现运算指令和输出指令
重置指令后出现的第一个数字,表示基础值。且在重置指令和第一个数字中间不会出现运算指令和输出指令
进制转换指令可能出现在任何地方

运算过程中中间变量均为非负整数,且小于2^63。
以大写的'A'~'Z'表示10~35

[输入格式]
第1行:1个n,表示指令数量
第2..n+1行:每行给出一条指令。指令序列一定以'CLEAR'作为开始,并且满足指令规则

[输出格式]
依次给出每一次'EQUAL'得到的结果

[样例输入]
7
CLEAR
NUM 1024
CHANGE 2
ADD
NUM 100000
CHANGE 8
EQUAL

[样例输出]
2040

补充说明:
1. n 值范围: 1<= n < 50000
2. 初始默认的进制是十进制

资源约定:
峰值内存消耗 < 256M
CPU消耗  < 1000ms


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

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

 

5 填字母游戏 

小明经常玩 LOL 游戏上瘾,一次他想挑战K大师,不料K大师说:
“我们先来玩个空格填字母的游戏,要是你不能赢我,就再别玩LOL了”。

K大师在纸上画了一行n个格子,要小明和他交替往其中填入字母。

并且:

1. 轮到某人填的时候,只能在某个空格中填入L或O
2. 谁先让字母组成了“LOL”的字样,谁获胜。
3. 如果所有格子都填满了,仍无法组成LOL,则平局。

小明试验了几次都输了,他很惭愧,希望你能用计算机帮他解开这个谜。

本题的输入格式为:
第一行,数字n(n<10),表示下面有n个初始局面。
接下来,n行,每行一个串,表示开始的局面。
  比如:“******”, 表示有6个空格。
  “L****”,   表示左边是一个字母L,它的右边是4个空格。

要求输出n个数字,表示对每个局面,如果小明先填,当K大师总是用最强着法的时候,小明的最好结果。
1 表示能赢
-1 表示必输
0 表示可以逼平


例如,
输入:
4
***
L**L
L**L***L
L*****L

则程序应该输出:
0
-1
1
1

资源约定:
峰值内存消耗 < 256M
CPU消耗  < 1000ms


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

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

 

 

6 区间移位

数轴上有n个闭区间:D1,...,Dn。
其中区间Di用一对整数[ai, bi]来描述,满足ai < bi。
已知这些区间的长度之和至少有10000。
所以,通过适当的移动这些区间,你总可以使得他们的“并”覆盖[0, 10000]——也就是说[0, 10000]这个区间内的每一个点都落于至少一个区间内。
你希望找一个移动方法,使得位移差最大的那个区间的位移量最小。

具体来说,假设你将Di移动到[ai+ci, bi+ci]这个位置。你希望使得maxi{|ci|} 最小。

【输入格式】
输入的第一行包含一个整数n,表示区间的数量。
接下来有n行,每行2个整数ai, bi,以一个空格分开,表示区间[ai, bi]。
保证区间的长度之和至少是10000。

【输出格式】
输出一个数字,表示答案。如果答案是整数,只输出整数部分。如果答案不是整数,输出时四舍五入保留一位小数。

【样例输入】
2
10 5010
4980 9980

【样例输出】
20

【样例说明】
第一个区间往左移动10;第二个区间往右移动20。

【样例输入】
4
0 4000
3000 5000
5001 8000
7000 10000
【样例输出】
0.5
【样例说明】
第2个区间往右移0.5;第3个区间往左移0.5即可。

【数据规模与约定】
对于30%的评测用例,1 <= n <= 10;
对于100%的评测用例,1 <= n <= 10000,0 <= ai < bi <= 10000。

资源约定:
峰值内存消耗 < 256M
CPU消耗  < 2000ms


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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值