C#递归使用及八皇后问题

递归简单使用(寻找路径)

题目描述

在这里插入图片描述
如图所示的地图,有颜色的区域代表有墙体,无法通过,现需要从a点到达b点,通过递归来查找可行路径

代码

using System;

namespace MazeExample
{
    class Program
    {
        static void Main(string[] args)
        {
            //创建一个二维数组模拟迷宫
            int[,] map = new int[8, 7];
            //使用 1 表示墙
            for (int i = 0; i < 7; i++)
            {
                map[0, i] = 1;
                map[7, i] = 1;
            }
            for (int i = 0; i < 8; i++)
            {
                map[i, 0] = 1;
                map[i, 6] = 1;
            }
            map[3, 1] = 1;
            map[3, 2] = 1;
            //map[1, 2] = 1;
            //map[2, 2] = 1;
            //输出地图
            for (int i = 0; i < 8; i++)
            {
                for (int j = 0; j < 7; j++)
                {
                    Console.Write(map[i, j] + " ");
                }
                Console.WriteLine();
            }

            bool tag = SetWayByAnotherStrategy(map, 1, 1);

            //输出新地图
            for (int i = 0; i < 3; i++)
            {
                Console.WriteLine();
            }
            for (int i = 0; i < 8; i++)
            {
                for (int j = 0; j < 7; j++)
                {
                    Console.Write(map[i, j] + " ");
                }
                Console.WriteLine();
            }
        }


        /*
         * 1.map表示地图
         * 2.i,j表示从地图的哪个位置开始找
         * 3.如果小球能到达map[6,5]的位置,则说明通路找到
         * 4.约定 当map[i,j]为0表示该点没有走过, 1表示墙,  3表示通路可以走,  3表示该点已经走过,但是走不通
         * 5.走迷宫时,需要确定一个策略,下->右->上->左,如果该点走不通,再回溯
         */

        /// <summary>
        /// 
        /// </summary>
        /// <param name="map">表示地图</param>
        /// <param name="i">从哪个位置开始找</param>
        /// <param name="j"></param>
        /// <returns>如果找到通路,就返回ture,否则返回false</returns>
        static bool SetWay(int[,]map,int i, int j)
        {
            if (map[6,5] == 2)  //退出条件
            {
                return true;
            }
            else
            {
                //如果当前这个点还没有走过
                if (map[i,j] == 0)
                {
                    //按照策略走 下->右->上->左
                    map[i, j] = 2;  //假定该点可以走通
                    if (SetWay(map,i+1,j))    //向下走
                    {
                        return true;
                    }
                    else if(SetWay(map,i,j+1))
                    {
                        return true;
                    }
                    else if(SetWay(map,i-1,j))
                    {
                        return true;
                    }
                    else if (SetWay(map,i,j-1))
                    {
                        return true;
                    }
                    else
                    {
                        //说明该点走不通
                        map[i, j] = 3;
                        return false;
                    }
                }
                else
                {
                    //如果 map[i,j] != 0 则可能是1、2、3
                    return false;
                }
            }
        }

        //修改策略 上->右->上->左
        static bool SetWayByAnotherStrategy(int[,] map, int i, int j)
        {
            if (map[6, 5] == 2)  //退出条件
            {
                return true;
            }
            else
            {
                //如果当前这个点还没有走过
                if (map[i, j] == 0)
                {
                    //按照策略走 下->右->上->左
                    map[i, j] = 2;  //假定该点可以走通
                    if (SetWayByAnotherStrategy(map, i-1, j))    //向下走
                    {
                        return true;
                    }
                    else if (SetWayByAnotherStrategy(map, i, j + 1))
                    {
                        return true;
                    }
                    else if (SetWayByAnotherStrategy(map, i + 1, j))
                    {
                        return true;
                    }
                    else if (SetWayByAnotherStrategy(map, i, j - 1))
                    {
                        return true;
                    }
                    else
                    {
                        //说明该点走不通
                        map[i, j] = 3;
                        return false;
                    }
                }
                else
                {
                    //如果 map[i,j] != 0 则可能是1、2、3
                    return false;
                }
            }
        }
    }
}

八皇后问题

题目描述

一个8×8的棋盘,将八个皇后摆放在棋盘上,各个皇后之间不能在同一行、同一列、同一斜线上,试求所有可能的解法

思路

  1. 将第一个皇后放在第一行第一列
  2. 第二个皇后放在第二行第二列,判断是否可行,如果不可行则依次遍历第二列、第三列 … 直到把所有列放一遍
  3. 继续第三个皇后、第四个皇后,直到第8个皇后也能放在一个不冲突的位置,即找到了一个正确解。

[注] 代码使用一维数组来模拟棋盘 下标代表放置的行数,对应的值代表放置的列数。 例如 arr[i] = val 则说明 第 i+1 个皇后放在第 i+1 行的第 val 列。

代码

using System;


namespace EightQueenProblem
{
    class Program
    {
        //定义一个max表示一共有多少个皇后
        static int max = 8;
        static int cnt = 0; //解法的数量
        //定义一个数组用于保存皇后放置的结果, 比如 arr = {0,4,7,5,2,6,1,3}
        static int[] array = new int[max];
        static void Main(string[] args)
        {
            Check(0);
            Console.WriteLine(cnt);
        }
       

        //放置第n个皇后的方法
        static void Check(int n)
        {
            if (n == max)   //8个皇后已经放好了
            {
                cnt++;
                Print();
                Console.WriteLine();
                return;
            }

            //依次放入皇后并判断是否冲突
            for (int i = 0; i < max; i++)
            {
                //先把当前这个皇后 n, 放在该行的第一列
                array[n] = i;

                //判断当放置第n个皇后到i列时是否冲突
                if (Judge(n))   //不冲突
                {
                    //接着放第n+1个皇后
                    Check(n + 1);
                }

                //如果冲突,继续执行for循环,array[n]=i; 即把第n个皇后放置在后一列
            }
        }


        //写一个方法,打印摆放的位置
        static void Print()
        {
            for (int i = 0; i < array.Length; i++)
            {
                Console.Write(array[i] + " ");
            }
            Console.WriteLine();
        }

        //查看当放置第n个皇后时,检测该皇后是否与之前已经存在的皇后冲突
        /// <summary>
        /// 
        /// </summary>
        /// <param name="n">第n个皇后</param>
        /// <returns></returns>
        static bool Judge(int n)
        {
            for (int i = 0; i < n; i++)
            {
                //Math.Abs(n - i) == Math.Abs(array[n] - array[i]) 判断是否在同一斜线上 纵坐标之差与横坐标之差相等代表在同一斜线上
                if (array[i] == array[n] || Math.Abs(n - i) == Math.Abs(array[n] - array[i]))   
                {
                    return false;
                }
            }
            return true;
        }
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值