数独解密小程序
本程序为C#控制台(.Net Framework 目标框架)
使用方法在data.csv中填好已有的数据,需要解密的数据空着不填。运行程序前一定要关闭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; // 初始化最大值为0 using (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 { // 如果失败,重置当前位置为0 board[row, col] = 0; } } } // 如果1到size的数字都不能填入,返回false return 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(); // 打印换行符 } } } }