算法初涉-解决比9*9数独更复杂的结构

Posted 勤劳的Coder

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法初涉-解决比9*9数独更复杂的结构相关的知识,希望对你有一定的参考价值。

算法起源于某朋友的一次求助。朋友在一家电器商场上班,每到年底就需要做数据,光凭个人能力基本无法解决。故向我提起此事,作为一个骄傲的程序猿,我表示分分钟给你解决了,然而详细了解后,发现问题并不是那么简单,故开始写一个算法帮助朋友解决问题。

问题描述如下:

填上所有的空格,保证列末尾的数等于末尾之前的数之和,行末尾的数等于末尾之前的数之和。

目前算法不是最优化的.运气差的时候会导致堆栈溢出..后续继续再优化..

static void Main(string[] args)
        {

            LoeFirstAlgorithm();
            
           
        }
        public static List<int> rowTarget = new List<int>() { };
        public static List<int> colTarger = new List<int>() { };
        public static ArrayList nullArr = new ArrayList();
        public static int iRdm = 0;
        public static int Yu = 0;
        public static int calCount = 0;
        public static void LoeFirstAlgorithm()
        {
            Console.WriteLine("请输入列目标,以,分隔,输入完成按Enter:");
            var colStr = Console.ReadLine();
            Console.WriteLine("请输入行目标,以,分隔,输入完成按Enter:");
            var rowStr = Console.ReadLine();
            var colArr = colStr.Split(\',\');
            var rowArr = rowStr.Split(\',\');
            foreach (var row in rowArr)
            {
                rowTarget.Add(int.Parse(row));
            }
            foreach (var col in colArr)
            {
                colTarger.Add(int.Parse(col));
            }
            Console.WriteLine("现在开始疯狂计算....");
            CalMethod();
            Console.Read();
        }
        public static void CalMethod()
        {
            ArrayList secondArray = new ArrayList() { };
            foreach (var row in rowTarget)
            {
                secondArray.Add((ArrayList)Cal(0, new ArrayList(), 0, row));
            }
            int[,] second = new int[rowTarget.Count, colTarger.Count];
            for (int i = 0; i < rowTarget.Count; i++)
            {
                for (int j = 0; j < colTarger.Count; j++)
                {
                    second[i, j] = (int)((ArrayList)secondArray[i])[j];
                }
            }
            int firstCol = 0;
            for (int i = 0; i < rowTarget.Count; i++)
            {
                firstCol += second[i, 0];
            }
            if (firstCol != colTarger[0])
            {
                GC.Collect();
                CalMethod();
            }
            else
            {
                Console.WriteLine("已经计算了" + calCount + "次,出现满足第一列和各行的要求,离成功近了一步");
                Console.WriteLine("目前数组如下:");
                Console.WriteLine("");
                for (int i = 0; i < rowTarget.Count; i++)
                {
                    for (int j = 0; j < colTarger.Count; j++)
                    {
                        if ((int)second[i, j] < 10)
                            Console.Write("0" + (int)second[i, j] + " ");
                        else
                            Console.Write((int)second[i, j] + " ");
                    }
                    Console.WriteLine("");
                }
                //数据处理
                for (int a = 1; a < (colTarger.Count - 1); a++)
                {

                    int cha = 0;
                    int colCount = 0;
                    for (int k = 0; k < rowTarget.Count; k++)
                    {
                        colCount += second[k, a];
                    }
                    cha = colCount - colTarger[a];
                    int i = 0;
                    do
                    {
                        if (cha > 0)
                        {
                            if (second[i, a] > cha)
                            {
                                second[i, a] = second[i, a] - cha;
                                second[i, a + 1] = second[i, a + 1] + cha;
                                cha = 0;
                            }
                            else
                            {
                                cha = cha - second[i, a];
                                second[i, a + 1] = second[i, a + 1] + second[i, a];
                                second[i, a] = 0;
                            }
                        }
                        else
                        {
                            if (second[i, a + 1] > Math.Abs(cha))
                            {
                                second[i, a] = second[i, a] - cha;
                                second[i, a + 1] = second[i, a + 1] + cha;
                                cha = 0;
                            }
                            else
                            {
                                cha = cha + second[i, a + 1];
                                second[i, a] = second[i, a] + second[i, a + 1];
                                second[i, a + 1] = 0;
                            }
                        }
                        i++;
                    }
                    while (Math.Abs(cha) > 0);
                }
                Console.WriteLine("数据处理完毕,处理完的数据如下:");
                for (int i = 0; i < rowTarget.Count; i++)
                {
                    for (int j = 0; j < colTarger.Count; j++)
                    {
                        if ((int)second[i, j] < 10)
                            Console.Write("0" + (int)second[i, j] + " ");
                        else
                            Console.Write((int)second[i, j] + " ");
                    }
                    Console.WriteLine("");
                }
                Console.WriteLine("你特么太厉害了!!");

            }

        }
        public static object Cal(int i, ArrayList arr, int count, int target)
        {
            Random Rdm = new Random(Environment.TickCount);
            i++;
            if ((target - count) >= colTarger[i - 1])
                Yu = colTarger[i - 1];
            else
                Yu = target - count;
            if (i == colTarger.Count)
            {
                iRdm = Yu;
            }
            else
            {
                iRdm = Rdm.Next(0, Yu + 1);

            }
            arr.Add(iRdm);
            count += iRdm;
            if (i == colTarger.Count)
            {
                calCount++;
                nullArr.Add(arr);
                if (count == target)
                {
                    return nullArr[calCount - 1];
                }
                else
                {
                    GC.Collect();
                    Cal(0, new ArrayList(), 0, target);
                }
            }
            else
            {
                GC.Collect();
                Cal(i, arr, count, target);
            }
            return nullArr[calCount - 1];
        }

  

 

以上是关于算法初涉-解决比9*9数独更复杂的结构的主要内容,如果未能解决你的问题,请参考以下文章

数据结构与算法之深入解析“有效的数独”的求解思路与算法示例

用c语言写一个简易数独的思路。要代码

数独回溯算法

2021-09-23:编写一个程序,通过填充空格来解决数独问题。数独的解法需遵循如下规则:数字 1-9 在每一行只能出现一次。数字 1-9 在每一列只能出现一次。数字 1-9 在每一个以粗实线分隔的(

Python数独回溯

确定数独是不是有唯一解