POJ - 3074 Sudoku

Sudoku
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 10881 Accepted: 3896

Description

In the game of Sudoku, you are given a large 9 × 9 grid divided into smaller 3 × 3 subgrids. For example,

.2738..1.
.1...6735
.......29
3.5692.8.
.........
.6.1745.3
64.......
9518...7.
.8..6534.

Given some of the numbers in the grid, your goal is to determine the remaining numbers such that the numbers 1 through 9 appear exactly once in (1) each of nine 3 × 3 subgrids, (2) each of the nine rows, and (3) each of the nine columns.

Input

The input test file will contain multiple cases. Each test case consists of a single line containing 81 characters, which represent the 81 squares of the Sudoku grid, given one row at a time. Each character is either a digit (from 1 to 9) or a period (used to indicate an unfilled square). You may assume that each puzzle in the input will have exactly one solution. The end-of-file is denoted by a single line containing the word “end”.

Output

For each test case, print a line representing the completed Sudoku puzzle.

Sample Input

.2738..1..1...6735.......293.5692.8...........6.1745.364.......9518...7..8..6534.
......52..8.4......3...9...5.1...6..2..7........3.....6...1..........7.4.......3.
end

Sample Output

527389416819426735436751829375692184194538267268174593643217958951843672782965341
416837529982465371735129468571298643293746185864351297647913852359682714128574936

Source

思路:每次从选择方案最少的格子填充,把每个行,列,块可取的数通过压位存到整数中,取的时候&运算,不断取lowbit。这题要尤其注意常数,以及及时剪枝,用了几乎一天从1.6s减到0.77s。
  1 #include <iostream>
  2 #include <fstream>
  3 #include <sstream>
  4 #include <cstdlib>
  5 #include <cstdio>
  6 #include <cmath>
  7 #include <string>
  8 #include <cstring>
  9 #include <algorithm>
 10 #include <queue>
 11 #include <stack>
 12 #include <vector>
 13 #include <set>
 14 #include <map>
 15 #include <list>
 16 #include <iomanip>
 17 #include <cctype>
 18 #include <cassert>
 19 #include <bitset>
 20 #include <ctime>
 21 
 22 using namespace std;
 23 
 24 #define pau system("pause")
 25 #define ll long long
 26 #define pii pair<int, int>
 27 #define pb push_back
 28 #define mp make_pair
 29 #define clr(a, x) memset(a, x, sizeof(a))
 30 
 31 const double pi = acos(-1.0);
 32 const int INF = 0x3f3f3f3f;
 33 const int MOD = 1e9 + 7;
 34 const double EPS = 1e-9;
 35 
 36 /*
 37 #include <ext/pb_ds/assoc_container.hpp>
 38 #include <ext/pb_ds/tree_policy.hpp>
 39 
 40 using namespace __gnu_pbds;
 41 tree<pli, null_type, greater<pli>, rb_tree_tag, tree_order_statistics_node_update> T;
 42 */
 43 
 44 
 45 int mmpr[11], mmpc[11], mmpf[11];
 46 char s[88];
 47 int flag, num[555], cnt[1555];
 48 struct Node {
 49     int val;
 50     int r, c, f;
 51     inline int get_bs() {
 52         return mmpr[r] & mmpc[c] & mmpf[f];
 53     }
 54     inline bool operator < (const Node &n) const {
 55         return  n.val || (!val && cnt[mmpr[r] & mmpc[c] & mmpf[f]]
 56             < cnt[mmpr[n.r] & mmpc[n.c] & mmpf[n.f]]);
 57     }
 58 } node[11][11];
 59 void output() {
 60     for (int i = 1; i <= 9; ++i) {
 61         for (int j = 1; j <= 9; ++j) {
 62             printf("%d", node[i][j].val);
 63         }
 64         puts("");
 65     }
 66     puts("");
 67 }
 68 inline bool dfs(int now) {
 69     if (!now) return true;
 70     int sx = 1, sy = 1, tmp = 10;
 71     for (int i = 1; i <= 9; ++i) {
 72         for (int j = 1; j <= 9; ++j) {
 73             if (node[i][j].val) continue;
 74             int val = node[i][j].get_bs();
 75             if (!val) return false;
 76             if (cnt[val] < tmp) {
 77                 tmp = cnt[val];
 78                 sx = i, sy = j;
 79             }
 80         }
 81     }
 82     int tbs = node[sx][sy].get_bs();
 83     for (int q = tbs & -tbs; tbs; tbs -= q, q = tbs & -tbs) {
 84         node[sx][sy].val = num[q];
 85         mmpr[sx] ^= q, mmpc[sy] ^= q, mmpf[node[sx][sy].f] ^= q;
 86         if (dfs(now - 1)) return true;
 87         mmpr[sx] ^= q, mmpc[sy] ^= q, mmpf[node[sx][sy].f] ^= q;
 88     }
 89     node[sx][sy].val = 0;
 90     return false;
 91 }
 92 int main() {
 93     //freopen("data.in", "r", stdin);
 94     //freopen("data.out", "w", stdout);
 95     for (int i = 1; i <= 9; ++i) {
 96         num[1 << i] = i;
 97     }
 98     for (int i = 0; i <= 1512; ++i) {
 99         cnt[i] = __builtin_popcount(i);
100     }
101     while (~scanf(" %s", s + 1) && 'e' != s[1]) {
102         //puts(s + 1); pau;
103         for (int i = 1; i <= 9; ++i) {
104             mmpr[i] = mmpc[i] = mmpf[i] = (1 << 10) - 2;
105         }
106         int now = 0;
107         for (int i = 1; i <= 9; ++i) {
108             for (int j = 1; j <= 9; ++j) {
109                 node[i][j].r = i;
110                 node[i][j].c = j;
111                 node[i][j].f = (i - 1) / 3 * 3 + (j - 1) / 3 + 1;
112                 if ('.' == s[(i - 1) * 9 + j]) {
113                     node[i][j].val = 0;
114                     ++now;
115                 } else {
116                     node[i][j].val = s[(i - 1) * 9 + j] - '0';
117                     mmpr[i] ^= 1 << node[i][j].val;
118                     mmpc[j] ^= 1 << node[i][j].val;
119                     mmpf[node[i][j].f] ^= 1 << node[i][j].val;
120                 }
121             }
122         }
123         dfs(now);
124         for (int i = 1; i <= 9; ++i) {
125             for (int j = 1; j <= 9; ++j) {
126                 //printf("%d", node[i][j].val);
127                 putchar(node[i][j].val + '0');
128             }
129         }
130         puts("");
131     }
132     return 0;
133 }
134 /*
135 2
136 000000000
137 000000000
138 000000000
139 000000000
140 000000000
141 000000000
142 000000000
143 000000000
144 000000000
145 
146 */
View Code

 

转载于:https://www.cnblogs.com/BIGTOM/p/9081279.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值