給出一個最簡單的生成數獨初盤的程序,不保證有唯一解,終盤的正確性通過填充的過程來確定,可以用舞蹈鏈算法求解該數獨得到其中一個解
隨機生成的方法就算交換行和列然後隨機挖洞
這裏有一點要注意的就是交換的行和列必須處於同一宮中,要不然交換之後保證不了正確性
然後就是隨機挖洞,可以直接隨機一個座標,或者用洗牌算法(類似於掃雷初盤的生成)
vector<vector<int> > generate(const int & level) {
vector<vector<int> > mtx =
{ {9 ,8 ,7 ,6 ,5 ,4 ,3 ,2 ,1},
{4 ,5, 6 ,2 ,3 ,1 ,7 ,8 ,9},
{3 ,2 ,1 ,7 ,8 ,9 ,4 ,5 ,6},
{1 ,3 ,5 ,8 ,6 ,7 ,2 ,9 ,4},
{8 ,4 ,2 ,3 ,9 ,5 ,6 ,1 ,7},
{6 ,7 ,9 ,1 ,4 ,2 ,5 ,3 ,8},
{2 ,6 ,3 ,9 ,7 ,8 ,1 ,4 ,5},
{7 ,9 ,4 ,5 ,1 ,3 ,8 ,6 ,2},
{5 ,1 ,8 ,4 ,2 ,6 ,9 ,7 ,3} };
int remain = -1;
switch (level)
{
case 0:
remain = 30;
break;
case 1:
remain = 25;
break;
case 2:
remain = 21;
break;
case 3:
remain = 18;
break;
default:
break;
}
for (int i = 0; i < 25; ++i) {
int t = rand() % 9;
int tx = t / 3 * 3;
int ty = t % 3 * 3;
int r1 = tx + rand() % 3;
int r2 = tx + rand() % 3;
int c1 = ty+ rand() % 3;
int c2 = ty+ rand() % 3;
swap(mtx[r1], mtx[r2]);
for (int j = 0; j < 9; ++j) {
swap(mtx[j][c1], mtx[j][c2]);
}
}
vector<int> nums(81);
for (int i = 0; i < remain; ++i) {
nums[i] = 1;
}
for (int i = 0; i < 81; ++i) {
swap(nums[i], nums[rand() % 81]);
}
for (int i = 0; i < 9; ++i) {
int pos = i * 9;
for (int j = 0; j < 9; ++j) {
if (!nums[pos++]) {
mtx[i][j] = 0;
}
}
}
return mtx;
}