蓝桥杯训练营第二周作业

19201419曾宇杰


1. 带分数
问题描述
100 可以表示为带分数的形式:100 = 3 + 69258 / 714。
还可以表示为:100 = 82 + 3546 / 197。
注意特征:带分数中,数字 1~9 分别出现且只出现一次(不包含 0)。
类似这样的带分数,100 有 11 种表示法。
输入格式
从标准输入读入一个正整数 N (N<1000*1000)
输出格式
程序输出该数字用数码 1~9 不重复不遗漏地组成带分数表示的全部种数。
注意:不要求输出每个表示,只统计有多少表示法!
样例输入 1
100
样例输出 1
11
样例输入 2
105
样例输出 2
6
import java.util.Scanner;

public class Q1 {
    static int n, result;

    public static void main(String[] args) {

        Scanner sc = new Scanner(System.in);
        n = sc.nextInt();
        sc.close();

        int[] data = {1, 2, 3, 4, 5, 6, 7, 8, 9};
        allSort(data, 0);
        System.out.println(result);
    }

    private static int split(int[] data, int j, int k) {

        int num = 0;
        for (int i = j; i < k; i++) {
            num = data[i] + num * 10;
        }
        return num;
    }

    public static void allSort(int[] data, int i) {

        if (i == data.length) {

            for (int j = 1; j < data.length; j++) {
                for (int k = j + 1; k < data.length; k++) {
                    int pre = split(data, 0, j);
                    int mid = split(data, j, k);
                    int fon = split(data, k, 9);
                    if (mid % fon != 0)
                        continue;
                    if (pre + mid / fon == n)
                        result++;
                }
            }
            return;
        }

        for (int j = i; j < data.length; j++) {

            int temp = data[j];
            data[j] = data[i];
            data[i] = temp;

            allSort(data, i + 1);

            temp = data[j];
            data[j] = data[i];
            data[i] = temp;
        }
    }
}
2. 李白打酒
题目描述
话说大诗人李白,一生好饮。幸好他从不开车。
一天,他提着酒壶,从家里出来,酒壶中有酒 2 斗。他边走边唱:
无事街上走,提壶去打酒。
逢店加一倍,遇花喝一斗。
这一路上,他一共遇到店 5 次,遇到花 10 次,已知最后一次遇到的是花,他正
好把酒喝光了。
请你计算李白遇到店和花的次序,可以把遇店记为 a,遇花记为 b。则:
babaabbabbabbbb 就是合理的次序。像这样的答案一共有多少呢?请你计算出
所有可能方案的个数(包含题目给出的)。
public class Q2 {
    static char[] ans = new char[20];
    static int res;

    public static void main(String[] args){
        dfs(1, 0, 0, 2);
        System.out.println(res);
    }

    public static void dfs(int index, int cnt1, int cnt2, int answer){
        if(index==15)//最后一次遇到的是花
        {
            if(answer==1)
            {
                ans[index]='b';
                for(int i=1;i<=index;i++)
                    System.out.print(ans[i]);
                System.out.println();
                res++;
            }
            return ;
        }
        if(cnt1<5)
        {
            //遇到的是店 ,a
            ans[index]='a';
            dfs(index+1,cnt1+1,cnt2,answer*2);
        }
        if(cnt2<9)//由于最后一次必须是花,所以前面只能遇到9次花
        {
            //遇到的是花 ,b
            ans[index]='b';
            dfs(index+1,cnt1,cnt2+1,answer-1);
        }
    }
}
3. 第 39 级台阶
题目描述:
小明刚刚看完电影《第 39 级台阶》,离开电影院的时候,他数了数礼堂前的
台阶数,恰好是 39 级!
站在台阶前,他突然又想着一个问题:
如果我每一步只能迈上 1 个或 2 个台阶。先迈左脚,然后左右交替,最后一
步是迈右脚,也就是说一共要走偶数步。那么,上完 39 级台阶,有多少种不同
的上法呢?
输出格式:
输出一个整数
答案:51167078
public class Q3 {
    public static void main(String[] args){
        int[][] step = new int[39][2];// 第一维是39层阶梯,第二维是左右脚

        // 对于第一级阶梯,左脚有1种方法到达,右脚0种(因为题目要求先迈左脚)
        step[0][0] = 1;
        step[0][1] = 0;

        // 对于第二级阶梯,左脚有1种方法到达,因为每一步只能迈上1或2 个台阶,右脚有1种
        step[1][0] = 1;
        step[1][1] = 1;

        for (int i = 2; i < 39; i++) {
            step[i][1] = step[i - 2][0] + step[i - 1][0];
            step[i][0] = step[i - 2][1] + step[i - 1][1];
        }

        System.out.println(step[38][1]);
    }
}

