[ C语言版 ] 数独计算器 [ 搜索剪枝法 ]

【原创】转载请注明出处。 【浙江大学 程序设计专题】

使用方法:按提示输入方式为9*9的矩阵,0表示未知数。

为解决这一问题,我们也尝试了两种方法,准确的说,是第一种方法太慢了,我们对它进行了优化。

方法一:
用最朴素的方法逐一枚举每一个格子,在某一个格子不能填入任何数字时回溯。
这个方法写法相对简单,但对于一些难以求解的情况,程序会非常慢,最慢的甚至无法在3秒内得出答案。如果每一个情况需要三秒钟来求解,那么要批量求解数独可能需要等好几分钟。
尽管我们将编译器的优化选项开到最高,一些情况仍需要1秒左右。

方法二:
模拟手算,当给定一道题目时,首先确定每个格子可以填那些数字,每次优先选择可选数字最少的格子。
此方法对于大多数数据能在0.1秒内求解。

 

方法一样例解释:绿色数字表示有多重可能的格子,红色数字表示唯一可能的格子,红色填充的格子表示无法填入数字。

方法二样例:

方法一代码:

  1 #include <stdio.h>
  2 #include <string.h>
  3 #include <stdlib.h>
  4 #include <time.h>
  5 #include "prnt_sudoku.h"
  6 
  7 /*Sudoku save in array Map, index counts from 0.*/
  8 int    Map[9][9],cnt;
  9 /*R<->Row  B<->Block  C<->Column*/
 10 int    R[11][11],B[11][11],C[11][11];
 11 /*characters on the left and right of output-numbers.*/
 12 /*this will make user know which numbers are given at first.*/
 13 char    C1[9][9],C2[9][9];
 14 
 15 int    Dfs(const int x,const int y)
 16 {
 17     if(x==9)
 18     {
 19         printf("\n\n\tSolution #%d:  \n\n",++cnt);
 20         Print(Map,C1,C2);
 21         /*when there are too many solutions return 1*/
 22         /*and the whole Search algorithm will stop*/
 23         if(cnt==5000) return 1;
 24         return 0;
 25     }
 26 
 27     if(Map[x][y]) { return Dfs(x+(y+1)/9,(y+1)%9); }
 28     /*if (x,y) is known, then fill the next one.*/
 29 
 30     int i;
 31     for(i=1;i<=9;++i)
 32     {
 33         /*Check if setting i in blank(x,y) is proper.*/
 34         if(R[x][i] || C[y][i] || B[x/3*3+y/3][i])continue;
 35 
 36         /*update arrays*/
 37         Map[x][y]=i;
 38         R[x][i]=1; C[y][i]=1; B[x/3*3+y/3][i]=1;
 39 
 40         if(Dfs(x+(y+1)/9,(y+1)%9)) return 1;
 41         /*this expression will fill blanks from the left-up one to */
 42         /*  the right-down one automaticly.*/
 43 
 44         /*undo*/
 45         R[x][i]=0; C[y][i]=0; B[x/3*3+y/3][i]=0;
 46         Map[x][y]=0;
 47     }
 48     return 0;
 49 }
 50 
 51 
 52 int main()
 53 {
 54     int op,T=0;
 55     system("cls");
 56     printf("Choose input/output way(1.Keyboard/2.File):  ");
 57     while(1)/*until receiving an expected input.*/
 58     {
 59         scanf("%d",&op);
 60         if(op==1)break;
 61         if(op==2)/*file input*/
 62         {
 63             char File_Name[110];
 64             printf("Please input File_Name:  ");
 65             scanf("%s",File_Name);
 66             printf("\n\tResult Will Save to Result.txt\n\n");
 67             printf("\tCalculating....\n\n");
 68             freopen(File_Name,"r",stdin);
 69             freopen("Result.txt","w",stdout);/*answer file is "Result.txt" */
 70             break;
 71         }
 72     }
 73 
 74     while(1)/*Support multi-set test, read to EOF.*/
 75     {
 76         /*Initialize*/
 77         memset(R,0,sizeof(R));
 78         memset(C,0,sizeof(C));
 79         memset(B,0,sizeof(B));
 80         memset(Map,0,sizeof(Map));
 81         cnt=0;
 82         if(op==1)printf("Please Input 9*9 matrix(0 for space):\n");
 83         int i,j,data;
 84         /*Read until EOF*/
 85         for(i=0;i<9;++i) for(j=0;j<9;++j)
 86         {
 87             if(!(~scanf("%1d",&data)))
 88             {
 89                 if(op==1)system("pause");
 90                 fclose(stdin);
 91                 return 0;
 92             }
 93             Map[i][j]=data;
 94             R[i][data]++;
 95             C[j][data]++;
 96             B[i/3*3+j/3][data]++;
 97         }
 98 
 99         printf("Test Case #%d: ",++T);
100         int f=0;/*Check if the sudoku is valid.*/
101         for(i=0;i<9;++i) for(j=1;j<=9;++j)
102             if(R[i][j]>1|| C[i][j]>1 || B[i][j]>1) f=1;
103         if(f)/*Invalid input*/
104         {
105             fprintf(stderr,"\n\t\tError in Test Case #%d: ",T);
106             fprintf(stderr,"Invalid Input.\n");
107             printf("\n\n\tFiled: No Solution Found!\n\n");
108             continue;
109         }
110 
111         /*Mark the known grids.*/
112         for(i=0;i<9;++i) for(j=0;j<9;++j)
113                 if(Map[i][j])C1[i][j]='[',C2[i][j]=']';
114                 else C1[i][j]=C2[i][j]=' ';
115 
116         int t1=clock();/*Timer*/
117         if(Dfs(0,0))
118             /*In case of costing too much time and disk storage,*/
119             /*Dfs(int,int) will find at most 5000 kinds of solution.*/
120         {
121             fprintf(stderr,"\n\t\tError in Test Case #%d: ",T);
122             fprintf(stderr,"Too much solution! Calculation has broken.\n");
123         }
124 
125         /*output the time*/
126         if(cnt==0) printf("\n\n\tFiled: No Solution Found!\n\n");
127         else printf("\n\n\t%d Solution Found In %ldms.\n\n",cnt,1000*(clock()-t1)/CLOCKS_PER_SEC);
128     }
129 
130     return 0;
131 }
View Code

