C++求解数独

  1 #include <iostream>
  2 using namespace std;
  3 #include <vector>
  4 #include <utility>
  5 const int MAX_SIZE = 9;
  6
  7 //int result[MAX_SIZE][MAX_SIZE] = {
  8 //    {1, 2, 3, 4, 5, 6, 7, 8, 9},
  9 //    {4, 6, 7, 1, 8, 9, 3, 2, 5},
 10 //    {5, 8, 9, 2, 3, 7, 1, 4, 6},
 11 //    {3, 1, 6, 5, 4, 8, 2, 9, 7},
 12 //    {2, 7, 8, 9, 6, 1, 5, 3, 4},
 13 //    {9, 4, 5, 7, 2, 3, 8, 6, 1},
 14 //    {7, 3, 1, 6, 9, 2, 4, 5, 8},
 15 //    {8, 9, 4, 3, 7, 5, 6, 1, 2},
 16 //    {6, 5, 2, 8, 1, 4, 9, 7, 3}
 17 //};
 18
 19 int result[MAX_SIZE][MAX_SIZE] = {
 20     {0, 6, 0, 5, 9, 3, 0, 0, 0},
 21     {9, 0, 1, 0, 0, 0, 5, 0, 0},
 22     {0, 3, 0, 4, 0, 0, 0, 9, 0},
 23     {1, 0, 8, 0, 2, 0, 0, 0, 4},
 24     {4, 0, 0, 3, 0, 9, 0, 0, 1},
 25     {2, 0, 0, 0, 1, 0, 6, 0, 9},
 26     {0, 8, 0, 0, 0, 6, 0, 2, 0},
 27     {0, 0, 4, 0, 0, 0, 8, 0, 7},
 28     {0, 0, 0, 7, 8, 5, 0, 1, 0}
 29 };
 30
 31 int index[3][3][2] =
 32 {
 33     {
 34         {0,0},{0,3},{0,6}
 35     },
 36     {
 37         {3,0},{3,3},{3,6}
 38     },
 39     {
 40         {6,0},{6,3},{6,6}
 41     }
 42 };
 43
 44 int one_to_nine[9] = {0};
 45
 46 bool try_number[9];
 47 vector<int> try_number_vector;
 48 vector<vector<vector<int> > > loop_all;
 49 vector<pair<vector<int>,pair<int,int> > > loop_line;
 50 typedef vector<pair<vector<int>,pair<int,int> > >::iterator  loop_line_itr_type;
 51 vector<int> loop_array;
 52 vector<int> loop_next;
 53 int loop_length =0;
 54 int total_try = 0;
 55 long long total_case = 1;
 56
 57 void clean_try_number(void);
 58 void get_line_number(int x);
 59 void get_column_number(int y);
 60 void get_mutrix_number(int x, int y);
 61 void print_try_number(void);
 62 bool check_shudu(void);
 63
 64
 65 void clean_try_number(void)
 66 {
 67     for (int i=0; i< 9; ++i)
 68     {
 69         try_number[i] = true;
 70     }
 71     try_number_vector.clear();
 72 }
 73
 74 void get_line_number(int x)
 75 {
 76     for (int i=0; i < 9; ++i)
 77     {
 78         //这个数字已经出现
 79         if (result[x][i] != 0)
 80         {
 81             //cout<<"line_number fined:["<<x<<"]["<<i<<"]: "<<result[x][i]<<endl;
 82             try_number[result[x][i]-1] = false;
 83         }
 84     }
 85 }
 86
 87 void get_column_number(int y)
 88 {
 89     for (int i=0; i < 9; ++i)
 90     {
 91         //这个数字已经出现
 92         if (result[i][y] != 0)
 93         {
 94             //cout<<"column_number fined:["<<i<<"]["<<y<<"]: "<<result[i][y]<<endl;
 95             try_number[result[i][y]-1] = false;
 96         }
 97     }
 98 }
 99