4. 穿越雷区
题目描述
已知的地图是一个方阵,上面用字母标出了 A,B 区,其它区都标了正号或负号
分别表示正负能量辐射区。
例如:
A + - + -
- + - - +
- + + + -
+ - + - +
B + - + -
坦克车只能水平或垂直方向上移动到相邻的区。
数据格式要求:
输入第一行是一个整数 瀁 ,表示方阵的大小, 4<=瀁<100
接下来是 瀁 行,每行有 瀁 个数据,可能是 A,B,+,-中的某一个,中间用空格
分开。
A,B 都只出现一次。
要求输出一个整数,表示坦克从 A 区到 B 区的最少移动步数。
如果没有方案,则输出-1
例如:
用户输入:
5
A + - + -
- + - - +
- + + + -
+ - + - +
B + - + -
则程序应该输出:
10 资源约定:
峰值内存消耗 < 512M
CPU 消耗 < 1000瀀s
请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意: 瀀a濼瀁 函数需要返回 0
注意: 只使用 ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的
特殊函数。
注意: 所有依赖的函数必须明确地在源文件中 #濼瀁c濿ude <xxx>, 不能通过工程
import java.util.Scanner;

public class Q4 {
    static int xA, yA, xB, yB;
    static char[][] array;
    static boolean [][] flag;
    static int n;
    static int countMin = -1;

    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        n = scan.nextInt();
        array = new char[n][n];
        flag = new boolean[n][n];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                char temp = scan.next().charAt(0);
                if (temp == '-' || temp == '+') {
                    array[i][j] = temp;
                } else if (temp == 'A') {
                    xA = j;
                    yA = i;
                    array[i][j] = temp;
                } else {
                    xB = j;
                    yB = i;
                    array[i][j] = temp;
                }
            }
        }
        flag[xA][yA] = true;
        dfs(xA, yA, '0', 0);
        System.out.println(countMin);
    }

    private static void dfs(int x, int y, char sign, int count) {
        if (x == xB && y == yB) {
            if(countMin == -1){
                countMin = count;
            }else{
                countMin = Math.min(countMin, count);
            }
            return;
        }

        if (sign == '0') {
            ahead(x, y, sign, count);
        }
        if (sign == '+' ) {
            ahead(x, y, sign, count);
        }
        if (sign == '-') {
            ahead(x, y, sign, count);
        }
    }

    private static void ahead(int x, int y, char sign, int count) {
        if(x + 1 < n && !flag[y][x+1] && array[y][x + 1] != sign){
            flag[y][x+1] = true;
            dfs(x + 1, y, array[y][x + 1], count + 1);
            flag[y][x+1] = false;
        }
        if(y + 1 < n &&!flag[y+1][x] && array[y + 1][x] != sign){
            flag[y+1][x] = true;
            dfs(x, y + 1, array[y + 1][x], count + 1);
            flag[y+1][x] = false;
        }
        if(x - 1 >= 0&& !flag[y][x-1] && array[y][x - 1] != sign){
            flag[y][x-1] = true;
            dfs(x - 1, y, array[y][x - 1], count + 1);
            flag[y][x-1] = false;
        }
        if(y - 1 >= 0&&!flag[y-1][x] && array[y - 1][x] != sign){
            flag[y-1][x] = true;
            dfs(x, y - 1, array[y - 1][x], count + 1);
            flag[y-1][x] = false;
        }
    }

}
5. 迷宫
题目描述
下图给出了一个迷宫的平面图,其中标记为 1 的为障碍,标记为 0 的为可 以
通行的地方。
010000
000100
001001
110000
迷宫的入口为左上角,出口为右下角,在迷宫中,只能从一个位置走到这 个它
的上、下、左、右四个方向之一。 对于上面的迷宫,从入口开始,可以按
DRRURRDDDR 的顺序通过迷宫, 一共 10 步。其中 D、U、L、R 分别表示向
下、向上、向左、向右走。 对于下面这个更复杂的迷宫(30 行 50 列),请找
出一种通过迷宫的方式, 其使用的步数最少,在步数最少的前提下,请找出字
典序最小的一个作为答案。 请注意在字典序中 D<L<R<U。(如果你把以下文字
复制到文本文件中,请务 必检查复制的内容是否与文档中的一致。在试题目录
下有一个文件 瀀aze.txt, 内容与下面的文本相同)
答案提交
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一 个字
符串,包含四种字母 D、U、L、R,在提交答案时只填写这个字符串,填 写多余
的内容将无法得分
DDDDRRURRRRRRDRRRRDDDLDDRDDDDDDDDDDDDRDDRRRURRUURRDDDDRDRRRRRRDRRURRDDDRRRRUURUUUUUUULULLUUUURRRRUULLLUUUULLUUULUURRURRURURRRDDRRRRRDDRRDDLLLDDRRDDRDDLDDDLLDDLLLDLDDDLDDRRRRRRRRRDDDDDDRR
import java.util.Scanner;

