zoukankan      html  css  js  c++  java
  • 软件工程实践2017第二次作业

    ===================

    一、GitHub地址:https://github.com/xiaoknownothing/Fzuwork

    二、遇到的困难及解决方法

     一看到这个题目感觉可以选定一个空位,扫看所在行,所在列,所在宫,排除数字后选择数字填入,最好的情况所在行列的数字全部填满,这样就简单多了。可是这个数独棋盘只有一个数已知,其他的位子都有9个数要去“猜测”,每行每列每宫格子内数字还不重复,顿时脑子有点大,忙着搜索了一下,看了一些博客,才有了一些大概方向。
    

    三、解题思路

    用回溯法求解数独:

    • 1.从找第一个空的位子开始,找可选数(排除同行同列同宫重复的数),逐个放入
    • 2.找下一个空的位置,找可选数填入,如果这时候,发现此处空白格没有可选数,就回溯,换掉前面的可选数,再继续执行2
    • 3.直到空位子都满了就是一个数独解出来了
      //找出area[x][y]的可选数
    vector <int> find(int x, int y) 
    {
    	int a[10] = { 0 };
    	vector <int> ret;//声明一个int型向量ret 
    	for (int i = 0; i < 9; i++)
    	 {
    		if (sudu[i][y] > 0) 
    		a[sudu[i][y]] = 1;//所在行若有其他数,标记已使用 
    		if (sudu[x][i] > 0)
    	    a[sudu[x][i]] = 1; //所在列若有其他数,标记已使用 
    		
    	}
    	int row = x / 3, col = y / 3;//所在宫若有其他数,标记已使用 
    	for (int i = row * 3; i < row * 3 + 3; i++)
    	{ 
    		for (int j = col * 3; j < col * 3 + 3; j++)
    		 {
    			if (sudu[i][j] > 0) 
    			a[sudu[i][j]] = 1;
    		}
    	}
    	for (int i = 1; i <= 9; i++) 
    	{
    	if (!a[i]) ret.push_back(i);//逐个填入剩余可选数 
        }
    	return ret;
    }
    
    void update() {
    	for (int i = 0; i < 81; i++) area[i].clear();
    	chosen = make_pair(0, 10);
    	can_update = false;
    	for (int i = 0; i < 9; i++	)
    	{
    		for (int j = 0; j < 9; j++) if (sudu[i][j]==0) 
    		{
    			int k = i * 9 + j;//k为该空白格序号 
    			area[k] = find(i, j);//填入可选数 
    			if (area[k].empty()) is_blank = false;//没有可选数 
    			if (area[k].size() < chosen.second) chosen = make_pair(k, area[k].size());//更新 
    			can_update = true;
    		}
    	}
    }
    
    void num_sudu() 
    {
    	update();
    	if (can_update==false)
    	 {
    		num++;
    		if (num >=N) is_over = true;
    		print();
    	}
    	else if (is_blank==false) 
    	{
    		return;
    	}
    	else if (is_over==false)
    	 {
    		int areaition = chosen.first;
    		int x = areaition / 9;
    		int y = areaition - x * 9;//x,y为该位置坐标 
            int size = chosen.second;//size为选中数个数 
    		vector <int> k = area[areaition];
    		for (int i = 0; i < size; i++) 
    		{
    			sudu[x][y] = k[i];
    			num_sudu();
    			sudu[x][y] = 0;
    			is_blank = true;
    			// 回溯, 还原数据, 原is_blank, 前面的深搜,都没有正确答案,会导致is_blank=false
    		}
    	}
    }
    

    四、测试

    • 运行测试

    五、PSP

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

  • 相关阅读:
    八数码难题 (codevs 1225)题解
    小木棍 (codevs 3498)题解
    sliding windows (poj 2823) 题解
    集合删数 (vijos 1545) 题解
    合并果子 (codevs 1063) 题解
    等价表达式 (codevs 1107)题解
    生理周期 (poj 1006) 题解
    区间 (vijos 1439) 题解
    区间覆盖问题 题解
    种树 (codevs 1653) 题解
  • 原文地址:https://www.cnblogs.com/xiao2017/p/7502581.html
Copyright © 2011-2022 走看看