zoukankan      html  css  js  c++  java
  • 数独——分析、设计与测评

    1、github地址:https://github.com/kinglc/sudoku1943

    2、解题思路:项目包括 输入与输出(文件读写、命令行),生成不重复终局,解数独三个部分。

      (1)输入与输出

          文件读写和命令行虽然都不熟,但稍微百度就完全可以解决。

      (2)生成不重复终局

          先随便写了一个数独终局

          1 2 3  4 5 6  7 8 9

          4 5 6  7 8 9  1 2 3

          7 8 9  1 2 3  4 5 6

          2 3 4  5 6 7  8 9 1

          5 6 7  8 9 1  2 3 4  

          8 9 1  2 3 4  5 6 7

          3 4 5  6 7 8  9 1 2

          6 7 8  9 1 2  3 4 5

          9 1 2  3 4 5  6 7 8

          只需要生成一定数量的数独终局从简单的入手就好,上图第一行是随手写,后8行都可以看做根据第一行左移得到,第一行全排列有8!=40320种,然后交换2-3(因为数据只要求1e6,可以不 考虑),4-6,7-9行,再乘3!×3!,结果略大于1e6。

      (3)解数独

          本来试着看了一下dancing links算法,但十字链表似乎好麻烦的样子,于是老老实实用dfs暴力写完了。

    3、代码设计

      (1)函数功能

        int main(int ,char *) :获取命令行参数,进入不同处理函数

        void createFinal():参数为-c时:生成终局存入数组,并调用output(int,int)函数

        void workout(int):参数为-s时:通过深搜得出终局,用check(int,int)函数判断,并调用output(int,int)函数

        bool check(int,int):判断在该处填的数字是否合理

        void output(int,int):根据参数所代表的输出顺序输出终局

        

      (2)关键函数

        生成终局:

    void createFinal()
    {
        int tmp[9] = { 8,9,1,2,3,4,5,6,7 };//tmp表示第一行数字
        int i, j, k, moveleft[8] = { 3,6,1,4,7,2,5,8 };    //moveleft表示2-9行在第1行基础上整体左移位数
        for (i = 0; i < 40320; i++)    //8!=40320
        {
            memcpy(numBoard[0], tmp, sizeof(tmp));
            //将第1行左移生成2-9行
            for (j = 0; j < 8; j++)
                for (k = 0; k < 9; k++)
                    numBoard[j + 1][k] = numBoard[0][(k + moveleft[j]) % 9];//初始图完成
            //调换4-6,7-9行
            for (j = 0; j < 6; j++)
                for (k = 0; k < 6; k++)
                {
                    output(j, k);
                    if (!--testnum)
                        return;
                }
            next_permutation(tmp + 1, tmp + 9);//重置第一行
        }
        return;
    }
    void createFinal()

        解数独:

    void workout(int pos)//深搜
    {
        if (pos == 81)
        {
            output(0, 0);
            flag = 1;    //标记是否输出过
            return;
        }
        int i, x, y;
        x = pos / 9;
        y = pos % 9;
        if (!numBoard[x][y])
        {
            for (i = 1; i <= 9; i++)
            {
                if (cnt[i - 1] == 9)
                    continue;
                numBoard[x][y] = i;//填充数字
                cnt[i - 1]++;
                if (check(pos, i))
                    workout(pos + 1);
                if (flag)    //该数独已解完
                    return;
                cnt[i - 1]--;
                numBoard[x][y] = 0;
            }
        }
        else
            workout(pos + 1);
    }
    void workout(int pos)

       (3)单元测试

           命令行参数判定:-c,  -s,  -abc

           运行情况判定:-c 1,  -c 1000,  -c  1000000,  -s 文件路径(其中包含1、1000、1000000个用例)

    4、运行分析

        (1)生成1000个数独终局

      (2)解1000个20-40个空格的数独

      (3)优化

        在生成终局中,本来是用了三次全排列分别对第一行8个数字、第4-6行、7-9行处理,后优化为用print[6][3]={ 0,1,2,0,2,1,1,2,0,1,0,2,2,1,0,2,0,1 }存入全排列数,在output函数中处理输出。

    void output(int mid,int last)
    {
        int i, j, k, row;
        int order[3] = { 0 };
        order[1] = mid;
        order[2] = last;
        for (i = 0; i < 3; i++)//输出第i个三行
            for (j = 0; j < 3; j++)
            {
                row = print[order[i]][j] + 3 * i;
                for (k = 0; k < 8; k++)
                    output_file << numBoard[row][k] << " ";
                output_file << numBoard[row][8]<<endl;
            }
        output_file << endl;
    }
    void output(int mid,int last)

    5、PSP

     PSP2.1  

       Personal Software Process Stages    

     预估耗时(分钟)

     实际耗时(分钟)

    Planning

    计划

    30

    30

    ·Estimate

    ·估计这个任务需要多少时间

    30

    30

    Development

    开发

    1080

     1080

    ·Analysis

    ·需求分析(包括学习新技术)

    120

    120

    ·Design Spec

    ·生成设计文档

    120

    90

    ·Design Review

    ·设计复审

    30

    30

    ·Coding Standard

    ·代码规范

    30

    30

    ·Design

    ·具体设计

    180

    180

    ·Coding

    ·具体编码

    540

    540

    ·Code Review

    ·代码复审

    30

    30

    ·Test

    ·测试

    30

    60

    Reporting

    报告

     90

     90

    ·Test Report

    ·测试报告

    40

    40

    ·Size Measurement

    ·计算工作量

    10

    10

    ·Postmortem&Process Improvement Plan

    ·事后总结并提出过程改进计划

    40

    40

     

    合计

    1200

    1200

  • 相关阅读:
    Java 内存管理机制:04 Java 内存分配策略
    Java 内存管理机制:03 垃圾收集器
    Java 内存管理机制:02 OOM异常
    蓝桥杯参赛笔记
    字符串和字符数组的输入输出种类对比
    centos6打开firewall遇到unit firewall.service is masked
    centos6打开防火墙时遇到Reason: No such file or directory
    linux配置文件
    试题 算法训练 素因子去重
    试题 算法训练 最大质因数
  • 原文地址:https://www.cnblogs.com/linanyj/p/8748745.html
Copyright © 2011-2022 走看看