public class Q5 {
    static char[][] ch = new char[35][55];
    static int[][] arr = new int[35][55];
    static int[] fx = { 1, 0, 0, -1 };
    static int[] fy = { 0, -1, 1, 0 };
    static int ph, pe;
    static int[][] pc = new int[1500][2];
    int x;
    int y;
    int pre;
    static Q5[] maze = new Q5[1500];

    public static void main(String[] args) {
        for (int i = 0; i < 35; i++) {
            for (int j = 0; j < 55; j++) {
                ch[i][j] = 0;
                arr[i][j] = 0;
            }
        }

        for (int i = 0; i < 1500; i++) {
            for (int j = 0; j < 2; j++) {
                pc[i][j] = 0;
            }
        }

        int i, j;
        Scanner sc = new Scanner(System.in);
        String[] str = new String[35];
        for (i = 0; i < 30; i++)
            str[i] = sc.next();

        for (int k = 0; k < 30; k++) {
            for (int l = 0; l < str[k].length(); l++) {
                ch[k][l] = str[k].charAt(l);
            }
        }
        
        for (i = 0; i < 30; i++)
        {
            for (j = 0; j < 50; j++)
            {
                arr[i][j] = ch[i][j] - '0';
            }
        }
        bfs();
    }

    public static void Out(){
        int len = 0;
        int i;
        while (maze[ph].pre != 0)//没有加入起点坐标(0,0)
        {
            pc[len][0] = maze[ph].x;
            pc[len][1] = maze[ph].y;
            ph = maze[ph].pre;
            len++;
        }
        pc[len][0] = 0;//加入起点坐标(0,0)
        pc[len][1] = 0;
        len++;
        for (i = len-1; i >0; i--)
        {
            if (pc[i][0] > pc[i - 1][0])//x值减小
                System.out.print("U");
            else if (pc[i][0] < pc[i - 1][0])
                System.out.print("D");
            else if (pc[i][1] > pc[i - 1][1])//y值减小
                System.out.print("L");
            else if (pc[i][1] < pc[i - 1][1])
                System.out.print("R");
        }
    }

    public static void bfs(){
        int x, y, i;
        pe = 0;
        ph = 1;
        maze[0].x = 0;
        maze[0].y = 0;
        maze[0].pre = 0;
        arr[0][0] = 1;
        while (true)
        {
            pe++;
            for (i = 0; i < 4; i++)
            {
                x = maze[pe].x + fx[i];
                y = maze[pe].y + fy[i];
                if ((arr[x][y] == 0)&&(x>=0&&x<30&&y>=0&&y<50))
                {
                    ph++;
                    maze[ph].x = x;
                    maze[ph].y = y;
                    maze[ph].pre = pe;
                    arr[x][y] = 1;
                    if (maze[ph].x == 29 && maze[ph].y == 49)
                    {
                        Out();
                        return;
                    }
                }
            }
        }
    }
}

6. 跳马
问题描述:
中国象棋半张棋盘如图 1 所示。马自左下角(0,0)向右上角(瀀 ,瀁 )跳。规定只能
往右跳,不准往左跳。比如图 1 中所示为一种跳行路线,并将路径总数打印出来。
输入格式:
只有一行:两个数 瀁 ,瀀
输出格式:
只有一个数:总方案数 t瀂ta濿。
import java.util.Scanner;

public class Q6 {
    static int n, m, ans;
    static int[] dx = new int[]{1, 2, 2, 1};
    static int[] dy = new int[]{2, 1, -1, -2};

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        n = sc.nextInt();
        m = sc.nextInt();

