数独的C++解法
Posted Ren.Yu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数独的C++解法相关的知识,希望对你有一定的参考价值。
grid.h
1 #ifndef _GRID_H_ 2 #define _GRID_H_ 3 4 #include <set> 5 #include <cstddef> 6 7 class Grid { 8 public: 9 Grid() { for ( int i = 0; i < 9; i++ ) { value_s.insert(i + 1); } } 10 11 bool set( int value ) { 12 if ( !contain(value) ) { return false; } 13 value_s.clear(); 14 value_s.insert(value); 15 return true; 16 } 17 18 size_t size() { return value_s.size(); } 19 20 int value() { 21 if ( 1 == size() ) { return *(value_s.begin()); } 22 return -1; 23 } 24 25 bool remove(int value) { 26 value_s.erase(value); 27 if ( 0 == size() ) { return false; } 28 return true; 29 } 30 31 int value( int index ) { 32 if ( index >= size() ) { return -1; } 33 std::set<int>::iterator it = value_s.begin(); 34 for ( int i = 0; i < index; i++ ) { it ++; } 35 return *it; 36 } 37 private: 38 std::set<int> value_s; 39 40 bool contain( int value ) { return ( value_s.end() != value_s.find(value) ); } 41 }; 42 43 #endif
sudoku.h
1 #ifndef _SUDOKU_H_ 2 #define _SUDOKU_H_ 3 4 #include "grid.h" 5 6 struct PosVal { 7 int i; 8 int j; 9 int val; 10 PosVal( int _i, int _j, int _val ) : i(_i), j(_j), val(_val) {} 11 bool operator < (const PosVal &pos_val) const { 12 return ( i == pos_val.i ) ? (j < pos_val.j ) : ( i < pos_val.i ); 13 } 14 }; 15 16 struct Result { 17 int value[9][9]; 18 bool operator < (const Result &result) const { 19 for ( int i = 0; i < 9; i++ ) { 20 for ( int j = 0; j < 9; j++ ) { 21 if (value[i][j] < result.value[i][j]) { return true; } 22 } 23 } 24 return false; 25 } 26 }; 27 28 class Sudoku { 29 public: 30 Sudoku() { 31 for ( int i = 0; i < 9; i++ ) { 32 for ( int j =0; j < 9; j++ ) { 33 fixed[i][j] = false; 34 } 35 } 36 } 37 38 bool Init( const std::set<PosVal>& pos_val_s) { 39 for ( std::set<PosVal>::iterator it = pos_val_s.begin(); it != pos_val_s.end(); it++ ) { 40 if ( ! set( it->i, it->j, it->val ) ) { return false; } 41 } 42 return true; 43 } 44 45 void calc( std::set<Result>& result_s ) { 46 if ( !trim() ) { return; } 47 if ( all_grid_fixed() ) { fill_result( result_s ); return; } 48 int i, j; 49 find_unfixed_min_size_grid(i, j); 50 for ( int loop = 0; loop < size(i, j); loop ++ ) { 51 Sudoku s( *this ); 52 if ( !s.set(i, j, value(i, j, loop)) ) { return; } 53 s.calc( result_s ); 54 } 55 } 56 private: 57 Grid grid[9][9]; 58 bool fixed[9][9]; 59 60 bool set(int i, int j, int value) { 61 if ( !grid[i][j].set(value) ) { return false; } 62 if ( !trim(i, j, value) ) { return false; } 63 fixed[i][j] = true; 64 return true; 65 } 66 67 size_t size(int i, int j) { return grid[i][j].size(); } 68 69 int value(int i, int j ) { return grid[i][j].value(); } 70 71 int value(int i, int j, int index) { return grid[i][j].value(index); } 72 73 bool trim(int ii, int jj, int value) { 74 for (int j = 0; j < 9; j++) { 75 if ( j != jj ) { if ( !grid[ii][j].remove(value) ) { return false; } } 76 } 77 for (int i = 0; i < 9; i++) { 78 if ( i != ii ) { if ( !grid[i][jj].remove(value) ) { return false; } } 79 } 80 for (int i = (ii/3) * 3; i < (ii/3) * 3 + 3; i++ ) { 81 for ( int j = (jj/3) * 3; j < (jj/3) * 3 + 3; j++ ) { 82 if ( ( i != ii ) || ( j != jj ) ) { if ( !grid[i][j].remove(value) ) { return false; } } 83 } 84 } 85 return true; 86 } 87 88 bool trim() { 89 bool has_new_fixed_grid = false; 90 for (int i = 0; i < 9; i++) { 91 for (int j = 0; j < 9; j++) { 92 if ( !fixed[i][j] && 1 == size(i, j) ) { 93 has_new_fixed_grid = true; 94 if ( !set(i, j, value(i, j)) ) { return false; } 95 } 96 } 97 } 98 if ( has_new_fixed_grid ) { return trim(); } 99 return true; 100 } 101 102 void find_unfixed_min_size_grid(int &ii, int &jj) { 103 size_t min_size = 9; 104 for (int i = 0; i < 9; i++ ) { 105 for ( int j = 0; j < 9; j++) { 106 if ( !fixed[i][j] ) { 107 if ( size(i, j) < min_size ) { ii = i; jj = j; min_size = size(i, j); } 108 } 109 } 110 } 111 } 112 113 bool all_grid_fixed() { 114 for ( int i = 0; i < 9; i++ ) { 115 for ( int j = 0; j < 9; j++ ) { 116 if ( !fixed[i][j] ) { return false; } 117 } 118 } 119 return true; 120 } 121 122 void fill_result( std::set<Result>& result_s ) { 123 Result result; 124 for ( int i = 0; i < 9; i++ ) { 125 for ( int j = 0; j < 9; j++ ) { 126 result.value[i][j] = value(i, j); 127 } 128 } 129 result_s.insert( result ); 130 } 131 }; 132 133 #endif
main.cpp
1 #include "sudoku.h" 2 #include <iostream> 3 4 int main() { 5 std::set<PosVal> pos_val_s; 6 pos_val_s.insert(PosVal(0, 0, 8)); 7 pos_val_s.insert(PosVal(1, 2, 3)); 8 pos_val_s.insert(PosVal(1, 3, 6)); 9 pos_val_s.insert(PosVal(2, 1, 7)); 10 pos_val_s.insert(PosVal(2, 4, 9)); 11 pos_val_s.insert(PosVal(2, 6, 2)); 12 pos_val_s.insert(PosVal(3, 1, 5)); 13 pos_val_s.insert(PosVal(3, 5, 7)); 14 pos_val_s.insert(PosVal(4, 4, 4)); 15 pos_val_s.insert(PosVal(4, 5, 5)); 16 pos_val_s.insert(PosVal(4, 6, 7)); 17 pos_val_s.insert(PosVal(5, 3, 1)); 18 pos_val_s.insert(PosVal(5, 7, 3)); 19 pos_val_s.insert(PosVal(6, 2, 1)); 20 pos_val_s.insert(PosVal(6, 7, 6)); 21 pos_val_s.insert(PosVal(6, 8, 8)); 22 pos_val_s.insert(PosVal(7, 2, 8)); 23 pos_val_s.insert(PosVal(7, 3, 5)); 24 pos_val_s.insert(PosVal(7, 7, 1)); 25 pos_val_s.insert(PosVal(8, 1, 9)); 26 pos_val_s.insert(PosVal(8, 6, 4)); 27 28 Sudoku s; 29 if ( !s.Init( pos_val_s ) ) { 30 return -1; 31 } 32 33 std::set<Result> result_s; 34 s.calc( result_s ); 35 for ( std::set<Result>::iterator it = result_s.begin(); it != result_s.end(); it++ ) { 36 for ( int i = 0; i < 9; i++ ) { 37 for ( int j = 0; j < 9; j++ ) { 38 std::cout << it->value[i][j] << " "; 39 } 40 std::cout << std::endl; 41 } 42 } 43 }
以上是关于数独的C++解法的主要内容,如果未能解决你的问题,请参考以下文章
2021-09-23:编写一个程序,通过填充空格来解决数独问题。数独的解法需遵循如下规则:数字 1-9 在每一行只能出现一次。数字 1-9 在每一列只能出现一次。数字 1-9 在每一个以粗实线分隔的(