100 void get_mutrix_number(int x, int y)
101 {
102     //cout<<"small matrix: ["<<x<<"] ["<<y<<"]\n";
103     for (int i=0; i<3; ++i)
104     {
105         for (int j=0;j<3;++j)
106         {
107             if (result[x+i][y+j] != 0)
108             {
109                 //cout<<"matrix fined:["<<x+i<<"]["<<y+j<<"]: "<<result[x+i][y+j]<<endl;
110                 try_number[result[x+i][y+j]-1] = false;
111             }
112         }
113     }
114 }
115
116 void get_all_matrix_number(int x, int y)
117 {
118     //cout<<"big matrix: ["<<x<<"] ["<<y<<"] ->";
119     get_mutrix_number(x/3*3,y/3*3);
120 }
121 void get_try_number(int x, int y)
122 {
123     if(result[x][y] != 0)
124     {
125         return;
126     }
127     clean_try_number();
128     get_line_number(x);
129     get_column_number(y);
130     get_all_matrix_number(x,y);
131
132     for (int i=0; i<9; ++i)
133     {
134         if (try_number[i] == true)
135         {
136             try_number_vector.push_back(i+1);
137         }
138     }
139 }
140
141 void print_try_number(void)
142 {
143     cout<<"try_number now is :";
144     for (int i=0; i<try_number_vector.size();++i)
145     {
146         cout<<try_number_vector[i]<<" ";
147     }
148     cout<<endl;
149 }
150
151 void use_one_try_number(int x, int y, int vaule)
152 {
153     result[x][y] = vaule;
154 }
155
156 void go_back(int x, int y, int value)
157 {
158     result[x][y] = value;
159 }
160
161 void print_result(void)
162 {
163     for (int i=0; i< 9; ++i)
164     {
165         for (int j=0; j<9; ++j)
166         {
167             cout<<result[i][j]<<" ";
168         }
169         cout<<endl;
170     }
171     cout<<endl;
172 }
173
174 void print_loop_line(void)
175 {
176     cout<<"loop_line:"<<endl;
177     for(int i=0;i<loop_line.size();++i)
178     {
179         cout<<"loop_line["<<i<<"]:";
180         for(int j=0;j<loop_line[i].first.size();++j)
181         {
182             cout<<loop_line[i].first[j]<<" ";
183         }
184         cout<<" ->["<<loop_line[i].second.first<<"]["<<loop_line[i].second.second<<"]\n";
185     }
186 }
187
188 bool finish_shudu(void)
189 {
190     for (int i=0; i< 9; ++i)
191     {
192         for (int j=0; j<9; ++j)
193         {
194             if (result[i][j] == 0)
195             {
196                 return false;
197             }
198         }
199     }
200 }
201
202
203
204 bool loop_end(void)
205 {
206     for(int i=0;i<loop_length;++i)
207     {
208         if(loop_next[i] != loop_array[i]-1)
209         {
210             return false;
211         }
212     }
213     return true;
214 }
215
216 //////////////////////////////////////////////////////////////////////////////
217 void make_loop_line(void)
218 {
219     loop_line.clear();
220     for(int i=0;i<9; ++i)
221     {
222         vector<vector<int> > temp_loop_line;
223         for(int j=0;j<9; ++j)
224         {
225             //cout<<"get_try_number["<<i<<"]["<<j<<"]:";
226             get_try_number(i,j);
227             temp_loop_line.push_back(try_number_vector);
228             if(try_number_vector.size()!=0)
229             {
230                 loop_line.push_back(make_pair(try_number_vector,make_pair(i,j)));
231             }
232             //print_try_number();
233             clean_try_number();
234         }
235     }
236 }
237
238 void init(void)
239 {
240     //make loop_line loop_all;
241     make_loop_line();
242
243     //cout<<"loop_all:"<<endl;
244     for(int i=0;i<loop_all.size();++i)
245     {
246         for(int j=0;j<loop_all[i].size();++j)
247         {
248             //cout<<"loop_all postion["<<i<<"]["<<j<<"]:";
249             for(int k=0;k<loop_all[i][j].size();++k)
250             {
251                 //cout<<loop_all[i][j][k]<<" ";
252             }
253             //cout<<endl;
254         }
255         //cout<<endl;
256     }
257
258     print_loop_line();
259
260
261     loop_length = loop_line.size();
262     cout<<"loop_length:"<<loop_length<<endl;
263
264     cout<<"init loop_array:";
265     for(int i=0;i<loop_length;++i)
266     {
267         loop_array.push_back(loop_line[i].first.size());
268         total_case *= loop_line[i].first.size();
269     }
270     for(int i=0;i<loop_array.size();++i)
271     {
272         cout<<loop_array[i]<<"*";
273     }
274     cout<<"\n="<<total_case<<endl;
275
276     cout<<"init loop_next:";
277     for(int i=0;i<loop_length;++i)
278     {
279         loop_next.push_back(0);
280     }
281     for(int i=0;i<loop_next.size();++i)
282     {
283         cout<<loop_next[i]<<" ";
284     }
285     cout<<endl;
286 }
287
288 void set_sole_to_position(int x,int y,int sole_value)
289 {
290     result[x][y] = sole_value;
291 }
292
293 bool exist_sole(void)
294 {
295     for(loop_line_itr_type itr=loop_line.begin();itr != loop_line.end();++itr)
296     {
297         if(itr->first.size() == 1)
298         {
299             return true;
300         }
301     }
302     return false;
303 }
304 void loop_set_sole()
305 {
306     int set_sole_times = 0;
307     while(exist_sole())
308     {
309         cout<<"set_sole_to_position "<< ++set_sole_times <<" s time\n";
310         //把当前loop_line中所有只有一种可能的位置,并将数字放进去
311         for(loop_line_itr_type itr=loop_line.begin();itr != loop_line.end();)
312         {
313             if(itr->first.size() == 1)
314             {
315                 int erased_value = itr->first[0];
316                 int x = itr->second.first;
317                 int y = itr->second.second;
318                 set_sole_to_position(x,y,erased_value);
319                 itr = loop_line.erase(itr);
320                 cout<<"erased: loop_line["<<x<<"]["<<y<<"]="<<erased_value<<endl;
321             }
322             else
323             {
324                 ++itr;
325             }
326         }
327         make_loop_line();
328         //print_loop_line();
329     }
330 }
331 void do_shudu(void)
332 {
333     cout<<"init:"<<endl;
334     init();
335
336     //剪枝
337     //
338     loop_set_sole();
339     cout<<"now result is:"<<endl;
340     print_result();
341     if(finish_shudu())
342     {
343         cout<<"OK I FINED !"<<endl;
344     }
345     else
346     {
347         cout<<"cao wrong !"<<endl;
348     }
349 }
350 bool check_one_to_nine(void)
351 {
352     bool flag = true;
353     for(int i=0; i<9; ++i)
354     {
355         if(one_to_nine[i]>=2)
356         {
357             flag =  false;
358             break;
359         }
360     }
361
362     for(int i = 0; i< 9; ++i)
363     {
364         one_to_nine[i] = 0;
365     }
366     return flag;
367 }
368
369 bool check_line(int start)
370 {
371     for(int i= 0; i<9; ++i)
372     {
373         ++one_to_nine[result[start][i]-1];
374     }
375     if(check_one_to_nine() == false)
376     {
377         //cout<<"check_line:"<<start<<" failed"<<endl;
378         return false;
379     }
380     else
381     {
382         //cout<<"check_line:"<<start<<" OK"<<endl;
383         return true;
384     }
385 }
386
387 bool check_column(int start)
388 {
389     for(int i= 0; i<9; ++i)
390     {
391         ++one_to_nine[result[i][start]-1];
392     }
393
394     if(check_one_to_nine() == false)
395     {
396         //cout<<"check_column:"<<start<<" failed"<<endl;
397         return false;
398     }
399     else
400     {
401         //cout<<"check_column:"<<start<<" OK"<<endl;
402         return true;
403     }
404 }
405
406 bool check_one_matrix(int xStart, int yStart)
407 {
408     for(int i=0; i<3; ++i)
409     {
410         for(int j=0; j<3; ++j)
411         {
412             ++one_to_nine[result[xStart+i][yStart+j]-1];
413         }
414     }
415     if(false == check_one_to_nine())
416     {
417         //cout<<"check_one_matrix:"<<xStart<<","<<yStart<<" failed"<<endl;
418         return false;
419     }
420     else
421     {
422         //cout<<"check_one_matrix:"<<xStart<<","<<yStart<<" OK"<<endl;
423         return true;
424     }
425 }
426
427 bool check_all_matrix()
428 {
429
430
431     for(int i=0;i<3;++i)
432     {
433         for(int j=0;j<3;++j)
434         {
435             if(false == check_one_matrix(index[i][j][0], index[i][j][1]))
436                 return false;
437         }
438     }
439     return true;
440 }
441
442 bool check_shudu()
443 {
444     for(int i=0;i<9;++i)
445     {
446         if(check_line(i) == false || check_column(i) == false)
447         {
448             return false;
449         }
450     }
451
452     if(check_all_matrix() == false)
453     {
454         return false;
455     }
456
457     return true;
458 }
459
460 int main(int , char**)
461 {
462     cout<<"Hello World!"<<endl;
463
464     do_shudu();
465
466     return 1;
467
468 }

