• 49-2017年第八届蓝桥杯国赛试题及详解(Java本科B组)


    蓝桥杯历年真题题目及题解目录汇总推荐

    ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    2017年第八届蓝桥杯国赛试题及详解(Java本科B组)

    1. 结果填空 (满分17分)
    2. 结果填空 (满分45分)
    3. 代码填空 (满分23分)
    4. 程序设计(满分43分)
    5. 程序设计(满分71分)
    6. 程序设计(满分101分)

    1.标题:平方十位数

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

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

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

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

    思路:一开始以为直接最大值开根号取整+1就结束,但是不能重复啊

    代码:

    package lq2017_gs;
    /*
    1.标题:平方十位数
    由0~9这10个数字不重复、不遗漏,可以组成很多10位数字。
    这中也有很多恰好是平方数(是某个数的平方)。
    比如:1026753849,就是其中最小的一个平方数。
    请你找出其中最大的一个平方数是多少?
    注意:你需要提交的是一个10位数字,不要填写任何多余内容。
    */
    
    public class t1 {
    	public static void main(String[] args) {
    		long MAX = (int) Math.sqrt(9876543210.0); // int 9876543210超过了范围
    		for(long i = MAX; i >= 1; i--) {
    			int a[] = new int[10];
    			long x =  i * i;
    			int flag = 1;
    			while(x != 0) {
    				int y = (int) (x % 10);
    				if(a[y] == 0) {
    					a[y] = 1;
    				}
    				else {
    					flag = 0;
    					break;
    				}
    				x /= 10;
    			}
    			for(int j = 0; j < 10; j++) {
    				if(a[j] == 0) {
    					flag = 0;
    					break;
    				}
    			}
    			if(flag == 1) {
    				System.out.println(i);
    				System.out.println(i * i);
    				break;
    			}
    		}
    		
    	}
    }

    答案:9814072356

    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网格上推演,并非只有题目中画出的那点空间。
    当然,对于遥远的位置,其初始状态一概为死细胞。

    注意:需要提交的是一个整数,不要填写多余内容。
    ---------------------
     思路: 开始受题目引导,以为后面的不会变化,存在某种循环,但是一直没找到,其实应该从数量循环来着手,

    因为的位置可能会一直向某个方向偏移。分析数量时,直接观察后面每代的数量也不直观,要做差,得到相邻两

    天的增长数量,可以将得到的差值,放入excel绘制折线图,来直观的找周期。

    我找了前200代,第一列记录该代数量,第二列记录了比前一代增长的数量:

    将差值绘制折线图:

    可以直观的看到是周期分布的,结合表格可以确定周期为30代:

    故可以发现,每30代增长5个细胞。

    30内每代增长数量为:

    所以最终的答案就是: 1000000000 / 30 * 5 + (1000000000 % 30 )  12 = 166666713

     代码:

    package lq2017_gs;
    
    import java.util.Scanner;
    
    public class t2 {
    	
    	public static void main(String[] args) {
    		Scanner cin = new Scanner(System.in);
    		
    		String st = "23";
    		char[][] map = new char[1000][1000];
    		for(int i = 0; i < 1000; i++) {
    			for(int j = 0; j < 1000; j++) {
    				map[i][j] = '.';
    			}
    		}
    //		System.out.println(map[0][0]);
    		int p = 300;
    		for(int i = p; i < p + 11; i++) {
    			String s = cin.next();
    			System.out.println("sss---" + s + s.length());
    			for(int j = p; j < p + 38; j++) {
    				map[i][j] = s.charAt(j - p);
    			}
    		}
    		
    		int dx[] = {-1, -1, -1, 0, 0, 1, 1, 1};
    		int dy[] = {-1, 0, 1, -1, 1, -1, 0, 1};
    		
    		int t = 200;
    		int all = 0;
    		int ans1 = 36;
    		int ans2 = 0;
    		
    		while(t-- != 0) {
    //			System.out.println("------+++");
    			char[][] map2 = new char[1000][1000];
    			for(int i = 0; i < 1000; i++) {
    				for(int j = 0; j < 1000; j++) {
    					int f = 0;
    					for(int k = 0; k < 8; k++) {
    						int x = i + dx[k];
    						int y = j + dy[k];
    						if(x >= 0 && x < 1000 && y >= 0 && y < 1000) {
    							if(map[x][y] == 'X') {
    								f++;
    							}
    						}
    					}
    					if(map[i][j] == 'X') {
    						if(f < 2) {
    							map2[i][j] = '.';
    						}
    						else if(f == 2 || f == 3) {
    							map2[i][j] = 'X';
    						}
    						else{
    							map2[i][j] = '.';
    						}
    					}
    					else {
    						if(f == 3) {
    							map2[i][j] = 'X';
    						}
    						else {
    							map2[i][j] = '.';
    						}
    					}
    				}	
    			}
    			
    			ans2 = 0;
    			int flag = 1;
    			for(int i = 0; i < 1000; i++) {
    				for(int j = 0; j < 1000; j++) {
    					if(map2[i][j] == 'X') {
    						ans2++;
    					}
    				}
    			}
    //			System.out.println(ans2 - ans1); // 输出找规律
    			ans1 = ans2;
    			map = map2;
    		}
    		
    		// 通过分析得知响邻两天之间增长个数有规律,每个30天增长5个
    		int yuan = 36;  //
    		int now = 0;
    		int zs = 36 / 30;
    		int ys = 36 % 30;
    		System.out.println(zs + ", " + ys); 
    	
    		now = zs * 5 + yuan;  // 还要加上余数增长的个数
    		
    		System.out.println("now: " + (now + 12));  //166666713
    	}
    	
    }
    
    /*
     * 
     * ans = 9814072356
     * 
     * */
    

      

    3.标题:树形显示

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

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

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

    package lq2017_gs;
    
    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 t3
    {
    	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】

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

    s =  last_child(pa) == true ? space(5) + 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,否则按无效代码处理。
    ---------------------
     思路: 充分利用java的BigInteger。

    构造方法摘要
    BigInteger(byte[] val)
              将包含 BigInteger 的二进制补码表示形式的 byte 数组转换为 BigInteger。
    BigInteger(int signum, byte[] magnitude)
              将 BigInteger 的符号-数量表示形式转换为 BigInteger。
    BigInteger(int bitLength, int certainty, Random rnd)
              构造一个随机生成的正 BigInteger,它可能是一个具有指定 bitLength 的素数。
    BigInteger(int numBits, Random rnd)
              构造一个随机生成的 BigInteger,它是在 0(2numBits - 1)(包括)范围内均匀分布的值。
    BigInteger(String val)
              将 BigInteger 的十进制字符串表示形式转换为 BigInteger。
    BigInteger(String val, int radix)
              将指定基数的 BigInteger 的字符串表示形式转换为 BigInteger。

     

    方法摘要
      BigInteger abs()
              返回其值是此 BigInteger 的绝对值的 BigInteger。
     BigInteger add(BigInteger val)
              返回其值为 (this + val) 的 BigInteger。
     BigInteger and(BigInteger val)
              返回其值为 (this & val) 的 BigInteger。
     BigInteger andNot(BigInteger val)
              返回其值为 (this & ~val) 的 BigInteger。
     int bitCount()
              返回此 BigInteger 的二进制补码表示形式中与符号不同的位的数量。
     int bitLength()
              返回此 BigInteger 的最小的二进制补码表示形式的位数,不包括 符号位。
     BigInteger clearBit(int n)
              返回其值与清除了指定位的此 BigInteger 等效的 BigInteger。
     int compareTo(BigInteger val)
              将此 BigInteger 与指定的 BigInteger 进行比较。
     BigInteger divide(BigInteger val)
              返回其值为 (this / val) 的 BigInteger。
     BigInteger[] divideAndRemainder(BigInteger val)
              返回包含 (this / val) 后跟 (this % val) 的两个 BigInteger 的数组。
     double doubleValue()
              将此 BigInteger 转换为 double
     boolean equals(Object x)
              比较此 BigInteger 与指定的 Object 的相等性。
     BigInteger flipBit(int n)
              返回其值与对此 BigInteger 进行指定位翻转后的值等效的 BigInteger。
     float floatValue()
              将此 BigInteger 转换为 float
     BigInteger gcd(BigInteger val)
              返回一个 BigInteger,其值是 abs(this)abs(val) 的最大公约数。
     int getLowestSetBit()
              返回此 BigInteger 最右端(最低位)1 比特的索引(即从此字节的右端开始到本字节中最右端 1 比特之间的 0 比特的位数)。
     int hashCode()
              返回此 BigInteger 的哈希码。
     int intValue()
              将此 BigInteger 转换为 int
     boolean isProbablePrime(int certainty)
              如果此 BigInteger 可能为素数,则返回 true,如果它一定为合数,则返回 false
     long longValue()
              将此 BigInteger 转换为 long
     BigInteger max(BigInteger val)
              返回此 BigInteger 和 val 的最大值。
     BigInteger min(BigInteger val)
              返回此 BigInteger 和 val 的最小值。
     BigInteger mod(BigInteger m)
              返回其值为 (this mod m) 的 BigInteger。
     BigInteger modInverse(BigInteger m)
              返回其值为 (this-1 mod m) 的 BigInteger。
     BigInteger modPow(BigInteger exponent, BigInteger m)
              返回其值为 (thisexponent mod m) 的 BigInteger。
     BigInteger multiply(BigInteger val)
              返回其值为 (this * val) 的 BigInteger。
     BigInteger negate()
              返回其值是 (-this) 的 BigInteger。
     BigInteger nextProbablePrime()
              返回大于此 BigInteger 的可能为素数的第一个整数。
     BigInteger not()
              返回其值为 (~this) 的 BigInteger。
     BigInteger or(BigInteger val)
              返回其值为 (this | val) 的 BigInteger。
     BigInteger pow(int exponent)
              返回其值为 (thisexponent) 的 BigInteger。
    static BigInteger probablePrime(int bitLength, Random rnd)
              返回有可能是素数的、具有指定长度的正 BigInteger。
     BigInteger remainder(BigInteger val)
              返回其值为 (this % val) 的 BigInteger。
     BigInteger setBit(int n)
              返回其值与设置了指定位的此 BigInteger 等效的 BigInteger。
     BigInteger shiftLeft(int n)
              返回其值为 (this << n) 的 BigInteger。
     BigInteger shiftRight(int n)
              返回其值为 (this >> n) 的 BigInteger。
     int signum()
              返回此 BigInteger 的正负号函数。
     BigInteger subtract(BigInteger val)
              返回其值为 (this - val) 的 BigInteger。
     boolean testBit(int n)
              当且仅当设置了指定的位时,返回 true
     byte[] toByteArray()
              返回一个 byte 数组,该数组包含此 BigInteger 的二进制补码表示形式。
     String toString()
              返回此 BigInteger 的十进制字符串表示形式。
     String toString(int radix)
              返回此 BigInteger 的给定基数的字符串表示形式。
    static BigInteger valueOf(long val)
              返回其值等于指定 long 的值的 BigInteger。
     BigInteger xor(BigInteger val)
              返回其值为 (this ^ val) 的 BigInteger。

    code:

    package lq2017_gs;
    
    import java.math.BigInteger;
    import java.util.Scanner;
    
    public class t4 {
    	public static void main(String[] args) {
    		Scanner cin = new Scanner(System.in);
    //		int n = cin.nextInt();
    		int n = Integer.parseInt(cin.nextLine().trim());
    		int nowRadix = 10;
    		String num = "";   // 存放数字
    		String ins = "";   // 存放当前进制
    		while(n-- != 0) {
    			String nowline = cin.nextLine().trim();
    			if(nowline.contains(" ")) {
    				String pre = nowline.split(" ")[0];
    				String last = nowline.split(" ")[1];
    				if(pre.equals("NUM")) {
    					if(ins.equals("ADD")) {
    						if(nowRadix == 10) {
    							num = new BigInteger(num).add(new BigInteger(last)).toString();
    						}
    						else {
    							num = new BigInteger(num, nowRadix).add(new BigInteger(last, nowRadix)).toString(nowRadix);
    						}
    					}
    					else if(ins.equals("SUB")) {
    						if(nowRadix == 10) {
    							num = new BigInteger(num).subtract(new BigInteger(last)).toString();
    						}
    						else {
    							num = new BigInteger(num, nowRadix).subtract(new BigInteger(last, nowRadix)).toString(nowRadix);
    						}
    					}
    					else if(ins.equals("MUL")) {
    						if(nowRadix == 10) {
    							num = new BigInteger(num).multiply(new BigInteger(last)).toString();
    						}
    						else {
    							num = new BigInteger(num, nowRadix).multiply(new BigInteger(last, nowRadix)).toString(nowRadix);
    						}
    					}
    					else if(ins.equals("DIV")) {
    						if(nowRadix == 10) {
    							num = new BigInteger(num).divide(new BigInteger(last)).toString();
    						}
    						else {
    							num = new BigInteger(num, nowRadix).divide(new BigInteger(last, nowRadix)).toString(nowRadix);
    						}
    					}
    					else if(ins.equals("MOD")) {
    						if(nowRadix == 10) {
    							num = new BigInteger(num).mod(new BigInteger(last)).toString();
    						}
    						else {
    							num = new BigInteger(num, nowRadix).mod(new BigInteger(last, nowRadix)).toString(nowRadix);
    						}
    					}
    					else {
    						num = last;
    					}
    				}
    				else if(pre.equals("CHANGE")){
    					if(nowRadix != Integer.parseInt(last)) {
    						num = new BigInteger(num, nowRadix).toString();
    						nowRadix = Integer.valueOf(last);
    						num = new BigInteger(num).toString(nowRadix);
    					}
    				}
    			}
    			else {
    				if(nowline.equals("CLEAR")) {
    					num = "";
    				}
    				else if(nowline.equals("EQUAL")) {
    //					System.out.println("test-equal");
    					System.out.println(num);
    				}
    				else if(nowline.equals("ADD")){
    					ins = "ADD";
    				}
    				else {
    //					System.out.println("test: " + nowline);
    					System.out.println("指令错误!");
    				}
    			}
    			
    		}
    		
    	}
    }
    

      

    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,否则按无效代码处理。
    ---------------------
    思路: 模拟吧。

    注意:string 不好改变某个位置的值,而stringBuilder可以,但是stringBuilder传参数传的引用,所以会改变原来的值,

    故在使用的时候要先copy一份!!!copy的方法不能只直接对象赋值,那样没用。

    package lq2017_gs;
    
    import java.util.Scanner;
    
    public class t5 {
    
    	public static void main(String[] args) {
    		Scanner cin = new Scanner(System.in);
    		int n = Integer.parseInt(cin.nextLine().trim());
    		while(n-- != 0) {
    			StringBuilder str = new StringBuilder(cin.nextLine());
    			
    			int ans = dfs(1, str);
    			
    			System.out.println(ans);
    		}
    		
    	}
    	
    	public static int dfs(int f, StringBuilder st) {
    		// 注意注意!!!st为引用对象,直接修改会改变原来的值!!!得copy一份!!!
    		StringBuilder str = new StringBuilder(st.toString());
    		// 判断比赛结果
    		if(str.indexOf("LOL") != -1) {
    			return -1; // 现在下的人输了
    		}
    		if(str.indexOf("*") == -1) {
    			return 0;  // 平棋
    		}
    		// 不同对象下子,都要达到利益最大化
    		int len = str.length();
    		int p = -1; // 标记是否能平棋
    		for(int i = 0; i < len; i++) {
    			if(str.charAt(i) == '*') { // 空格可以下子
    				// 尝试第一种下法
    				str.setCharAt(i, 'L'); 
    				int ans = dfs(-f, str);
    				if(ans == -1) { // 对方输了我就赢了
    					return 1;
    				}
    				else if(ans == 0) {
    					p = i;
    				}
    				// 第一种没赢的话就尝试第二种下法
    				str.setCharAt(i, 'O'); 
    				ans = dfs(-f, str);
    				if(ans == -1) {
    					return 1;
    				}
    				else if(ans == 0) {
    					p = i;
    				}
    				str.setCharAt(i, '*');
    			}
    		}
    		if(p == -1) {
    			return -1; // 不能赢和平就是输
    		}
    		else {
    			return 0;
    		}
    	}
    }
    
    /*
    4
    ***
    L**L
    L**L***L
    L*****L
    */
    

      

  • 相关阅读:
    MyBatis:分页的实现
    Mybatis之配置文件
    Java之创建线程的方式四:使用线程池
    Java之创建线程的方式三:实现Callable接口
    Java之线程通信的应用:经典例题:生产者/消费者问题
    Java之线程通信的方法
    Java之解决线程安全问题的方式三:Lock锁
    Java之同步方法处理实现Runnable接口的线程安全问题
    Java之同步方法处理继承Thread类的线程安全问题
    01 while 循环输入1 2 3 4 5 6 8 9 10
  • 原文地址:https://www.cnblogs.com/zhumengdexiaobai/p/10807181.html
Copyright © 2020-2023  润新知