蓝桥日记①2017第八届省赛(软件类)JavaA组❤️答案解析

Posted 白鳯

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了蓝桥日记①2017第八届省赛(软件类)JavaA组❤️答案解析相关的知识,希望对你有一定的参考价值。

【蓝桥日记①】2017第八届省赛(软件类)JavaA组❤️答案解析

文章目录


题目链接:第八届蓝桥杯大赛个人赛省赛(软件类)Java大学A组

官网题库中搜索相应题目

A、迷宫

考点:dfs

package eightSession;
import java.util.*;
/***
 * 2017年 JavaA
 * 迷宫
 *  ***/

public class A 
    public static void main(String[] args) 
        String[] grids =  "UDDLUULRUL", "UURLLLRRRU", "RRUURLDLRD", "RUDDDDUUUU", "URUDLLRRUU",
                "DURLRLDLRL", "ULLURLLRDU", "RDLULLRDDD", "UUDDUDUDLL", "ULRDLUURRR" ;
        char[][] gs = new char[10][10];
        for (int i = 0; i < 10; i++) 
            for (int j = 0; j < 10; j++) 
                gs[i][j] = grids[i].charAt(j);
            
        

        int res = 0;
        for (int i = 0; i < 10; i++) 
            for (int j = 0; j < 10; j++) 
                boolean[] marks = new boolean[100];
                if (dfs(gs, i, j, marks)) res++;
            
        
        System.out.println(res);
    

    private static boolean dfs(char[][] gs, int r, int c, boolean[] marks) 
        if (r < 0 || c < 0 || r >= 10 || c >= 10) return true;
        if (marks[r * 10 + c]) return false;
        marks[r * 10 + c] = true;
        if (gs[r][c] == 'U') 
            return dfs(gs, r - 1, c, marks);
         else if (gs[r][c] == 'D') 
            return dfs(gs, r + 1, c, marks);
         else if (gs[r][c] == 'L') 
            return dfs(gs, r, c - 1, marks);
         else 
            return dfs(gs, r, c + 1, marks);
        
    


答案: 31


B、9数算式

考点:全排列+组合枚举

package eightSession;
import java.util.*;

/***
 * 2017年 JavaA
 * 9数算式
 *  ***/

public class B 
    static int[] a = 1, 2, 3, 4, 5, 6, 7, 8, 9;
    static int res = 0;

    public static void main(String[] args) 
        backtrack(0);
        res /= 2;
        System.out.println(res);
    

    private static void backtrack(int k) 
        if (k == a.length) 
            int x1 = 0, x2 = 0, y = 0;
            for (int i = 0; i < a.length; i++) 
                x1 = x1 * 10 + a[i];
                x2 = 0;
                for (int j = i + 1; j < a.length; j++) 
                    x2 = x2 * 10 + a[j];
                
                y = x1 * x2;
                if (check(y)) res++;
            
            return;
        
        for (int i = k; i < a.length; i++) 
            int t = a[k]; a[k] = a[i]; a[i] = t;
            backtrack(k + 1);
            t = a[k]; a[k] = a[i]; a[i] = t;
        
    

    private static boolean check(int num) 
        int cnt = 0;
        boolean[] mark = new boolean[10];
        while (num > 0) 
            int x = num % 10;
            if (x == 0 || mark[x] == true) 
                return false;
            
            mark[x] = true;
            cnt++;
            num /= 10;
        
        return cnt == 9;
    

答案:1625


C、魔方状态

考点:排列组合和群

方法一:队列模拟

将块和面编号,使用队列模拟,每个状态通过如下旋转产生三个状态

  • 上层块顺时针旋转
  • 右层块顺时针旋转
  • 前层块顺时针旋转

新生成的状态通过哈希去重考虑是否加入队列

package eightSession;
import java.util.*;

/***
 * 2017年 JavaA
 * 魔方状态
 *  ***/

/***
 * 上层逆时针 0 1 2 3
 * 下层逆时针 4 5 6 7
 * o橙色 g绿色 y黄色 x无色
 * 对于每一个小块 前后上下右左 表示为 0 5 1 3 2 4
 * ***/

