利用程序随机构造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个已解答的数独棋盘的主要内容,如果未能解决你的问题,请参考以下文章