用了一点简单的回溯就可以建立一个数独Grid了, 算法并不复杂, 效率也很不错哦.
求解一个数独其实也可以用回溯搞定.
参考:
Sudoku Generator
A Sudoku Solver in C
Sudoku-Help Difficulty (SHD) Rating
Minimum Sudoku
求解一个数独其实也可以用回溯搞定.
using System;
using System.Collections.Generic;
using System.Text;
namespace Adrian.Sudoku
{
public class SudokuDataGenerator
{
public static SudokuData New()
{
SudokuData dt = new SudokuData();
Random ran = new Random();
// data stores in "grid:int[,]"
int[,] grid = dt.Data;
// stores data for backtracking
List<int>[,] used = new List<int>[9, 9];
int i = 0;
int j = 0;
for (i = 0; i < 9; i++)
{
for (j = 0; j < 9; j++)
{
used[i, j] = new List<int>();
}
}
for (i = 0; i < 9; i++)
{
for (j = 0; j < 9; j++)
{
bool ok = false;
// used numbers of current cell
List<int> curUsed = used[i, j];
while (!ok && curUsed.Count < 9)
{
int posValue = ran.Next(1, 10);
// find an unused number
while (curUsed.Contains(posValue))
{
posValue = ran.Next(1, 10);
}
// satisfy the constraint?
ok = Check(grid, i, j, posValue);
if (ok)
{
grid[i, j] = posValue;
}
curUsed.Add(posValue);
}
// used up 1~9
if (!ok)
{
// backtracking
// go back to the last cell and try the rest numbers
curUsed.Clear();
if (j > 0)
{
j -= 2;
grid[i, j + 1] = 0;
}
else
{
i--;
j = 7;
grid[i, 8] = 0;
}
}
}
}
return dt;
}
private static bool Check(int[,] grid, int row, int col, int possibleValue)
{
int i = 0;
int j = 0;
// check column
for (i = 0; i < 9; i++)
{
if (grid[row, i] == possibleValue)
{
return false;
}
}
// check row
for (j = 0; j < 9; j++)
{
if (grid[j, col] == possibleValue)
{
return false;
}
}
// check 3*3 child grid
int rowStart = (row - row % 3);
int colStart = (col - col % 3);
for (i = rowStart; i < rowStart + 3; i++)
{
for (j = colStart; j < colStart + 3; j++)
{
if (grid[i, j] == possibleValue)
{
return false;
}
}
}
return true;
}
}
}
using System.Collections.Generic;
using System.Text;
namespace Adrian.Sudoku
{
public class SudokuDataGenerator
{
public static SudokuData New()
{
SudokuData dt = new SudokuData();
Random ran = new Random();
// data stores in "grid:int[,]"
int[,] grid = dt.Data;
// stores data for backtracking
List<int>[,] used = new List<int>[9, 9];
int i = 0;
int j = 0;
for (i = 0; i < 9; i++)
{
for (j = 0; j < 9; j++)
{
used[i, j] = new List<int>();
}
}
for (i = 0; i < 9; i++)
{
for (j = 0; j < 9; j++)
{
bool ok = false;
// used numbers of current cell
List<int> curUsed = used[i, j];
while (!ok && curUsed.Count < 9)
{
int posValue = ran.Next(1, 10);
// find an unused number
while (curUsed.Contains(posValue))
{
posValue = ran.Next(1, 10);
}
// satisfy the constraint?
ok = Check(grid, i, j, posValue);
if (ok)
{
grid[i, j] = posValue;
}
curUsed.Add(posValue);
}
// used up 1~9
if (!ok)
{
// backtracking
// go back to the last cell and try the rest numbers
curUsed.Clear();
if (j > 0)
{
j -= 2;
grid[i, j + 1] = 0;
}
else
{
i--;
j = 7;
grid[i, 8] = 0;
}
}
}
}
return dt;
}
private static bool Check(int[,] grid, int row, int col, int possibleValue)
{
int i = 0;
int j = 0;
// check column
for (i = 0; i < 9; i++)
{
if (grid[row, i] == possibleValue)
{
return false;
}
}
// check row
for (j = 0; j < 9; j++)
{
if (grid[j, col] == possibleValue)
{
return false;
}
}
// check 3*3 child grid
int rowStart = (row - row % 3);
int colStart = (col - col % 3);
for (i = rowStart; i < rowStart + 3; i++)
{
for (j = colStart; j < colStart + 3; j++)
{
if (grid[i, j] == possibleValue)
{
return false;
}
}
}
return true;
}
}
}
参考:
Sudoku Generator
A Sudoku Solver in C
Sudoku-Help Difficulty (SHD) Rating
Minimum Sudoku