<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    so true

    心懷未來,開創(chuàng)未來!
    隨筆 - 160, 文章 - 0, 評論 - 40, 引用 - 0
    數(shù)據(jù)加載中……

    sudoku

      1 #include <sys/time.h>
      2 #include <stdlib.h>
      3 #include <string.h>
      4 #include <iostream>
      5 #include <vector>
      6 #include <string>
      7 #include <set>
      8 
      9 class Sudoku {
     10 public:
     11     Sudoku(const std::string& question, bool does_try_all_answers = false): m_does_try_all_answers(does_try_all_answers), m_data(9) {
     12         for (int i = 0; i < 9; ++i) {
     13             m_data[i].resize(9);
     14             for (int j = 0; j < 9; ++j) {
     15                 m_data[i][j] = question[i * 9 + j];
     16             }
     17         }
     18     }
     19 
     20     bool Solve() {
     21         return Fill(0, 0);
     22     }
     23 
     24     const std::string GiveOneAnswer() const {
     25         return m_all_answers.empty() ? "" : *m_all_answers.begin();
     26     }
     27 
     28     const std::set<std::string> GiveAllAnswers() const {
     29         return m_all_answers;
     30     }
     31 
     32     static const std::string ProvideOneQuestionRandomly(int min_filled_num = 30) {
     33         std::vector<std::vector<char> > ques(9, std::vector<char>(9, '.'));
     34 
     35         struct timeval cur_tv;
     36         gettimeofday(&cur_tv, NULL);
     37         srand(cur_tv.tv_usec);
     38 
     39         int valid_digit_num = 0;
     40         for (int i = 0; i < 9; ++i) {
     41             for (int j = 0; j < 9; ++j) {
     42                 if (rand() % 81 <= min_filled_num + valid_digit_num / 6) {
     43                     char c = rand() % 9 + '1';
     44 
     45                     if (DoesConflict(ques, i, j, c)) {
     46                         int k = 0;
     47                         for (; k < 8; ++k) {
     48                             if (c == '9') {
     49                                 c = '1';
     50                             }
     51                             if (!DoesConflict(ques, i, j, ++c)) {
     52                                 break;
     53                             }
     54                         }
     55                         if (8 == k) {
     56                             c = '.';
     57                         }
     58                     }
     59 
     60                     valid_digit_num += ('.' != c);
     61                     ques[i][j] = c;
     62                 } else {
     63                     ques[i][j] = '.';
     64                 }
     65             }
     66         }
     67 
     68         char buf[82];
     69         buf[81] = '\0';
     70         for (int i = 0; i < 9; ++i) {
     71             for (int j = 0; j < 9; ++j) {
     72                 buf[i * 9 + j] = ques[i][j];
     73             }
     74         }
     75 
     76         Sudoku sudoku(buf);
     77         sudoku.Solve();
     78         if (81 == sudoku.GiveOneAnswer().size()) {
     79             return buf;
     80         } else {
     81             return ProvideOneQuestionRandomly(min_filled_num);
     82         }
     83 
     84         return buf;
     85     }
     86 
     87     static void PrintSudoku(const std::string& sudoku) {
     88         if (sudoku.size() < 81) {
     89             return;
     90         }
     91 
     92         for (int i = 0; i < 9; ++i) {
     93             for (int j = 0; j < 9; ++j) {
     94                 if (0 != j) {
     95                     std::cout << " ";
     96                 }
     97                 std::cout << sudoku[i * 9 + j];
     98             }
     99             std::cout << std::endl;
    100         }
    101     }
    102 
    103     static bool ValidateOneAnswer(const std::string& answer) {
    104         if (answer.size() != 81) {
    105             return false;
    106         }
    107 
    108         for (int i = 0; i < 9; ++i) {
    109             char hit_h[9] = { '\0' };
    110             char hit_v[9] = { '\0' };
    111             for (int j = 0; j < 9; ++j) {
    112                 if ('.' == answer[i * 9 + j] || ++hit_h[answer[i * 9 + j] - '1'] != 1) { //row check
    113                     return false;
    114                 } else if ('.' == answer[j * 9 + i] || ++hit_v[answer[j * 9 + i] - '1'] != 1) { //column check
    115                     return false;
    116                 }
    117                 if (0 == i % 3 && 0 == j % 3) { //3x3 square check
    118                     char hit_m[9] = { '\0' };
    119                     for (int i2 = i; i2 < i + 3; ++i2) {
    120                         for (int j2 = j; j2 < j + 3; ++j2) {
    121                             if ('.' == answer[i2 * 9 + j2] || ++hit_m[answer[i2 * 9 + j2] - '1'] != 1) {
    122                                 return false;
    123                             }
    124                         }
    125                     }
    126                 }
    127             }
    128         }
    129         return true;
    130     }
    131 
    132 private:
    133     void AddOneAnswer() {
    134         char buf[82];
    135         buf[81] = '\0';
    136 
    137         for (int i = 0; i < 9; ++i) {
    138             for (int j = 0; j < 9; ++j) {
    139                 buf[i * 9 + j] = m_data[i][j];
    140             }
    141         }
    142 
    143         m_all_answers.insert(buf);
    144     }
    145 
    146     static bool DoesConflict(const std::vector<std::vector<char> >& data, int i, int j, char digit) {
    147         for (int k = 0; k < 9; ++k) {
    148             if (digit == data[i][k]) {
    149                 return true;
    150             }
    151             if (digit == data[k][j]) {
    152                 return true;
    153             }
    154         }
    155 
    156         int i0 = i - i % 3;
    157         int j0 = j - j % 3;
    158         for (int i2 = i0; i2 < i0 + 3; ++i2) {
    159             for (int j2 = j0; j2 < j0 + 3; ++j2) {
    160                 if (digit == data[i2][j2]) {
    161                     return true;
    162                 }
    163             }
    164         }
    165 
    166         return false;
    167     }
    168 
    169     bool Fill(int i, int j) {
    170         for (; i < 9; ++i, j = 0) {
    171             for (; j < 9; ++j) {
    172                 if ('.' == m_data[i][j]) {
    173                     for (int k = '1'; k <= '9'; ++k) {
    174                         if (DoesConflict(m_data, i, j, k)) {
    175                             continue;
    176                         }
    177 
    178                         m_data[i][j] = k;
    179                         if (8 == j) {
    180                             if (Fill(i + 1, 0)) {
    181                                 AddOneAnswer();
    182                                 if (!m_does_try_all_answers) {
    183                                     return true;
    184                                 }
    185                             }
    186                         } else {
    187                             if (Fill(i, j + 1)) {
    188                                 AddOneAnswer();
    189                                 if (!m_does_try_all_answers) {
    190                                     return true;
    191                                 }
    192                             }
    193                         }
    194                     }
    195                     m_data[i][j] = '.';
    196                     return false;
    197                 }
    198             }
    199         }
    200 
    201         AddOneAnswer();
    202         return true;
    203     }
    204 
    205 private:
    206     bool m_does_try_all_answers;
    207     std::vector<std::vector<char> > m_data;
    208     std::set<std::string> m_all_answers;
    209 };
    210 
    211 int main(int argc, char* argv[]) {
    212     std::string question;
    213     //with many answers
    214     question = ".2..4836..5163887..63195..45.4.7.2.98..";
    215 
    216     //with just one answer: https://baike.baidu.com/item/%E4%B8%96%E7%95%8C%E6%9C%80%E9%9A%BE%E6%95%B0%E7%8B%AC/13848819
    217     question = "..53..82..7..1.5..4.531..76..328..6.5.9..4.397..";
    218 
    219     bool find_all_answers = false;
    220     if (argc > 1 && 81 == strlen(argv[1])) {
    221         question = argv[1];
    222     } else {
    223         if (argc > 1) {
    224             find_all_answers = true;
    225         }
    226         question = Sudoku::ProvideOneQuestionRandomly();
    227     }
    228 
    229     Sudoku::PrintSudoku(question);
    230 
    231     Sudoku sudoku(question, find_all_answers);
    232     sudoku.Solve();
    233 
    234     const std::set<std::string>& all_answers = sudoku.GiveAllAnswers();
    235     int idx = 0;
    236     for (typeof(all_answers.begin()) iter = all_answers.begin(); all_answers.end() != iter; ++iter) {
    237         std::cout << "answer " << ++idx << " for this sudoku is:" << std::endl;
    238         Sudoku::PrintSudoku(*iter);
    239         if (!Sudoku::ValidateOneAnswer(*iter)) {
    240             std::cout << "answer is not correct: " << *iter << std::endl;
    241         }
    242         std::cout << "[" << *iter << "]" << std::endl;
    243     }
    244     return 0;
    245 }
    246 

    posted on 2017-11-03 17:19 so true 閱讀(183) 評論(0)  編輯  收藏 所屬分類: C&C++Linux

    主站蜘蛛池模板: 亚洲一区二区三区免费| 亚洲中文无码永久免费| 亚洲成av人片在线观看天堂无码| 国产成人精品亚洲日本在线| 182tv免费视视频线路一二三| 亚洲AV天天做在线观看| 欧洲人成在线免费| 亚洲嫩草影院久久精品| 嫩草成人永久免费观看| 亚洲精品资源在线| 亚色九九九全国免费视频| 2017亚洲男人天堂一| 成人黄动漫画免费网站视频 | 欧美a级成人网站免费| 亚洲AV成人无码天堂| 成人免费看吃奶视频网站| 亚洲精品国产首次亮相| 国产无遮挡吃胸膜奶免费看视频 | 亚洲精品无码mⅴ在线观看| 永久在线毛片免费观看| 色妞www精品视频免费看| 色噜噜亚洲精品中文字幕| 国产啪精品视频网站免费尤物| 久久亚洲AV无码精品色午夜| 91嫩草国产在线观看免费| 久久精品国产亚洲AV电影网| 亚洲精品国产成人影院| 国内少妇偷人精品视频免费| 亚洲黄色网址在线观看| 野花高清在线观看免费3中文 | 免费无码作爱视频| 亚洲精品日韩专区silk| 日韩视频免费一区二区三区| 亚洲精品黄色视频在线观看免费资源| 亚洲AV无码一区二区二三区软件| 久草免费在线观看视频| 黄色免费在线网址| 久久丫精品国产亚洲av不卡| 热久久精品免费视频| 免费看男人j放进女人j免费看| 亚洲综合色区中文字幕|