2019软工第三次作业

准备阶段

1、github地址

2、PSP表格

psp2.1 预估耗时(分钟) 实际耗时(分钟)
计划 30 30
估计这个任务需要多少时间 20 15
开发 150 120
需求分析 (包括学习新技术) 240 300
生成设计文档 20 30
设计复审 10 10
代码规范(为目前的开发制定合适的规范) 120 120
具体设计 30 30
具体编码 240 180
代码复审 20 15
测试(自我测试,修改代码,提交修改) 120 240
报告 30 60
测试报告 30 50
计算工程量 20 30
事后总结,并提出过程改进计划 60 60
合计 1140 1290

开始阶段

1、思考

百度百科简介:
数独盘面是个九宫,每一宫又分为九个小格。在这八十一格中给出一定的已知数字和解题条件,利用逻辑和推理,在其他的空格上填入1-9的数字。使1-9每个数字在每一行、每一列和每一宫中都只出现一次,所以又称“九宫格”。

对于从来没有接触过数独的我来讲,这无疑是一个非常、非常、非常难的题目,因为我连最基本的数独规则都不清楚。即使它只有三条判断逻辑,但是解一个九宫格数独,还是需要一定的时间的。

2、思路

首先判断、利用三个bool数组直接获得合法性结果。

 if(row[x][i] == false && col[y][i] == false && little_shudu[area][i] == false)
 

如此之后,我们可以得到一个方格是否能进行填入的结果。
得到方块的合法性之后,我们用DFS进行遍历、回溯

                shudu[x][y] = i;
                row[x][i] = true;
                col[y][i] = true;
                if(gx != 1 || gy != 1)
                    little_shudu[area][i] = true;
                dfs(index + 1,maxscan,jie,gx,gy);
                shudu[x][y] = 0;
                row[x][i] = false;
                col[y][i] = false;
                if(gx != 1 || gy != 1) 
                    little_shudu[area][i] = false;

3、模块

1、输入模块

由于要求是要从input.txt中输入,所以输入模块如下:

void input(int x,int gx,int gy)
{
    memset(row,false,sizeof(row));
    memset(col,false,sizeof(col));
    memset(little_shudu,false,sizeof(little_shudu));
    for(int i = 0 ; i < x ; i++){
        for(int j = 0 ; j < x ; j++){
            fscanf(fp, "%d", &shudu[i][j]);
        
            int temp_i = i / gx;
            int temp_j = j / gy;
            int area = temp_i * gx + temp_j;
        
            if(shudu[i][j] != 0){
                int temp = shudu[i][j];
                row[i][temp] = true;
                col[j][temp] = true;
                if(gx != 1 || gy != 1 ){
                    little_shudu[area][temp] = true;
                }
                
            }
        }
    }
}

2、输出模块

通过输入文件得到数独并进行求解,然后将其输出一个output.txt文件

void print(int x)
{
    for(int i = 0 ; i < x ; i++)
    {
        for(int j = 0 ; j < x ; j++)
        {
            if(j == x - 1) {
                fprintf(fp, "%d\n", shudu[i][j]);
            
            }
            else {
                fprintf(fp, "%d ", shudu[i][j]);
            
            }
        }
    }
    fprintf(fp, "\n");
    
}

3、求解模块

即先检查合法性,后进行计算填入。

void dfs(int index , int maxscan,int jie,int gx , int gy)
{
    if(index >= maxscan) 
    {
        print(jie);
        return ; 
    }
    int x = index / jie ;
    int y = index % jie ;
    int temp_i = x / gx;
    int temp_j = y / gy;
    int area = temp_i * gx + temp_j;
    if(shudu[x][y] == 0)
    { 
        for(int i = 1 ; i <= jie ; i++)
        {
            if(row[x][i] == false && col[y][i] == false && little_shudu[area][i] == false)
            {
                shudu[x][y] = i;
                row[x][i] = true;
                col[y][i] = true;
                if(gx != 1 || gy != 1)
                    little_shudu[area][i] = true;
                dfs(index + 1,maxscan,jie,gx,gy);
                shudu[x][y] = 0;
                row[x][i] = false;
                col[y][i] = false;
                if(gx != 1 || gy != 1) 
                    little_shudu[area][i] = false;
            }
        }
    }
    else{
        dfs(index + 1,maxscan,jie,gx,gy);
    }
}

