数独_DFS剪枝,状态压缩,lowbit树

166. 数独

数独是一种传统益智游戏,你需要把一个 9×9 的数独补充完整,使得图中每行、每列、每个 3×3 的九宫格内数字 19 均恰好出现一次。

请编写一个程序填写数独。

输入格式

输入包含多组测试用例。

每个测试用例占一行,包含 81 个字符,代表数独的 81 个格内数据(顺序总体由上到下,同行由左到右)。

每个字符都是一个数字(19)或一个 .(表示尚未填充)。

您可以假设输入中的每个谜题都只有一个解决方案。

文件结尾处为包含单词 end 的单行,表示输入结束。

输出格式

每个测试用例,输出一行数据,代表填充完全后的数独。

输入样例:

4.....8.5.3..........7......2.....6.....8.4......1.......6.3.7.5..2.....1.4...... ......52..8.4......3...9...5.1...6..2..7........3.....6...1..........7.4.......3. end

输出样例:

417369825632158947958724316825437169791586432346912758289643571573291684164875293 416837529982465371735129468571298643293746185864351297647913852359682714128574936

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
<div id="mCSB_3" class="mCustomScrollBox mCS-minimal-dark mCSB_vertical_horizontal mCSB_outside" style="max-height: none;" tabindex="0"><div id="mCSB_3_container" class="mCSB_container mCS_y_hidden mCS_no_scrollbar_y mCS_x_hidden mCS_no_scrollbar_x" style="position: relative; top: 0px; left: 0px; width: 100%;" dir="ltr"><code-pre class="code-pre" id="pre-iFWrRY"><code-line class="line-numbers-rows"></code-line>#include <bits/stdc++.h>
<code-line class="line-numbers-rows"></code-line>using namespace std;
<code-line class="line-numbers-rows"></code-line>
<code-line class="line-numbers-rows"></code-line>const int N = 9, M = 1 << N;
<code-line class="line-numbers-rows"></code-line>int row[N], col[N], cell[3][3];
<code-line class="line-numbers-rows"></code-line>int ones[M], m[M];
<code-line class="line-numbers-rows"></code-line>string str;
<code-line class="line-numbers-rows"></code-line>int flag;
<code-line class="line-numbers-rows"></code-line>void init(){
<code-line class="line-numbers-rows"></code-line>    flag = 0;
<code-line class="line-numbers-rows"></code-line>    for(int i = 0; i < N; i++){
<code-line class="line-numbers-rows"></code-line>        row[i] = (1 << N) - 1;
<code-line class="line-numbers-rows"></code-line>        col[i] = (1 << N) - 1;
<code-line class="line-numbers-rows"></code-line>        cell[i / 3][i % 3] = (1 << N) - 1;
<code-line class="line-numbers-rows"></code-line>    }
<code-line class="line-numbers-rows"></code-line>   
<code-line class="line-numbers-rows"></code-line>}
<code-line class="line-numbers-rows"></code-line>void draw(int x, int y, int t, int is_set){
<code-line class="line-numbers-rows"></code-line>    int a = 1 << t;
<code-line class="line-numbers-rows"></code-line>   
<code-line class="line-numbers-rows"></code-line>    if(is_set){
<code-line class="line-numbers-rows"></code-line>        str[x * N + y] = t + '1';
<code-line class="line-numbers-rows"></code-line>        row[x] -= a;
<code-line class="line-numbers-rows"></code-line>        col[y] -= a;
<code-line class="line-numbers-rows"></code-line>        cell[x / 3][y / 3] -= a;
<code-line class="line-numbers-rows"></code-line>    }else{
<code-line class="line-numbers-rows"></code-line>        str[x * N + y] = '.';
<code-line class="line-numbers-rows"></code-line>        row[x] += a;
<code-line class="line-numbers-rows"></code-line>        col[y] += a;
<code-line class="line-numbers-rows"></code-line>        cell[x / 3][y / 3] += a;
<code-line class="line-numbers-rows"></code-line>    }
<code-line class="line-numbers-rows"></code-line>}
<code-line class="line-numbers-rows"></code-line>int get(int x, int y){
<code-line class="line-numbers-rows"></code-line>    return row[x] & col[y] & cell[x / 3][y / 3];
<code-line class="line-numbers-rows"></code-line>}
<code-line class="line-numbers-rows"></code-line>int lowbit(int x){
<code-line class="line-numbers-rows"></code-line>    return x & -x;
<code-line class="line-numbers-rows"></code-line>}
<code-line class="line-numbers-rows"></code-line>void dfs(int cnt){
<code-line class="line-numbers-rows"></code-line>    if(!cnt){
<code-line class="line-numbers-rows"></code-line>        cout << str << endl;
<code-line class="line-numbers-rows"></code-line>        flag = 1;
<code-line class="line-numbers-rows"></code-line>        return ;
<code-line class="line-numbers-rows"></code-line>    }
<code-line class="line-numbers-rows"></code-line>    if(flag)return;
<code-line class="line-numbers-rows"></code-line>    int MIN = 10;
<code-line class="line-numbers-rows"></code-line>    int x, y;
<code-line class="line-numbers-rows"></code-line>    for(int i = 0; i < N; i++){
<code-line class="line-numbers-rows"></code-line>        for(int j = 0; j < N; j++){
<code-line class="line-numbers-rows"></code-line>            if(str[i * N + j] == '.'){
<code-line class="line-numbers-rows"></code-line>                int state = get(i,j);
<code-line class="line-numbers-rows"></code-line>                int sum = ones[state];
<code-line class="line-numbers-rows"></code-line>               
<code-line class="line-numbers-rows"></code-line>                if(sum < MIN){
<code-line class="line-numbers-rows"></code-line>                    MIN = sum;
<code-line class="line-numbers-rows"></code-line>                    x = i, y = j;
<code-line class="line-numbers-rows"></code-line>                }
<code-line class="line-numbers-rows"></code-line>            }
<code-line class="line-numbers-rows"></code-line>           
<code-line class="line-numbers-rows"></code-line>        }
<code-line class="line-numbers-rows"></code-line>    }
<code-line class="line-numbers-rows"></code-line>    //printf("x = %d  y = %d\n",x,y);
<code-line class="line-numbers-rows"></code-line>    int state = get(x,y);
<code-line class="line-numbers-rows"></code-line>    for(int i = state; i; i -= lowbit(i)){
<code-line class="line-numbers-rows"></code-line>        int t = m[lowbit(i)];
<code-line class="line-numbers-rows"></code-line>        draw(x,y,t,1);
<code-line class="line-numbers-rows"></code-line>        dfs(cnt - 1);
<code-line class="line-numbers-rows"></code-line>        draw(x,y,t,0);
<code-line class="line-numbers-rows"></code-line>       
<code-line class="line-numbers-rows"></code-line>    }
<code-line class="line-numbers-rows"></code-line>}
<code-line class="line-numbers-rows"></code-line>int main(){
<code-line class="line-numbers-rows"></code-line>    for(int i = 0; i < N; i++)  m[1 << i] = i;
<code-line class="line-numbers-rows"></code-line>    for(int i = 0; i < M; i++)
<code-line class="line-numbers-rows"></code-line>        for(int j = 0; j < N; j++)
<code-line class="line-numbers-rows"></code-line>            ones[i] += (i >> j) & 1;
<code-line class="line-numbers-rows"></code-line>   
<code-line class="line-numbers-rows"></code-line>   
<code-line class="line-numbers-rows"></code-line>    while(cin >> str, str[0] != 'e'){
<code-line class="line-numbers-rows"></code-line>        init();
<code-line class="line-numbers-rows"></code-line>        int cnt = 0;
<code-line class="line-numbers-rows"></code-line>        for(int i = 0; i < N; i++){
<code-line class="line-numbers-rows"></code-line>            for(int j = 0; j < N; j++){
<code-line class="line-numbers-rows"></code-line>                char c = str[i * N + j];
<code-line class="line-numbers-rows"></code-line>                if(c != '.'){
<code-line class="line-numbers-rows"></code-line>                    draw(i,j,c - '1',1);
<code-line class="line-numbers-rows"></code-line>                }else cnt++;
<code-line class="line-numbers-rows"></code-line>            }
<code-line class="line-numbers-rows"></code-line>            //cout << endl;
<code-line class="line-numbers-rows"></code-line>        }
<code-line class="line-numbers-rows"></code-line>        flag = 0;
<code-line class="line-numbers-rows"></code-line>        dfs(cnt);
<code-line class="line-numbers-rows"></code-line>    }
<code-line class="line-numbers-rows"></code-line>    return 0;
<code-line class="line-numbers-rows"></code-line>}
</code-pre></div></div><div id="mCSB_3_scrollbar_vertical" class="mCSB_scrollTools mCSB_3_scrollbar mCS-minimal-dark mCSB_scrollTools_vertical" style="display: none;"><div class="mCSB_draggerContainer"><div id="mCSB_3_dragger_vertical" class="mCSB_dragger" style="position: absolute; min-height: 0px; height: 0px; top: 0px;"><div class="mCSB_dragger_bar" style="line-height: 0px;"></div></div><div class="mCSB_draggerRail"></div></div></div><div id="mCSB_3_scrollbar_horizontal" class="mCSB_scrollTools mCSB_3_scrollbar mCS-minimal-dark mCSB_scrollTools_horizontal" style="display: none;"><div class="mCSB_draggerContainer"><div id="mCSB_3_dragger_horizontal" class="mCSB_dragger" style="position: absolute; min-width: 0px; width: 0px; left: 0px;"><div class="mCSB_dragger_bar"></div></div><div class="mCSB_draggerRail"></div></div></div>

  

 

__EOF__

本文作者从荣
本文链接https://www.cnblogs.com/rongrongrong/p/15936405.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   荣荣荣荣荣荣  阅读(52)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示