方法二代码:

  1 #include <stdio.h>
  2 #include <string.h>
  3 #include <stdlib.h>
  4 #include <time.h>
  5 #include "prnt_sudoku.h"
  6 
  7 struct PII { int x,y; };
  8 
  9 /*Sudoku save in array Map, index counts from 0.*/
 10 int    Map[9][9],cnt;
 11 /*F[i][j][k] refers to that, in grid (i,j), number k is used if F[i][j][k]!=0*/
 12 int    F[9][9][10];
 13 /*characters on the left and right of output-numbers.*/
 14 /*this will make user know which numbers are given at first.*/
 15 char    C1[9][9],C2[9][9];
 16 
 17 /*Mark Row x and Column y,and the 3*3 grid that number 'data' has been used.*/
 18 void    Update(const int x,const int y,const int data)
 19 {
 20     int i,px=x/3,py=y/3;
 21     for(i=0;i<9;++i)
 22     {
 23         F[x][i][data]++;/*Row*/
 24         F[i][y][data]++;/*Column*/
 25         F[px*3+i/3][py*3+i%3][data]++;/*Block*/
 26     }
 27 }
 28 
 29 /*Undo 'Update'.*/
 30 void    Undo_update(const int x,const int y,const int data)
 31 {
 32     int i,px=x/3,py=y/3;
 33     for(i=0;i<9;++i)
 34     {
 35         F[x][i][data]--;/*Row*/
 36         F[i][y][data]--;/*Column*/
 37         F[px*3+i/3][py*3+i%3][data]--;/*Block*/
 38     }
 39 }
 40 
 41 /*Returns a pair of int (x,y) referring to the next grid should fill.*/ 
 42 struct PII Get_next()
 43 {
 44     int i,j,k,Min=0x7fffffff;
 45     struct PII pos;
 46     for(i=0;i<9;++i)
 47         for(j=0;j<9;++j)
 48         {
 49             if(Map[i][j])continue;
 50             int cc=0;/*to count how many numbers are not used*/
 51             for(k=1;k<=9;++k)
 52                 if(!F[i][j][k])cc++;
 53             if(cc==0) { pos.x=-1; return pos; }
 54             if(cc<Min)Min=cc,pos.x=i,pos.y=j;
 55             /*Choose the grid which has least numbers can use.*/
 56         }
 57     if(Min!=0x7fffffff) return pos;
 58     pos.x=-1; return pos;/*No grids can fill in*/
 59 }
 60 
 61 int    Dfs(const int rest)
 62 {
 63     if(rest==0)
 64     {
 65         printf("\n\n\tSolution #%d:  \n\n",++cnt);
 66         Print(Map,C1,C2);
 67         /*too many solutions.*/
 68         if(cnt==5000) return 1;
 69         return 0;
 70     }
 71     struct PII pos=Get_next();
 72     if(pos.x==-1) return 0;
 73     int i,list[11],top=0;
 74     /*find numbers not used, and save then in 'list'.*/
 75     for(i=1;i<=9;++i)
 76         if(!F[pos.x][pos.y][i]) list[top++]=i;
 77     for(i=0;i<top;++i)
 78     {
 79         /*Mark that number 'i' has been used*/
 80         Map[pos.x][pos.y]=list[i];
 81         Update(pos.x,pos.y,list[i]);
 82         
 83         if(Dfs(rest-1)) return 1;
 84         /*if Dfs retruns 1, there would be too many solutions*/
 85         /*stop searching and return*/
 86         
 87         /*Undo*/
 88         Undo_update(pos.x,pos.y,list[i]);
 89         Map[pos.x][pos.y]=0;
 90     }
 91     return 0;
 92 }
 93 
 94 int main()
 95 {
 96     int op,T=0;
 97     system("cls");
 98     printf("Choose input/output way(1.Keyboard/2.File):  ");
 99     while(1)/*until receiving an expected input.*/
100     {
101         scanf("%d",&op);
102         if(op==1)break;
103         if(op==2)
104         {
105             char File_Name[110];
106             printf("Please input File_Name:  ");
107             scanf("%s",File_Name);
108             printf("\n\tResult Will Save to Result.txt\n\n");
109             printf("\tCalculating....\n\n");
110             freopen(File_Name,"r",stdin);
111             freopen("Result.txt","w",stdout);
112             break;
113         }
114     }
115 
116     while(1)/*Support multi-set test, read to EOF.*/
117     {
118         memset(F,0,sizeof(F));
119         memset(Map,0,sizeof(Map));
120         cnt=0;
121         if(op==1)printf("Please Input 9*9 matrix(0 for space):\n");
122         int i,j,data;
123         
124         /*Read until EOF*/
125         for(i=0;i<9;++i) for(j=0;j<9;++j)
126         {
127             if(!(~scanf("%1d",&data)))
128             /*Only ~(-1)==0 while EOF==-1*/
129             {
130                 if(op==1)system("pause");
131                 fclose(stdin);
132                 return 0;
133             }
134             Map[i][j]=data;
135         }
136 
137         int rest=81;/*Update array 'F'. */
138         for(i=0;i<9;++i) for(j=0;j<9;++j)
139             if(Map[i][j]) Update(i,j,Map[i][j]),rest--;
140 
141         printf("Test Case #%d: ",++T);
142 
143         /*Check if the input is corret.*/
144         int f=0,k;
145         for(i=0;i<9;++i)
146         {
147             for(j=0;j<9;++j)
148             {
149                 if(Map[i][j] && F[i][j][Map[i][j]]>3) { f=1; break; }
150                 if(Map[i][j])continue;
151                 int cc=0;/*Count the numbers can use in (i,j)*/
152                 for(k=1;k<=9;++k)
153                     if(!F[i][j][k])cc++;
154                 if(cc==0) { f=1; break; }
155             }
156             if(j!=9) break;
157         }
158 
159         /*Input error*/
160         if(f)
161         {
162             fprintf(stderr,"\n\t\tError in Test Case #%d: ",T);
163             fprintf(stderr,"Invalid Input.\n");
164             printf("\n\n\tFiled: No Solution Found!\n\n");
165             continue;
166         }
167 
168         /*if a number is known, it will be output as [x]*/
169         /*otherwise, there will not be the square brackets, spaces instead.*/
170         for(i=0;i<9;++i)
171             for(j=0;j<9;++j)
172                 if(Map[i][j])C1[i][j]='[',C2[i][j]=']';
173                 else C1[i][j]=C2[i][j]=' ';
174 
175         int t1=clock();/*Timer*/
176         if(Dfs(rest))
177             /*In case of costing too much time and disk storage,*/
178             /*Dfs(int,int) will find at most 5000 kinds of solution.*/
179         {
180             fprintf(stderr,"\n\t\tError in Test Case #%d: ",T);
181             fprintf(stderr,"Too much solution! Calculation has broken.\n");
182         }
183 
184         if(cnt==0) printf("\n\n\tFiled: No Solution Found!\n\n");
185         else printf("\n\n\t%d Solution Found In %ldms.\n\n",cnt,1000*(clock()-t1)/CLOCKS_PER_SEC);
186     }
187 
188     return 0;
189 }
View Code

