第二次作业——个人项目实战:数独

第二次作业——个人项目实战:数独


运行环境: windows10
编程IDE: Visual Studio 2017 社区版
编程语言: C++
Github地址:传送门

1)项目需求

利用程序随机构造出N个已解答的数独棋盘。
输入: 数独棋盘题目个数N(0< N<=1000000)
输出:随机生成N个 不重复 的 已解答完毕的 数独棋盘,并输出到sudoku.txt中

2)解题思路

首先我想到的是本题中的随机性,用C++中的随机函数rand()来产生随机数。在一开始先利用随机数生成左上角的第一个宫格,在此过程中只需要判断第一个宫格是否数独冲突。在接下去的宫格生成过程中,需要每个数的宫格检查、行检查、列检查。而在后续的宫格生成过程中可能会存在无解的情况,这时候就需要回溯重来。
由于左上第一个数字是固定的,则第一个宫格的随机排列组合有8!=40320种,若再加上其他行列的变化后会有几何数级增长的可能性,经过了解,数独的可能有6,670,903,752,021,072,936,960种组合。其他宫格中每个数字的生成有9种可能(1~9),若试完这些可能仍然无法填入宫格则为无解,需要重新再来。

3)设计实现

采用一个动态的二维数组来表示数独棋盘(9×9),初始化为0表示未填入。设计列检查、行检查、宫检查的函数以及生成宫格的函数和打印函数(检查用)。输入需要生成棋盘的个数N后,开始初始化棋盘,首先用随机数生成一个满足要求的第一宫格,接下去的八个宫格均同样方法(若无解回到第一步生成宫格开始),为提高效率,若重试次数过多(这里限制为100次),则重新生成整个棋盘。(简单粗暴的方法)

4)代码说明

//行检查(列检查同理)
bool Sudoku_Row(int arr[9][9],int row, int num)
{
	bool flag = false;
	for (int i = 0; i < 9; i++)
	{
		if (arr[row][i] == num) 
		{
			flag = true;
			break;
		}
	}
	return flag;
}
//宫检查
bool Sudoku_Square(int arr[9][9],int row, int col, int num)
{
	bool flag = false;  //冲突标志
	int Square_Row = (row / 3) * 3;
	int Square_Col = (col / 3) * 3;
	for (int i = 0; i < 3; i++)
	{
		for (int j = 0; j < 3; j++)
		{
			if (arr[Square_Row + i][Square_Col + j] == num)
			{
				flag = true;
				break;
			}
		}
	}
	return flag;
}
//生成宫格
bool makeSquare(int arr[9][9],int num)
{
	int square_row = (num / 3) * 3;
	int square_col = (num % 3) * 3;
	int x, y;
	int temp;
	if (num == 0)  //第一个宫格
	{
		for (int i = 1; i < 9; i++)
		{
			x = square_row + i / 3;
			y = square_col + i % 3;
			temp = Random(8) + 2;//生成2~9的随机数
			if (!Sudoku_Square(arr, x, y, temp))
			{
				arr[x][y] = temp;
			}
			else i--;
		}
	}
	else  //其他宫格
	{
		int try_count = 0;
		temp = Random(9)+1;////生成1~9的随机数
		for (int i = 0; i < 9; i++)
		{
			x = square_row + i / 3;
			y = square_col + i % 3;
			temp++;
			temp = temp % 10;//循环随机数在1~9范围内
			if (!Sudoku_Square(arr, x, y, temp) && !Sudoku_Col(arr, y, temp) && !Sudoku_Row(arr, x, temp)&&temp!=0)
			{
				arr[x][y] = temp;
				try_count = 0;
			}
			else
			{
				i--;
				try_count++;
			}
			if (try_count > 10)
			{
				return false;
				break;
			}//若所有可能试完则返回无解
		}
	}
	return true;//有解
}

5)测试运行




N=10000
如图所示 输出和宫格生成占用的时间最多,在这方面还有很多需要改善。
由于项目开始时间太晚,只能先完成这些部分了,后续再完善(有生之年)


6)关于执行力与泛泛而谈

执行力是一个种将意愿转化为实际结果的能力,也就是与办事能力、工作效率相挂钩。若是三分钟热度,往往只是停留在空想阶段,容易泛泛而谈,一旦碰壁就放弃。兴趣和热情很重要,方式方法也是另一面手心,热情毕竟是有限的,提高执行力能看到实际的结果,也比较有信心把这件事做下去。

PSP

PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划 600 800
· Estimate · 估计这个任务需要多少时间 30 20
Development 开发 600 800
· Analysis · 需求分析 (包括学习新技术) 120 60
· Design Spec · 生成设计文档 100 60
· Design Review · 设计复审 (和同事审核设计文档) 60 30
· Coding Standard · 代码规范 (为目前的开发制定合适的规范) 100 0
· Design · 具体设计 100 100
· Coding · 具体编码 600 800
· Code Review · 代码复审 100 150
· Test · 测试(自我测试,修改代码,提交修改) 100 150
Reporting 报告 150 250
· Test Report · 测试报告 60 30
· Size Measurement · 计算工作量 30 25
· Postmortem & Process Improvement Plan · 事后总结, 并提出过程改进计划 30 10
合计 2180 2485
原文地址:https://www.cnblogs.com/kunza/p/7502312.html