本程序为C#控制台(.Net Framework 目标框架)
使用方法在data.csv中填好已有的数据,需要解密的数据空着不填。
using System; using System.Diagnostics; using System.IO;namespace 数独解密 {class Program{static void Main(){// 动态确定数独板的大小int size = GetBoardSizeFromCsv("data.csv");// 创建一个动态大小的二维数组来表示数独板int[,] board = new int[size, size];// 从CSV文件读取数独板的初始值ReadFromCsv(board, "sudoku.csv");// 创建一个 Stopwatch 实例用于计时Stopwatch stopwatch = new Stopwatch();// 开始计时 stopwatch.Start();// 调用递归函数尝试解决数独if (SolveSudoku(board, size)){// 如果成功解决数独,则打印结果 PrintBoard(board, size);}else{// 如果没有解,则打印消息Console.WriteLine("没有解");}// 停止计时 stopwatch.Stop();// 输出耗时Console.WriteLine($"耗时: {stopwatch.Elapsed.TotalMilliseconds} 毫秒");Console.ReadKey();}// 从CSV文件中获取数独板的大小static int GetBoardSizeFromCsv(string filePath){int maxValue = 0; // 初始化最大值为0using (var reader = new StreamReader(filePath)){while (!reader.EndOfStream){var line = reader.ReadLine(); // 读取一行var values = line.Split(','); // 按逗号分割该行// 遍历该行中的每个值foreach (var value in values){if (!string.IsNullOrEmpty(value)) // 如果值不为空 {int num = int.Parse(value); // 将字符串转换为整数if (num > maxValue) // 更新最大值 {maxValue = num;}}}}}return maxValue; // 返回最大值,作为数独板的大小 }// 从CSV文件读取数独板的初始值static void ReadFromCsv(int[,] board, string filePath){using (var reader = new StreamReader(filePath)){int row = 0;while (!reader.EndOfStream){var line = reader.ReadLine(); // 读取一行var values = line.Split(','); // 按逗号分割该行// 遍历该行中的每个值for (int col = 0; col < values.Length; col++){if (values[col] != "") // 如果值不为空 {board[row, col] = int.Parse(values[col]); // 将值赋给数独板 }}row++; // 行索引递增 }}}// 递归函数:尝试解决数独static bool SolveSudoku(int[,] board, int size){// 遍历每一行和每一列for (int row = 0; row < size; row++){for (int col = 0; col < size; col++){// 如果当前位置是0,表示需要填充if (board[row, col] == 0){// 尝试填入1到size的数字for (int num = 1; num <= size; num++){// 检查填入的数字是否有效if (IsValid(board, row, col, num, size)){// 填入数字board[row, col] = num;// 递归调用解决剩余部分if (SolveSudoku(board, size)){return true; // 如果成功,返回true }else{// 如果失败,重置当前位置为0board[row, col] = 0;}}}// 如果1到size的数字都不能填入,返回falsereturn false;}}}// 如果没有空位置,说明解决成功return true;}// 检查在给定位置填入数字是否有效static bool IsValid(int[,] board, int row, int col, int num, int size){// 检查同一行是否有相同的数字for (int i = 0; i < size; i++){if (board[row, i] == num){return false; // 如果有相同的数字,则无效 }}// 检查同一列是否有相同的数字for (int i = 0; i < size; i++){if (board[i, col] == num){return false; // 如果有相同的数字,则无效 }}// 检查子宫格中是否有相同的数字int boxSize = (int)Math.Sqrt(size); // 子宫格的大小int startRow = row - row % boxSize; // 子宫格的起始行int startCol = col - col % boxSize; // 子宫格的起始列for (int i = 0; i < boxSize; i++){for (int j = 0; j < boxSize; j++){if (board[i + startRow, j + startCol] == num){return false; // 如果有相同的数字,则无效 }}}// 如果没有相同的数字,则有效return true;}// 打印数独板static void PrintBoard(int[,] board, int size){for (int row = 0; row < size; row++){for (int col = 0; col < size; col++){Console.Write(board[row, col] + " "); // 打印数字 }Console.WriteLine(); // 打印换行符 }}} }