输出函数print_sudoku.h(上面两篇代码公用):

 1 /*
 2     *This head defines the function to print a Sudoku by a 9*9 array
 3     *Map[9][9] is the munber matrix,C1,C2 are the characters to print on the left and
 4     *  right side of the numbers.
 5 */
 6 #include <stdio.h>
 7 /*Function for printing the Sudoku table.*/
 8 void    Print(int Map[9][9],char C1[9][9],char C2[9][9])
 9 {
10     printf("\t  || A | B | C || D | E | F || G | H | I ||\n");
11     printf("\t==#########################################\n");
12     printf("\t1-##%c%d%c|%c%d%c|%c%d%c||%c%d%c|%c%d%c|%c%d%c||%c%d%c|%c%d%c|%c%d%c##\n",
13         C1[0][0], Map[0][0], C2[0][0], C1[0][1], Map[0][1], C2[0][1],
14         C1[0][2], Map[0][2], C2[0][2], C1[0][3], Map[0][3], C2[0][3],
15         C1[0][4], Map[0][4], C2[0][4], C1[0][5], Map[0][5], C2[0][5],
16         C1[0][6], Map[0][6], C2[0][6], C1[0][7], Map[0][7], C2[0][7],
17         C1[0][8], Map[0][8], C2[0][8]);
18     printf("\t--##---+---+---||---+---+---||---+---+---##\n");
19     printf("\t2-##%c%d%c|%c%d%c|%c%d%c||%c%d%c|%c%d%c|%c%d%c||%c%d%c|%c%d%c|%c%d%c##\n",
20         C1[1][0], Map[1][0], C2[1][0], C1[1][1], Map[1][1], C2[1][1],
21         C1[1][2], Map[1][2], C2[1][2], C1[1][3], Map[1][3], C2[1][3],
22         C1[1][4], Map[1][4], C2[1][4], C1[1][5], Map[1][5], C2[1][5],
23         C1[1][6], Map[1][6], C2[1][6], C1[1][7], Map[1][7], C2[1][7],
24         C1[1][8], Map[1][8], C2[1][8]);
25     printf("\t--##---+---+---||---+---+---||---+---+---##\n");
26     printf("\t3-##%c%d%c|%c%d%c|%c%d%c||%c%d%c|%c%d%c|%c%d%c||%c%d%c|%c%d%c|%c%d%c##\n",
27         C1[2][0], Map[2][0], C2[2][0], C1[2][1], Map[2][1], C2[2][1],
28         C1[2][2], Map[2][2], C2[2][2], C1[2][3], Map[2][3], C2[2][3],
29         C1[2][4], Map[2][4], C2[2][4], C1[2][5], Map[2][5], C2[2][5],
30         C1[2][6], Map[2][6], C2[2][6], C1[2][7], Map[2][7], C2[2][7],
31         C1[2][8], Map[2][8], C2[2][8]);
32     printf("\t==##===========++===========++===========##\n");
33     printf("\t4-##%c%d%c|%c%d%c|%c%d%c||%c%d%c|%c%d%c|%c%d%c||%c%d%c|%c%d%c|%c%d%c##\n",
34         C1[3][0], Map[3][0], C2[3][0], C1[3][1], Map[3][1], C2[3][1],
35         C1[3][2], Map[3][2], C2[3][2], C1[3][3], Map[3][3], C2[3][3],
36         C1[3][4], Map[3][4], C2[3][4], C1[3][5], Map[3][5], C2[3][5],
37         C1[3][6], Map[3][6], C2[3][6], C1[3][7], Map[3][7], C2[3][7],
38         C1[3][8], Map[3][8], C2[3][8]);
39     printf("\t--##---+---+---||---+---+---||---+---+---##\n");
40     printf("\t5-##%c%d%c|%c%d%c|%c%d%c||%c%d%c|%c%d%c|%c%d%c||%c%d%c|%c%d%c|%c%d%c##\n",
41         C1[4][0], Map[4][0], C2[4][0], C1[4][1], Map[4][1], C2[4][1],
42         C1[4][2], Map[4][2], C2[4][2], C1[4][3], Map[4][3], C2[4][3],
43         C1[4][4], Map[4][4], C2[4][4], C1[4][5], Map[4][5], C2[4][5],
44         C1[4][6], Map[4][6], C2[4][6], C1[4][7], Map[4][7], C2[4][7],
45         C1[4][8], Map[4][8], C2[4][8]);
46     printf("\t--##---+---+---||---+---+---||---+---+---##\n");
47     printf("\t6-##%c%d%c|%c%d%c|%c%d%c||%c%d%c|%c%d%c|%c%d%c||%c%d%c|%c%d%c|%c%d%c##\n",
48         C1[5][0], Map[5][0], C2[5][0], C1[5][1], Map[5][1], C2[5][1],
49         C1[5][2], Map[5][2], C2[5][2], C1[5][3], Map[5][3], C2[5][3],
50         C1[5][4], Map[5][4], C2[5][4], C1[5][5], Map[5][5], C2[5][5],
51         C1[5][6], Map[5][6], C2[5][6], C1[5][7], Map[5][7], C2[5][7],
52         C1[5][8], Map[5][8], C2[5][8]);
53     printf("\t==##===========++===========++===========##\n");
54     printf("\t7-##%c%d%c|%c%d%c|%c%d%c||%c%d%c|%c%d%c|%c%d%c||%c%d%c|%c%d%c|%c%d%c##\n",
55         C1[6][0], Map[6][0], C2[6][0], C1[6][1], Map[6][1], C2[6][1],
56         C1[6][2], Map[6][2], C2[6][2], C1[6][3], Map[6][3], C2[6][3],
57         C1[6][4], Map[6][4], C2[6][4], C1[6][5], Map[6][5], C2[6][5],
58         C1[6][6], Map[6][6], C2[6][6], C1[6][7], Map[6][7], C2[6][7],
59         C1[6][8], Map[6][8], C2[6][8]);
60     printf("\t--##---+---+---||---+---+---||---+---+---##\n");
61     printf("\t8-##%c%d%c|%c%d%c|%c%d%c||%c%d%c|%c%d%c|%c%d%c||%c%d%c|%c%d%c|%c%d%c##\n",
62         C1[7][0], Map[7][0], C2[7][0], C1[7][1], Map[7][1], C2[7][1],
63         C1[7][2], Map[7][2], C2[7][2], C1[7][3], Map[7][3], C2[7][3],
64         C1[7][4], Map[7][4], C2[7][4], C1[7][5], Map[7][5], C2[7][5],
65         C1[7][6], Map[7][6], C2[7][6], C1[7][7], Map[7][7], C2[7][7],
66         C1[7][8], Map[7][8], C2[7][8]);
67     printf("\t--##---+---+---||---+---+---||---+---+---##\n");
68     printf("\t9-##%c%d%c|%c%d%c|%c%d%c||%c%d%c|%c%d%c|%c%d%c||%c%d%c|%c%d%c|%c%d%c##\n",
69         C1[8][0], Map[8][0], C2[8][0], C1[8][1], Map[8][1], C2[8][1],
70         C1[8][2], Map[8][2], C2[8][2], C1[8][3], Map[8][3], C2[8][3],
71         C1[8][4], Map[8][4], C2[8][4], C1[8][5], Map[8][5], C2[8][5],
72         C1[8][6], Map[8][6], C2[8][6], C1[8][7], Map[8][7], C2[8][7],
73         C1[8][8], Map[8][8], C2[8][8]);
74     printf("\t==#########################################\n");
75     return ;
76 }
View Code