        dfs(0, 0);

        System.out.println(ans);
    }

    public static void dfs(int x, int y){
        if(x == m && y == n)
        {
            ans ++ ;
        }
        int i ;
        int tx = 0 ;
        int ty = 0 ;
        for (i = 0 ; i< 4 ;i++)
        {
            tx = x + dx[i] ;
            ty = y + dy[i] ;
            if(tx >m  || tx <0 || ty >n || ty<0)
                continue ;
            else
            {
                dfs(tx,ty);
            }

        }
    }
}

7. 路径之谜
小明冒充 X 星球的骑士,进入了一个奇怪的城堡。
城堡里边什么都没有,只有方形石头铺成的地面。
假设城堡地面是 瀁 x 瀁 个方格。【如图 1.瀃瀁g】所示。
按习俗,骑士要从西北角走到东南角。
可以横向或纵向移动,但不能斜着走,也不能跳跃。
每走到一个新方格,就要向正北方和正西方各射一箭。
(城堡的西墙和北墙内各有 瀁 个靶子)
同一个方格只允许经过一次。但不必做完所有的方格。
如果只给出靶子上箭的数目,你能推断出骑士的行走路线吗?
有时是可以的,比如图 1.瀃瀁g 中的例子。
本题的要求就是已知箭靶数字,求骑士的行走路径(测试数据保证路径唯一)
输入:
第一行一个整数 N(0<N<20),表示地面有 N x N 个方格
第二行 N 个整数,空格分开,表示北边的箭靶上的数字(自西向东)
第三行 N 个整数,空格分开,表示西边的箭靶上的数字(自北向南)
输出:
一行若干个整数,表示骑士路径。
为了方便表示,我们约定每个小格子用一个数字代表,从西北角开始编号:
0,1,2,3....
比如,图 1.瀃瀁g 中的方块编号为:
0 1 2 3
4 5 6 7 8 9 10 11
12 13 14 15
示例:
用户输入:
4
2 4 3 4
4 3 3 3
程序应该输出:
0 4 5 1 2 3 7 11 10 9 13 14 15
资源约定:
峰值内存消耗 < 256M
CPU 消耗 < 1000瀀s
请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意:不要使用 瀃ac濾age 语句。不要使用 濽d濾1.7 及以上版本的特性。
注意:主类的名字必须是:Ma濼瀁,否则按无效代码处理。
import java.util.Arrays;
import java.util.Scanner;

public class Q7 {
    static int[][] arr, arr1, path, xy = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}};
    static boolean[][] vis;
    static int N;

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        N = sc.nextInt();
        sc.nextLine();
        // 地图数组
        arr = new int[N][N];
        // 靶子数组
        arr1 = new int[2][N];
        // 记录是否经过
        vis = new boolean[N][N];
        // 记录经过的路径
        path = new int[N][N];
        int c = 0;
        for (int i = 0; i < arr1.length; i++) {
            String[] s = sc.nextLine().split(" ");
            for (int j = 0; j < N; j++) {
                arr1[i][j] = Integer.parseInt(s[j]);
            }
        }
        sc.close();
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                arr[i][j] = c ++;
            }
        }
        f();
    }

    static void f() {
        // 从起点开始,且靶子箭的数目大于0
        if (arr1[0][0] > 0 && arr1[1][0] > 0) {
            // 标记已经过
            vis[0][0] = true;
            // 北方向靶子数-1
            arr1[0][0] -= 1;
            // 西方向靶子数-1
            arr1[1][0] -= 1;
            // 深度遍历
            dfs(0, 0);
        }
    }

    static void dfs(int x, int y) {
        // 若走到终点
        if (x == N - 1 && y == N - 1) {
            // 判断靶子是否射完
            if (check()) {
                for (int i = 0; i < N; i++) {
                    System.out.println(Arrays.toString(path[i]));
                }
                System.out.print(arr[0][0] + " ");
                // 深度遍历进行打印
                dfs1(0, 0);
            }
            return;
        }
        // 上下左右走
        for (int i = 0; i < xy.length; i++) {
            int o = x + xy[i][0];
            int p = y + xy[i][1];
            // 若没有越界 且 未经过 且 靶子箭的数量不为0
            if (o >= 0 && o < N && p >= 0 && p < N && !vis[o][p] && arr1[0][p] > 0 && arr1[1][o] > 0) {
                arr1[0][p] -= 1;
                arr1[1][o] -= 1;
                vis[o][p] = true;
                // 记录经过的路径
                path[o][p] += path[x][y] + 1;
                dfs(o, p);
                arr1[0][p] += 1;
                arr1[1][o] += 1;
                vis[o][p] = false;
                // 回溯时将当前路径置为0
                path[o][p] = 0;
            }
        }
    }

    static boolean check() {
        for (int i = 0; i < arr1.length; i++) {
            for (int j = 0; j < arr1[i].length; j++) {
                if (arr1[i][j] != 0) {
                    return false;
                }
            }
        }
        return true;
    }

    static void dfs1(int x, int y) {
        for (int i = 0; i < xy.length; i++) {
            int o = x + xy[i][0];
            int p = y + xy[i][1];
            if (o >= 0 && o < N && p >= 0 && p < N && path[o][p] == path[x][y] + 1) {
                System.out.print(arr[o][p] + " ");
                dfs1(o, p);
            }
        }
    }
}

