利用程序随机构造N个已解答的数独棋盘

Posted pljy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了利用程序随机构造N个已解答的数独棋盘相关的知识,希望对你有一定的参考价值。

根据题目要求,所写2.cpp代码如下:(本部分代码主要是判断输入是否合法,然后把数独输出到sudotiku.exe文本中)

 1 #include "2.h"
 2 #include<iostream>
 3 #include<ctime>
 4 #include<fstream>
 5 #include <string>
 6 #include <sstream>
 7 #include <cstdlib>
 8 
10 int main(int argc,char** argv)
11 {
12     int n;
13     FILE* fp;
14     if (argc == 3) 
15     {
16         if (strcmp(argv[1],"-c")==0) //-c:
17         {
18             if (!stringtonum(argv[2])) 
19             {
20                 cout << "输入有错" << endl<<"重新输入:";
21                 cin >> n;
22             }
23             else 
24             {
25                 n = atoi(argv[2]);
26             }
27         }
28         else
29         {
30             cout << "输入有错" << endl << "重新输入:";
31             cin >> n;
32         }
33     }
34     else
35     {
36         cout << "输入有错" << endl << "重新输入:";
37         cin >> n;
38     }
39     while (n == 0) 
40     {
41         cout << "输入有错" << endl << "重新输入:";
42         cin >> n;
43     }
44    
45    
46           fp = fopen("sudotiku.txt","w");
47         back(0,fp);
48         fclose(fp);
49   return 0;
50 }

2.h代码如下:(本部分代码主要的功能就是生成数独棋盘与用回溯法解数独)

  1 #ifndef __SUDOKU__ 
  2 #define __SUDOKU__
  3 #include <iostream>
  4 #include <stdio.h>
  5 #include <string.h>
  6 #include <math.h>
  7 
  8 using namespace std;
  9 
 10 int shudu[9];
 11 int sudotiku[9][9] = {0};
 12 void suiji()
 13 {
 14     int i, j;
 15     for (i = 0; i < 9; i++)
 16         shudu[i] = 0;
 17     for (i = 0; i < 9; i++)
 18     {
 19         shudu[i] = rand() % 9 + 1;//得到随机数
 20         for (j = 0; j < i; j++)
 21         {
 22             if (shudu[i] == shudu[j])//如果重复,重新产生随机数
 23             {
 24                 --i;
 25                 break;
 26             }
 27         }
 28     }
 29 
 30 }
 31 int sum = 0;
 32 int num = 0;
 33 int flag = 0;
 34 char ch[200];
 35 
 36 bool stringtonum(string str)
 37 {
 38   int count = 0;
 39   int stringlen = str.length();
 40   while(stringlen)
 41   {
 42     if(48>str[stringlen-1] || str[stringlen-1]>57)
 43     {
 44       return false;
 45     }
 46     num += (str[stringlen-1]-48)*pow(10,count);
 47     count++;
 48     stringlen--;
 49     if(num - 1> 1000000)return false;
 50   }
 51   return true;
 52 }
 53 bool bijiao(int count)
 54 {
 55   int x = count/9;
 56   int y = count%9;
 57   int k;
 58 //与同一列比较
 59   for(k = 0; k < 9; ++k)
 60   {
 61       if(sudotiku[x][k]==sudotiku[x][y] && k!=y)
 62     {
 63       return false;
 64     }
 65   }
 66   for(k = 0; k< 9; ++k)//与同一行比较
 67   {
 68       if(sudotiku[k][y]==sudotiku[x][y] && k!=x)
 69     {
 70       return false;
 71     }
 72   }
 73   //是否满足三小方格规则
 74   int gctx = x/3*3;
 75   int gcty = y/3*3;
 76   int shudu;
 77   for(k= gctx; k< gctx + 3; ++k)
 78   {
 79       for( shudu = gcty; shudu < gcty + 3; ++shudu)
 80       {
 81           if(sudotiku[k][shudu] == sudotiku[x][y] && k!= x)
 82         {
 83               return false;
 84         }
 85       }
 86     
 87   }
 88   return true;
 89 }
 90 
 91 void back(int count,FILE* fp)
 92 {
 93     if(count == 81)
 94     {
 95         sum++;
 96         if(sum >num) exit(0);
 97 
 98         for(int i = 0;i<9;++i)
 99       {
100           for(int j = 0;j<9;++j)
101           {
102                 ch[flag++] = sudotiku[i][j]+0;
103                 ch[flag++] =  ;
104           }
105           ch[flag++] = \n;
106       }
107             ch[flag++] = \n;
108             fputs(ch,fp);
109             flag = 0;
110       return ;
111     }
112 
113     int row = count/9;
114     int col = count%9;
115     if(sudotiku[row][col] == 0)
116     {
117         for(int i = 1;i<=9;++i)
118         {
119             sudotiku[row][col] = i;
120             if(bijiao(count))
121             {
122                 back(count+1, fp);
123             }
124             sudotiku[row][col]=0;
125         }
126         sudotiku[row][col] = 0;
127     }
128     else
129     {
130         back(count+1,fp);
131     }
132 }
133 
134 
135 #endif 