附加几个测试数据:

 1 000010054
 2 800000000
 3 000000000
 4 650400000
 5 000002730
 6 000000000
 7 210000800
 8 700000300
 9 000350000
10 
11 008900070
12 053000000
13 000000000
14 760100090
15 200000000
16 000080000
17 000020805
18 400007000
19 000000300
20 
21 800000000
22 003600000
23 070090200
24 050007000
25 000045700
26 000100030
27 001000068
28 008500010
29 090000400
30 
31 000064000
32 000000000
33 910000070
34 700000000
35 000900010
36 406008000
37 000000408
38 000002600
39 500100000
40 
41 205600000
42 100007003
43 008000000
44 040031000
45 000000820
46 000090000
47 000000000
48 030000001
49 000200500
50 
51 005300000
52 800000020
53 070010500
54 400005300
55 010070006
56 003200080
57 060500009
58 004000030
59 000009700
60 
61 005890060
62 001000005
63 400010200
64 700900006
65 500000002
66 060027050
67 008005001
68 040709500
69 200000300
View Code

 

转载于:https://www.cnblogs.com/Gster/p/9248352.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 好的,我可以为您提供一个简单的 C 语言代码来实现数独计算器。 以下是程序代码: ``` #include <stdio.h> #include <stdbool.h> #define N 9 bool isValid(int num, int x, int y, int sudoku[N][N]) { int row, col; for (row = 0; row < N; row++) if (sudoku[row][y] == num || sudoku[x][row] == num) return false; int sqrtN = (int) sqrt(N); int boxRowStart = x - x % sqrtN; int boxColStart = y - y % sqrtN; for (row = 0; row < sqrtN; row++) for (col = 0; col < sqrtN; col++) if (sudoku[boxRowStart + row][boxColStart + col] == num) return false; return true; } bool solveSudoku(int sudoku[N][N]) { int row, col; for (row = 0; row < N; row++) { for (col = 0; col < N; col++) { if (sudoku[row][col] == 0) { for (int num = 1; num <= N; num++) { if (isValid(num, row, col, sudoku)) { sudoku[row][col] = num; if (solveSudoku(sudoku)) return true; sudoku[row][col] = 0; } } return false; } } } return true; } int main() { int sudoku[N][N]; int row, col; printf("请输入数独,0表示未知数字:\n"); for (row = 0; row < N; row++) { for (col = 0; col < N; col++) { scanf("%d", &sudoku[row][col]); } } if (solveSudoku(sudoku)) { printf("\n解决方案:\n"); for (row = 0; row < N; row++) { for (col = 0; col < N; col++) { printf("%d ", sudoku[row][col]); } printf("\n"); } } else { printf("\n无解决数独问题。\n"); } return 0; } ``` 该 ### 回答2: 数独是一种数字逻辑谜题,目标是填充一个9x9的方格,使得每行、每列和每个3x3子方格内的数字都是1到9之间的唯一数字。为了编写一个数独计算器程序,我们可以使用C语言来实现。 首先,我们可以定义一个二维数组作为数独的棋盘。每个元素代表一个方格,该方格上的数字可以是1到9之间的任何一个数字。我们可以使用0来表示空方格。 接下来,我们可以编写一个函数来验证给定的数字是否可以放置在给定的方格上。这个函数需要检查给定的数字是否在所在行、所在列和所在子方格内已经存在。如果数字不存在,那么该数字可以放置在对应的方格上。 然后,我们可以编写一个函数来解决数独问题。该函数可以通过遍历棋盘中的每个方格,并尝试填充1到9之间的数字,来递归地寻找可行的解决方案。在每次尝试填充数字前,我们需要先调用验证函数来确认该数字是否可以放置在对应的方格上。如果遍历完所有的方格并找到解决方案,程序将输出这个解决方案。 最后,我们可以编写一个主函数来调用解决函数,并显示数独的解决方案。在主函数中,我们可以先手动输入数独的初始状态,然后调用解决函数来找到解决方案。如果找到了解决方案,程序将将其打印出来。如果没有找到解决方案,则可以输出一条消息提示数独无解。 这就是一个简单的数独计算器程序的C语言实现。通过定义棋盘数组、编写验证函数和解决函数,并在主函数中调用它们,我们可以实现一个能够求解数独问题的程序。 ### 回答3: 数独计算器可以使用C语言编写,下面是一个简单的实现示例: ```c #include <stdio.h> #include <stdbool.h> // 定义数独的大小为9x9的常量 #define SIZE 9 // 检查数字num是否在行row上已存在 bool isRowSafe(int puzzle[SIZE][SIZE], int row, int num) { for (int col = 0; col < SIZE; col++) { if (puzzle[row][col] == num) { return false; } } return true; } // 检查数字num是否在列col上已存在 bool isColSafe(int puzzle[SIZE][SIZE], int col, int num) { for (int row = 0; row < SIZE; row++) { if (puzzle[row][col] == num) { return false; } } return true; } // 检查数字num是否在9x9的子方格中已存在 bool isBoxSafe(int puzzle[SIZE][SIZE], int startRow, int startCol, int num) { for (int row = 0; row < 3; row++) { for (int col = 0; col < 3; col++) { if (puzzle[row + startRow][col + startCol] == num) { return false; } } } return true; } // 检查是否可以将数字num放置到指定位置(row, col) bool isSafe(int puzzle[SIZE][SIZE], int row, int col, int num) { return isRowSafe(puzzle, row, num) && isColSafe(puzzle, col, num) && isBoxSafe(puzzle, row - row % 3, col - col % 3, num); } // 查找未填数字的位置 bool findUnassignedLocation(int puzzle[SIZE][SIZE], int *row, int *col) { for (*row = 0; *row < SIZE; (*row)++) { for (*col = 0; *col < SIZE; (*col)++) { if (puzzle[*row][*col] == 0) { return true; } } } return false; } // 使用回溯解决数独 bool solveSudoku(int puzzle[SIZE][SIZE]) { int row, col; if (!findUnassignedLocation(puzzle, &row, &col)) { return true; // 所有位置已填满 } for (int num = 1; num <= SIZE; num++) { if (isSafe(puzzle, row, col, num)) { puzzle[row][col] = num; if (solveSudoku(puzzle)) { return true; } puzzle[row][col] = 0; // 撤销上一次的选择 } } return false; // 无解 } // 打印数独 void printSudoku(int puzzle[SIZE][SIZE]) { for (int row = 0; row < SIZE; row++) { for (int col = 0; col < SIZE; col++) { printf("%d ", puzzle[row][col]); } printf("\n"); } } int main() { int puzzle[SIZE][SIZE] = { {5, 3, 0, 0, 7, 0, 0, 0, 0}, {6, 0, 0, 1, 9, 5, 0, 0, 0}, {0, 9, 8, 0, 0, 0, 0, 6, 0}, {8, 0, 0, 0, 6, 0, 0, 0, 3}, {4, 0, 0, 8, 0, 3, 0, 0, 1}, {7, 0, 0, 0, 2, 0, 0, 0, 6}, {0, 6, 0, 0, 0, 0, 2, 8, 0}, {0, 0, 0, 4, 1, 9, 0, 0, 5}, {0, 0, 0, 0, 8, 0, 0, 7, 9} }; if (solveSudoku(puzzle)) { printSudoku(puzzle); } else { printf("该数独无解\n"); } return 0; } ``` 这个程序可以解决一个9x9的数独问题,并在控制台上打印出结果。在该示例中,我们使用了回溯来解决数独问题。其中,`solveSudoku`函数递归地尝试所有可能的数字组合,并使用`isSafe`函数来检查每个数字在行、列、子方格中是否是唯一的。如果数独有解,则在解决方案找到后,`printSudoku`函数会将答案打印出来。如果数独无解,则会输出提示信息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值