软工第三次作业

Github地址

031702523

PSP表格

PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划 30 45
Estimate 估计这个任务需要多少时间 20 20
Development 开发 1500 1650
Analysis 需求分析 (包括学习新技术) 60 120
Design Spec 生成设计文档 50 60
Design Review 设计复审 10 30
Coding Standard 代码规范 (为目前的开发制定合适的规范) 50 100
Design 具体设计 110 150
Coding 具体编码 500 600
Code Review 代码复审 100 80
Test 测试(自我测试,修改代码,提交修改) 150 120
Reporting 报告 30 30
Test Repor 测试报告 40 40
Size Measurement 计算工作量 20 20
Postmortem & Process Improvement Plan 事后总结, 并提出过程改进计划 10 10
合计 1550 1715

解题思路

全局变量
int arr[11][11] = { 0 };
int xrr[11][11] = { 0 };//第一维是第几行,第二维是第几个数
int yrr[11][11] = { 0 };//第一维是第几列,第二维是第几个数
int mrr[11][11] = { 0 };//第一维是第几个宫,第二维是第几个数

1.先实现用文件流输入和输出

#include<fstream>

ifstream fin("input.txt");
ofstream fout("output.txt");
定义文件流输入fin和输出fout
void read(int x, int a, int b)//文件流输入
{
	int i, j, k;
	for (i = 1; i <= x; i++)
		for (j = 1; j <= x; j++)
		{
			fin >> arr[i][j];
			k = arr[i][j];
			if (k != 0)
			{
				xrr[i][k] = 1;//把初始化时行上当前数字置为不可用
				yrr[j][k] = 1;//原理同上
				if (a != 1)
					mrr[checkm(a, b, i, j)][k] = 1;//原理同上
			}
		}
}
void print(int x)//输出数独
{
	int i, j;
	for (i = 1; i <= x; i++)
	{
		for (j = 1; j <= x; j++)
		{
			fout << arr[i][j] << ' ';
		}
		fout << endl;
	}
}
read函数和print函数把数独装入和输出

2.实现3、5和7阶数独的实现

checkandwrite函数实现数独数字的填入
bool checkandwrite(int x, int y, int type, int a, int b)//找到空白的格子,找到并填入合适的数字
{
	if (x == type && y == (type + 1))//遍历完数独最后一个格子
		return true;
	else if (y == (type + 1))//遍历换行
	{
		x++;
		y = 1;
	}
	if (arr[x][y] == 0)//找到了空白格子
	{
		int num = checkm(a, b, x, y);
		for (int n = 1; n <= type; n++)
		{
			if (xrr[x][n] == 0 && yrr[y][n] == 0 )
			{
				arr[x][y] = n;//填入数字,同时更新可用数字的三个数组
				xrr[x][n] = 1;
				yrr[y][n] = 1;
				if (checkandwrite(x, y + 1, type, a, b) == 0)
				{
					arr[x][y] = 0;//当前位置无数可填,返回上一级,并重置为原来状态
					xrr[x][n] = 0;
					yrr[y][n] = 0;
				}
				else
					return true;
			}
		}
		return false;
	}
	else
		return checkandwrite(x, y + 1, type, a, b);//当前格子已有数据,直接进行下一个格子

}



3.实现4、6、8和9的数独运算

更新后的checkandwrite
bool checkandwrite(int x, int y, int type, int a, int b)//找到空白的格子,找到并填入合适的数字
{
	if (x == type && y == (type + 1))//遍历完数独最后一个格子
		return true;
	else if (y == (type + 1))//遍历换行
	{
		x++;
		y = 1;
	}
	if (arr[x][y] == 0)//找到了空白格子
	{
		int num = checkm(a, b, x, y);
		if (a == 1)
			num = 0;
		for (int n = 1; n <= type; n++)
		{
			if (xrr[x][n] == 0 && yrr[y][n] == 0 && mrr[num][n] == 0)
			{
				arr[x][y] = n;//填入数字,同时更新可用数字的三个数组
				xrr[x][n] = 1;
				yrr[y][n] = 1;
				if (a != 1)
					mrr[num][n] = 1;
				if (checkandwrite(x, y + 1, type, a, b) == 0)
				{
					arr[x][y] = 0;//当前位置无数可填,返回上一级,并重置为原来状态
					xrr[x][n] = 0;
					yrr[y][n] = 0;
					if (a != 1)
						mrr[num][n] = 0;
				}
				else
					return true;
			}
		}
		return false;
	}
	else
		return checkandwrite(x, y + 1, type, a, b);//当前格子已有数据,直接进行下一个格子

}





更新后需要加入宫的判断
int checkm(int x, int y, int a, int b)//找到当前格所在宫的编号
{
	int n, m;
	n = a / x;
	if ((a%x) != 0)
		n++;
	m = b / y;
	if ((b%y) != 0)
		m++;
	return (n - 1)*x + m;
}
具体解题思路通过网上了解到回溯法解数独,但是大部分代码有点看不懂,就按照自己的想法用数组记录的方式一步步更新数组,最终得到解。
posted on 2019-09-25 21:24  breeze1024  阅读(172)  评论(1编辑  收藏  举报