时间: 2024-08-04 04:20:13

C++求解数独的相关文章

求解数独回溯算法

实现的java代码如下: //判断a[i][j]取值val是否有效 public boolean isValid(int[][] a, int i, int j, int val){ //判断是否跟同行冲突 for(int j1=0;j1<9;j1++){ if(a[i][j1]==val) return false; } //判断是否跟同列冲突 for(int i1=0;i1<9;i1++){ if(a[i1][j]==val) return false; } //找出a[i][j]所在的九

回溯法求解数独算法(C语言)

没有对输入的待解数独进行一般性验证(同一行.一列以及同一个小九宫格都不能出现重复数字) 算法利用回溯的思想: 从第一个空白处开始,找到其候选解(排除同行.同列以及同一小九宫格的所有出现过的数字,剩下未出现的数字都是候选解)的第一个值填入数独. 对第二个空白执行第一步(前面所填入的数字对此空白处有影响). 当出现某个空白的候选解个数为0时,就开始回溯,找到第一个候选解多于一个的,将其在使用的候选解设为不可取(本程序取值为-1),找到其下一个候选解,继续上面的步骤! 直到所有空白处填满,运算完成,输

LeetCode 37 Sudoku Solver(求解数独)

题目链接: https://leetcode.com/problems/sudoku-solver/?tab=Description Problem : 解决数独问题,给出一个二维数组,将这个数独进行求解. 思路: 嵌套循环,三层循环体,每一行,每一列,填入从1到9的数字.判断填入之后是否合理 判断数独是否合理的函数 参考代码: package leetcode_50; /*** * * @author pengfei_zheng * 求解数独问题 */ public class Solutio