4、性能测试

感觉好像还行,不明觉厉。

5、运行测试



三宫格 done!



四宫格 done!

(中间省略5 6 8)



七宫格 done!



当然肯定也少不了九宫格!
总代码:

#include "stdafx.h"
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include<string>
#include <cstring>
#include <set>
#include <map>
#include <cmath>
#include <stack>
#include <queue>
#include <fstream>

using namespace std;
const int maxn = 1000;
const int sizen = 16;
int shudu[sizen][sizen];//存储数独
bool row[sizen][sizen];//row[i][j]判断i行j是否被填过
bool col[sizen][sizen];//col[i][j]判断i列j是否被填过
bool little_shudu[sizen][sizen];//little_sudu[i][j]判断从左往右开始的第i个小数独中,j是否被填过;
FILE* fp;

void input(int x, int gx, int gy) {
    memset(row, false, sizeof(row));
    memset(col, false, sizeof(col));
    memset(little_shudu, false, sizeof(little_shudu));
    for (int i = 0; i < x; i++) {
        for (int j = 0; j < x; j++) {

            scanf("%d", &shudu[i][j]);
            int temp_i = i / gx;
            int temp_j = j / gy;
            int area = temp_i * gx + temp_j;

            if (shudu[i][j] != 0) {
                int temp = shudu[i][j];
                row[i][temp] = true;
                col[j][temp] = true;
                if (gx != 1 || gy != 1) {
                    little_shudu[area][temp] = true;

                }

            }
        }
    }
}
void print(int x) {
    for (int i = 0; i < x; i++) {
        for (int j = 0; j < x; j++) {
            if (j == x - 1) {


                printf("%d\n", shudu[i][j]);
            }
            else {

                printf("%d ", shudu[i][j]);
            }
        }
    }

    printf("\n");
}
void dfs(int index, int maxscan, int jie, int gx, int gy) {
    if (index >= maxscan) {
        print(jie);
        return;
    }
    int x = index / jie;
    int y = index % jie;
    int temp_i = x / gx;
    int temp_j = y / gy;
    int area = temp_i * gx + temp_j;
    if (shudu[x][y] == 0) {
        for (int i = 1; i <= jie; i++) {
            if (row[x][i] == false && col[y][i] == false && little_shudu[area][i] == false) {
                shudu[x][y] = i;
                row[x][i] = true;
                col[y][i] = true;
                if (gx != 1 || gy != 1)
                    little_shudu[area][i] = true;
                dfs(index + 1, maxscan, jie, gx, gy);
                shudu[x][y] = 0;
                row[x][i] = false;
                col[y][i] = false;
                if (gx != 1 || gy != 1)
                    little_shudu[area][i] = false;
            }
        }

    }
    else {
        dfs(index + 1, maxscan, jie, gx, gy);
    }
}

int main(int argc, char *argv[]) {
    int pan, size, jie, gx, gy;
    int in, out;
    for (int i = 0; i < argc; i++)
    {
        if (strlen(argv[i]) == 1)
        {
            if (i == 2)
                size = atoi(argv[i]);
            if (i == 4)
                pan = atoi(argv[i]);
        }
        else if (argv[i][0] == '-' && argv[i][1] == 'i') {
            i++;
            in = i;
        }
        else if (argv[i][0] == '-' && argv[i][1] == 'o') {
            i++;
            out = i;
        }
    }
    freopen(argv[in], "r", stdin);
    freopen(argv[out], "w", stdout);
    jie = size;
    if (size == 4) {
        gx = gy = 2;
    }
    else if (size == 6) {
        gx = 2;
        gy = 3;
    }
    else if (size == 8) {
        gx = 4;
        gy = 2;
    }
    else if (size == 9) {
        gx = gy = 3;
    }
    else gx = gy = 1;
    for (int i = 0; i < pan; i++) {
        input(size, gx, gy);

        dfs(0, jie*jie, jie, gx, gy);

    }
    return 0;
}

尾声

总结

在众多大佬的帮助下,终于是完成了这次作业。通过这次的作业,更是学到了不少东西,典型的就是github。希望能够在以后的学习中,更上一层楼。

猜你喜欢

转载自www.cnblogs.com/Pr0Sk1er/p/11576063.html