8. 未名湖边的烦恼
问题描述
每年冬天,北大未名湖上都是滑冰的好地方。北大体育组准备了许多冰鞋,
可是人太多了,每天下午收工后,常常一双冰鞋都不剩。
每天早上,租鞋窗口都会排起长龙,假设有还鞋的 瀀 个,有需要租鞋的 瀁
个。现在的问题是,这些人有多少种排法,可以避免出现体育组没有冰鞋可租的
尴尬场面。(两个同样需求的人(比如都是租鞋或都是还鞋)交换位置是同一种
排法)
输入格式
两个整数,表示 瀀 和 瀁
输出格式
一个整数,表示队伍的排法的方案数。
样例输入
3 2
样例输出
5
数据规模和约定
瀀,瀁∈[0,18]
public class Q8 {

    public static void main(String[] args){
        int n, m;
        Scanner sc = new Scanner(System.in);
        n = sc.nextInt();
        m = sc.nextInt();

        System.out.println(fun(n, m));
    }

    public static int fun(int n, int m){
        if(n < m) return 0;
        if(m == 0) return 1;
        return fun(n - 1, m) + fun(n, m - 1);
    }
}
9. 大臣的旅费
问题描述
很久以前,T 王国空前繁荣。为了更好地管理国家,王国修建了大量的快速
路,用于连接首都和王国内的各大城市。
为节省经费,T 国的大臣们经过思考,制定了一套优秀的修建方案,使得任何
一个大城市都能从首都直接或者通过其他大城市间接到达。同时,如果不重复
经过大城市,从首都到达每个大城市的方案都是唯一的。
J 是 T 国重要大臣,他巡查于各大城市之间,体察民情。所以,从一个城市马
不停蹄地到另一个城市成了 J 最常做的事情。他有一个钱袋,用于存放往来城
市间的路费。
聪明的 J 发现,如果不在某个城市停下来修整,在连续行进过程中,他所花的
路费与他已走过的距离有关,在走第 x 千米到第 x+1 千米这一千米中(
x 是整
数),他花费的路费是 x+10 这么多。也就是说走 1 千米花费 11,走 2 千米要
花费 23。
J 大臣想知道:他从某一个城市出发,中间不休息,到达另一个城市,所有可
能花费的路费中最多是多少呢?
输入格式
输入的第一行包含一个整数 瀁 ,表示包括首都在内的 T 王国的城市数
城市从 1 开始依次编号,1 号城市为首都。
接下来 瀁 -1 行,描述 T 国的高速路(
T 国的高速路一定是 瀁 -1 条)
每行三个整数 P濼, Q濼, D濼,表示城市 P濼 和城市 Q濼 之间有一条高速路,长度为 D濼
千米。
输出格式
输出一个整数,表示大臣 J 最多花费的路费是多少。
样例输入 1
5
1 2 2 1 3 1
2 4 5
2 5 4
样例输出 1
135
输出格式
大臣 J 从城市 4 到城市 5 要花费 135 的路费。
#include <iostream>
#include <map>
#include <vector>
#include <cstring>
using namespace std;
map<int,vector<int> > t;
map<pair<int,int>,int> dis;
int visited[10001];
int mdis=0,pos;
void DFS(int i,int d)
{
	if(!visited[i])
	{
		visited[i]=1;
		if(d>mdis)
		{
			pos=i;
			mdis=d;			
		} 
		for(int j=0;j<t[i].size();j++)
			if(!visited[t[i][j]])
			{
				pair<int,int> tmp(i,t[i][j]);
				DFS(t[i][j],d+dis[tmp]);
			}	
	}
}
int main()
{
	int n,a,b,d,cost=0;
	cin>>n;
	for(int i=0;i<n-1;i++)
	{
		cin>>a>>b>>d;
		t[a].push_back(b);
		t[b].push_back(a);
		dis[make_pair(a,b)]=d;
		dis[make_pair(b,a)]=d;
	}
	memset(visited,0,sizeof(visited));//一定不要忘记两次置零
	DFS(1,0);//找到一个端点
	memset(visited,0,sizeof(visited));
	DFS(pos,0);
	for(int i=1;i<=mdis;i++)
		cost+=(10+i);
	cout<<cost<<endl;
	return 0;
}

