万金流
以码会友。 吾Q:578751655。 水平有限,轻喷,谢!

如题。

显然,八皇后问题可以用栈来解决。

突然想试试用一维数组的下标和值,表示入栈的皇后在棋盘上的位置,就有了下面的c#代码:

using System;

namespace ConsoleApp1
{
    class Program
    {
        //使用一维数组表示栈
        //  用法:a[3]=5表示第三行第五列入栈
        //  main函数中的n指向靠近栈顶的空元素
        static int[] a = new int[8];
        static void Main(string[] args)
        {
            int i, n = 0, c = 0;
            //此处赋初值仅是为了使刚进循环时,i为0
            a[0] = -1;
            do
            {
                //结合n--,i=a[n]表示出栈操作
                i = a[n];
                //结合后面的for循环,i++表示从出栈元素代表位置的后一个元素继续扫描
                i++;
                for (; i < 8; i++)
                {
                    if (isOK(n, i))
                    {
                        a[n] = i;//入栈
                        if (n == 7)
                        {
                            c++;
                            if (c == 1)
                            {
                                Console.WriteLine($"第{c}种解法:");
                                for (int j = 0; j < a.Length; j++)
                                {
                                    Console.WriteLine($"({j},{a[j]})");
                                }
                            }
                        }
                        else
                        {
                            n++;
                            //为了使for循环的i从0重新开始
                            i = -1;
                        }
                    }
                }
                //当前行扫描完毕,回到上一行继续扫描
                //把n看成栈顶的空单元格指针,这个操作也是“出栈”的前奏
                n--;
            } while (n >= 0);
            Console.WriteLine($"共有{c}种解法。");
        }
        static bool isOK(int x, int y)
        {
            bool myb = true;
            for (int i = 0; i < x; i++)
            {
                if (a[i] == y || i - a[i] == x - y || i + a[i] == x + y)
                {
                    myb = false;
                    break;
                }
            }
            return myb;
        }
    }
}

//原始思路:
//n = 0

//第n行每个格子能否落子
//* 每个格子
//能                不能
//(第七行,结束)            
//(不是第7行)
//压栈
//n++                下一个
//*格子全部走完
//*n--
//*退栈

我是先写了后面的思路,再编的代码,然后稍微优化了一点点,添加了程序注释。


 使用递归解八皇后问题,思考起来容易一些,写代码也更轻松。

思路:

  fangGe(int n)表示在第n行和它后面的行放皇后。具体做法:

  如果要放的是第八行(行标从0开始),说明前面(0-7行)已经摆出了8皇后的正确位置,这里输出结果就行了。

  否则

    1、第n行,从左到右,一个格子一个格子看。能放就放(放皇后就是格子里的值为1);不能放拉倒。

    (如果能放)

    2、放下之后,放它后面的所有行。即:执行fangGe(int n+1)。后面能不能放,输不输出结果,交给后面代码的去考虑。

    3、”2“执行完以后,说明这个格子的使命完成,把它置为0,再看下一格。

java程序代码如下:

public class App
{
    static int[][] a = new int[8][8];
    static int c = 0, printNo = 5;

    public static void main(String[] args) throws Exception
    {
        fangGe(0);
        System.out.println("共有解法" + c + "种");
    }

    public static void fangGe(int n)
    {
        if (n == 8)
        {
            c++;
            if (c == printNo)
            {
                System.out.println("第" + printNo + "种解法:");
                showArray();
            }
            return;
        }
        for (int i = 0; i < 8; i++)
        {
            if (nengFang(n, i))
            {
                a[n][i] = 1;
                fangGe(n + 1);
                a[n][i] = 0;
            }
        }
    }

    public static boolean nengFang(int x, int y)
    {
        int hang = x, lie = y;
        boolean flag = true;
        while (--hang >= 0 && --lie >= 0)
        {
            if (a[hang][lie] == 1)
            {
                flag = false;
            }
        }
        if (!flag)
        {
            return flag;
        }
        hang = x;
        lie = y;
        while (--hang >= 0 && ++lie <=7)
        {
            if (a[hang][lie] == 1)
            {
                flag = false;
            }
        }
        if (!flag)
        {
            return flag;
        }
        hang = x;
        lie = y;
        while (--hang >= 0)
        {
            if (a[hang][lie] == 1)
            {
                flag = false;
            }
        }
        return flag;
    }

    static void showArray()
    {
        for (int i = 0; i < a.length; i++)
        {
            for (int j = 0; j < a[i].length; j++)
            {
                System.out.print(a[i][j] + "\t");
            }
            System.out.println();
        }
    }
}

运行结果:

 

posted on 2020-11-09 23:28  万金流  阅读(426)  评论(0编辑  收藏  举报