Github地址:https://github.com/cfafa2018/SudokuProject
思路:
根据题目要求,摘取出一些需要解决的问题,差不多也就是整体的解题思路。
代码分成了两大块,生成数独和解数独部分,还有一些小的函数。
(1)命令行中使用 -c和-s,识别并根据命令生成或读取相应的文件。
用ofstream和C语言里面的fopen。对于-c和-s以及一些错误的输入,例如:-c ab 进行处理,提示 Wrong input。利用main函数里的argc和argv两个参数解决。
(2)生成数独。
根据要求,数独左上角的第一个数应该为 (0 + 8)% 9 + 1 = 9,后面8个位置用剩下的8个数进行全排列。然后下面的8行可以分别通过第一行右移得到。(借鉴了同学的思路)这里采用C++实现。
1 if(AllisNum(argv[2])){
2 int shudu[9][9]={0},arr[]={1,2,3,4,5,6,7,8};
3 shudu[0][0] = 9;//数独第一个数字为9
4 for(int i = 0; i < atoi(argv[2]); i ++){
5 next_permutation(arr, arr+8);
6 for(int j =0; j < 8; j ++){//将arr数组里排列好的数赋给shudu第一行
7 shudu[0][j+1] = arr[j];
8 }
9 int num[9]={0,3,6,1,4,7,2,5,8};
10 int temp[9];
11 memcpy(&temp, &shudu[0], sizeof(shudu[0]));
12 for(int j=0; j < 9; j ++){//通过第一行进行下面8列的移数
13 int n =9;
14 RightShift(shudu[0], n, num[j]);
15 for(int k = 0; k < 8; k ++){//输出数据
16 write<<"shudu[0][k] ";
17 }
18 write<<"shudu[0][k]\n";
19 memcpy(&shudu[0], &temp, sizeof(temp));
20 }
21 write<<"\n";
22 }
23 }
24 else write<<"Wrong input\n";
25 }
(3)解数独。
根据数独的求解规则,可以知道,每一小格要求填上1~9中的一个数,而且要求在同一行,同一列,以及包括这一小格在内的所有的3X3的九宫格都不在包含这个数。按照求解规则进行填数,所有小格循环进行。如果遇到无解的小格,则回到上一个点,还不行就一直回溯,直到得到解为止。下面用回溯法来进行求解。
1 void backtrace(int count){
2 if(count == 81){
3 for(int i = 0; i < 9; ++i){
4 for(int j = 0; j < 8; ++j){
5
6 output<<map[i][j];
7 output<<" ";
8 }
9 output<<map[i][8]<<endl;
10 }
11 output<<"\n";
12 return;
13 }
14 int row = count / 9;
15 int col = count % 9;
16 if(map[row][col] == 0){
17 for(int i = 1; i <= 9; ++i){
18 map[row][col] = i;//赋值
19 if(isPlace(count)){//可以放
20 backtrace(count+1);//进入下一层
21 }
22 }
23 map[row][col] = 0;//回溯
24 }
25 else{
26 backtrace(count+1);
27 }
28 }
(4) 性能分析。
生成1000个数独
解100个数独
来源:oschina
链接:https://my.oschina.net/u/4313381/blog/4008880