10. 2n 皇后问题
Description
给定一个 瀁*瀁 的棋盘,棋盘中有一些位置不能放皇后。现在要向棋盘中放入 瀁 个
黑皇后
和 瀁 个白皇后,使任意的两个黑皇后都不在同一行、同一列或同一条对角线上,
任意的两
个白皇后都不在同一行、同一列或同一条对角线上。问总共有多少种放法?瀁 小
于等于 8。
Input
输入的第一行为一个整数 瀁 ,表示棋盘的大小。
接下来 瀁 行,每行 瀁 个 0 或 1 的整数,如果一个整数为 1,表示对应的位置可以
放皇后,
如果一个整数为 0,表示对应的位置不可以放皇后。
Output
输出一个整数,表示总共有多少种放法。
Sample Input
N瀂.1
4
1 1 1 1
1 1 1 1
1 1 1 1
1 1 1 1
N瀂.2
4
1 0 1 1
1 1 1 1
1 1 1 1
1 1 1 1 Sample Output
N瀂.1
2
N瀂.2
0
import java.util.Scanner;

public class Q10 {

        static int count = 0;//存放有多少种方法
        static int[] white = null;//存放白皇后
        static int[] black = null;//存放黑皇后
        static int queens = 0;//棋盘大小
        static int[][] arr = null;//初始化棋盘

        public static void main(String[] args) {
            Scanner scan = new Scanner(System.in);
            queens = scan.nextInt();
            white = new int[queens];
            black = new int[queens];
            arr = new int[queens][queens];
            //初始化棋盘
            for (int i = 0; i < queens; i++) {
                for (int j = 0; j < queens; j++) {
                    arr[i][j] = scan.nextInt();
                }
            }
            scan.close();
            checkWhite(0);
            System.out.println(count);
        }
        
        private static void checkWhite(int n) {
            //先放置白皇后,当n=queens说明最后一个白皇后已经放置
            if (n == queens) {
                checkBlock(0);//白皇后放置完,则放置黑皇后
                return;
            }
            for (int i = 0; i < queens; i++) {
                if (arr[n][i] == 1) {//判断此位置是否可以放皇后,此位置为1说明可以放置
                    white[n] = i;//将第n个皇后放置到位置i,i表示第i列
                } else {
                    continue;//若此位置不能放置,则结束本次循环。即尝试放置到下一列
                }
                if (judgeW(n)) {//检验是否冲突
                    checkWhite(n + 1);//不冲突则递归放置下一个皇后
                }
            }
        }
        
        private static void checkBlock(int m) {
            if (m == queens) {//当m=queens表示黑皇后已经放置结束
                count++;
                return;
            }
            for (int i = 0; i < queens; i++) {
                if (arr[m][i] == 1 && i != white[m]) {//i!=white[m]表示此位置没有放置白皇后
                    black[m] = i;
                } else {
                    continue;
                }
                if (judgeB(m)) {
                    checkBlock(m + 1);
                }
            }
        }
        
        private static boolean judgeW(int n) {
            for (int i = 0; i < n; i++) {
                if (white[i] == white[n] || Math.abs(n - i) == Math.abs(white[n] - white[i])) {
                    return false;
                }
            }
            return true;
        }
        
        private static boolean judgeB(int m) {
            for (int i = 0; i < m; i++) {
                if (black[i] == black[m] || Math.abs(m - i) == Math.abs(black[m] - black[i])) {
                    return false;
                }
            }
            return true;
        }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值