c++ 隨機生成數獨(不保證唯一解)

給出一個最簡單的生成數獨初盤的程序,不保證有唯一解,終盤的正確性通過填充的過程來確定,可以用舞蹈鏈算法求解該數獨得到其中一個解

隨機生成的方法就算交換行和列然後隨機挖洞

這裏有一點要注意的就是交換的行和列必須處於同一宮中,要不然交換之後保證不了正確性

然後就是隨機挖洞,可以直接隨機一個座標,或者用洗牌算法(類似於掃雷初盤的生成)

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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章