[LeetCode] Sudoku Solver 求解数独

Write a program to solve a Sudoku puzzle by filling the empty cells. Empty cells are indicated by the character '.'. You may assume that there will be only one unique solution. A sudoku puzzle... ...and its solution numbers marked in red. 这道求解数独的题是在之

[LeetCode] 37. Sudoku Solver 求解数独

Write a program to solve a Sudoku puzzle by filling the empty cells. A sudoku solution must satisfy all of the following rules: Each of the digits 1-9 must occur exactly once in each row. Each of the digits 1-9 must occur exactly once in each column.

高效算法求解数独

title: 高效算法求解数独 date: 2019-12-26 17:55:16 tags: 数据结构与算法 categories: 数据结构与算法 背景 ??之前上python课的时候,有一次实验是求解数独,要求时间复杂度要低:为此老师讲解了一个高效的数独算法,我觉得算法挺有意思的,写篇博客记录一下. 描述 首先需要知晓数独的两个规则: 若某个位置的值已经确定,那么,和这个位置在同一行,同一列,同一个3×3的格子,都不能填写这个值,比如,九宫格(1,1)位置的值为2,那么,第一行,第一列,以

求解数独的所有解法,java编程实现

数独是一种考验眼力和逻辑的小游戏,关键在这个"独"字上,横竖不能重复,方块不能重复.今天我给大家介绍一种利用"循环+递归+回溯"的办法来用Java程序替我们完成数独. 先给代码随后讲解: 1 import java.util.HashMap; 2 import java.util.Map; 3 4 public class T2 { 5 public static final int N=3; 6 public static void main(String[] a

求解数独

dfs爆搜,从第一个空开始试探 bool check(int sodu[10][10], int n, int m) { int heng = n / 9; int zong = n % 9; int a = heng / 3, b = zong / 3; a *= 3, b *= 3; int i, j; for (i = 0; i < 9; i++) if (sodu[i][zong] == m) return false; for (i = 0; i < 9; i++) if (sodu

leetcode python 037 求解数独

import numpy as npimport syssys.setrecursionlimit(1000) #例如这里设置为一百万 def get1(n):    if n<3:        return 0    if n<6:        return 3    return 6 def get2(n):    if n<3:        return 3    if n<6:        return 6    return 9 def get3(arr,i,j)