此次代码的编写是在vc++6.0环境下运行的,程序运行后在自动生成的Debug文件夹中的sudotiku.ilk文件中按住shift+单击右键  选“在此处打开命令窗口”然后输入sudotiku.exe -c  n(要随机生成数独的个数)(F:\啊啊\sudotiku\Debug\sudotiku.exe -c 2)

则可在sudotiku.txt文件中查看生成的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 1 4 3 6 5 8 9 7 
3 6 5 8 9 7 2 1 4 
8 9 7 2 1 4 3 6 5 
5 3 1 6 4 2 9 7 8 
6 4 2 9 7 8 5 3 1 
9 7 8 5 3 1 6 4 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 1 4 3 6 5 8 9 7 
3 6 5 8 9 7 2 1 4 
8 9 7 2 1 4 3 6 5 
5 3 1 6 4 2 9 7 8 
6 4 8 9 7 1 5 3 2 
9 7 2 5 3 8 6 4 1 

此次作业完整代码可在http//coding.net/u/dhlg201810812010/p/sudotiku1/git查看。

 

心得:在本次的作业当中遇到的困难与对应的解决方法如下:

1、输入要随机生成的个数为2时,出来的随机数独只有一个(解决办法:if(sum >=num)  exit(0 ) 改为 if(sum>num)exit(0))

2、忘记怎么在vc环境下建工程,创建项目。(解决办法:百度)

3、在2.cpp的代码的主函数那里,一开始的想法是定义一个字符串string,把argv[1]赋值给string1 然后与“-c”做比较,然后运行报错。(解决办法:用strcmp函数直接把argv[1]与“-c”作比较,即strcmp(argv[1],"-c")==0)

4、知道解决数独问题要用到的算法是回溯法,但是回溯法这个算法我不太会写。(解决办法:百度,看别人怎么写的,理解别人写代码的思路,然后自己尝试写)

 

这次作业整个做下来耗时挺长的,共花了28个小时,但是却学到了好多东西,对C++的知识重新巩固了下,知道了理解了回溯法这个算法,学习了一个新软件Git,运用这个软件知道了怎么创建项目和上传自己写的代码。其实一开始我是觉得这道作业我做不出来的,但是花时间每天看懂一点,多思考点,还是每天都会有收获的。

 

课外任务作业:

截止到至今,我对c语言和汇编语言比较熟悉,c++语言较为熟悉,对《数据结构》这门课程学习的较好,但就我目前这水平,离一个合格的IT专业毕业生相差十万八千里,还得不断努力再努力,就比如《数据结构》吧,知道算法但却不会如何运用。c语言的指针精华还没有学透。

在链接的调查表中,我觉得这五项技能对我很重要:1、程序理解 2、programming language  3、效能分析和改进 4、Design 5、对编程整体的理解    这五个方面我现在的水平只停留在看得懂的层面上,特别是在效能分析和改进这块特别欠缺。我希望在本课程结束时,我能熟练的运用c++语言写代码,对程序的理解更近一个层次,在看的懂别人代码的情况下,还能够优化那些代码,对每次写代码都能够把每个模块设计好,做到读起来清晰明了易修改。

以上是关于利用程序随机构造N个已解答的数独棋盘的主要内容,如果未能解决你的问题,请参考以下文章

利用程序随机构造N个已解答的数独棋盘

利用程序随机构造N个已解答的数独棋盘

利用程序随机构造N个已解答的数独棋盘

150+行Python代码实现带界面的数独游戏

C语言折半查找法详细代码(假如有10个已排好序的数)

在 Java 中使用 JPanel 的数独板