public class C 
    static char[][] start = 
            "oyxxgx".toCharArray(),
            "oygxxx".toCharArray(),
            "xygxxy".toCharArray(),
            "xyxxgy".toCharArray(),
            "oxxogx".toCharArray(),
            "oxgoxx".toCharArray(),
            "xxgoxy".toCharArray(),
            "xxxogy".toCharArray()
    ;
    // 若是正常二阶魔方,队列q需改为4000000
    static char[][][] q = new char[2000000][8][6];
    static Set<String> all_state = new HashSet<>();
    static int front, tail;

    private static String to_string(char[][] s) 
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < 8; i++) 
            for (int j = 0; j < 6; j++) 
                sb.append(s[i][j]);
            
        
        return sb.toString();
    

    private static void swap(char[] a, int i, int j) 
        char t = a[i];
        a[i] = a[j];
        a[j] = t;
    

    private static void swap(char[][] s, int i, int j) 
        char[] t = s[i];
        s[i] = s[j];
        s[j] = t;
    

    // 上层块的旋转,面的相对位置调换
    private static void ucell(char[] a) 
        swap(a, 0, 2);
        swap(a, 2, 5);
        swap(a, 5, 4);
    

    // 上层顺时针旋转
    private  static void u(char[][] s) 
        ucell(s[0]);
        ucell(s[1]);
        ucell(s[2]);
        ucell(s[3]);
        // 块的相对位置调换
        swap(s, 0, 1);
        swap(s, 1, 2);
        swap(s, 2, 3);
    

    // 右层块的旋转,面的相对位置调换
    private static void rcell(char[] a) 
        swap(a, 0, 1);
        swap(a, 0, 3);
        swap(a, 3, 5);
    

    // 右层顺时针旋转
    private static void r(char[][] s) 
        rcell(s[1]);
        rcell(s[2]);
        rcell(s[5]);
        rcell(s[6]);
        // 块的相对位置调换
        swap(s, 1, 2);
        swap(s, 1, 5);
        swap(s, 5, 6);
    

    // 前层块的旋转,面的相对位置调换
    private static void fcell(char[] a) 
        swap(a, 1, 2);
        swap(a, 1, 4);
        swap(a, 3, 4);
    

    // 前层顺时针旋转
    private static void f(char[][] s) 
        fcell(s[0]);
        fcell(s[1]);
        fcell(s[4]);
        fcell(s[5]);
        // 块的相对位置调换
        swap(s, 0, 1);
        swap(s, 0, 4);
        swap(s, 4, 5);
    

    // 从整个魔方顶部看,顺时针转, 用于判重
    private static void uwhole(char[][] s) 
        u(s);
        // 下层旋转
        ucell(s[4]);
        ucell(s[5]);
        ucell(s[6]);
        ucell(s[7]);
        swap(s, 4, 5);
        swap(s, 5, 6);
        swap(s, 6, 7);
    

    // 从整个魔方右侧看,顺时针转,用于判重
    private static void rwhole(char[][] s) 
        r(s);
        // 左层旋转
        rcell(s[0]);
        rcell(s[3]);
        rcell(s[4]);
        rcell(s[7]);
        swap(s, 0, 3);
        swap(s, 0, 4);
        swap(s, 4, 7);
    

    // 从整个魔方前面看,顺时针转,用于判重
    private static void fwhole(char[][] s) 
        f(s);
        // 后层旋转
        fcell(s[2]);
        fcell(s[3]);
        fcell(s[6]);
        fcell(s[7]);
        swap(s, 3, 2);
        swap(s, 3, 7);
        swap(s, 6, 7);
    

    private static boolean try_insert(char[][] s) 
        char[][] cur = new char[8][6];
        memcpy(cur, s);
        for (int i = 0; i < 4; i++) 
            fwhole(cur);
            for (int j = 0; j < 4; j++) 
                rwhole(cur);
                for (int k = 0; k < 4; k++) 
                    uwhole(cur);
                    if (all_state.contains(to_string(cur))) 
                        return false;
                    
                
            
        
        all_state.add(to_string(s));
        return true;
    

    private static void memcpy(char[][] news, char[][] s) 
        for (int i = 0; i < 8; i++) 
            for (int j = 0; j < 6; j++) 
                news[i]以上是关于蓝桥日记①2017第八届省赛(软件类)JavaA组❤️答案解析的主要内容,如果未能解决你的问题,请参考以下文章

蓝桥日记③2016第七届省赛(软件类)JavaA组✿答案解析

第八届蓝桥杯(2017年)JavaA组省赛真题解析

蓝桥日记⑤2014第五届省赛(软件类)JavaA组❆答案解析

蓝桥日记④2015第六届省赛(软件类)JavaA组➤答案解析

蓝桥日记⑥2013第四届省赛(软件类)JavaA组@答案解析

第八届省赛程序设计题--电子钟程序设计蓝桥杯真题—03