【HDOJ】3909 Sudoku
2015-11-18 20:51
375 查看
DLX的应用,基本题,注意maxnode开大点儿。
/* 3909 */ #include <iostream> #include <string> #include <map> #include <queue> #include <set> #include <stack> #include <vector> #include <deque> #include <algorithm> #include <cstdio> #include <cmath> #include <ctime> #include <cstring> #include <climits> #include <cctype> #include <cassert> #include <functional> #include <iterator> #include <iomanip> using namespace std; //#pragma comment(linker,"/STACK:102400000,1024000") #define sti set<int> #define stpii set<pair<int, int> > #define mpii map<int,int> #define vi vector<int> #define pii pair<int,int> #define vpii vector<pair<int,int> > #define rep(i, a, n) for (int i=a;i<n;++i) #define per(i, a, n) for (int i=n-1;i>=a;--i) #define clr clear #define pb push_back #define mp make_pair #define fir first #define sec second #define all(x) (x).begin(),(x).end() #define SZ(x) ((int)(x).size()) #define lson l, mid, rt<<1 #define rson mid+1, r, rt<<1|1 typedef struct DLX { static const int maxc = 4*16*16+5; static const int maxr = 16*16*16+5; static const int maxnode = 16*16*16*5+5; int n, sz; int S[maxc]; int row[maxnode], col[maxnode]; int L[maxnode], R[maxnode], U[maxnode], D[maxnode]; int ansd, cnt, ans[maxr], ans_[maxr]; void init(int n_) { cnt = 0; n = n_; rep(i, 0, n+1) { L[i] = i-1; R[i] = i+1; U[i] = i; D[i] = i; } L[0] = n; R = 0; sz = n+1; memset(S, 0, sizeof(S)); } void addRow(int r, vi columns) { int first = sz; int size = SZ(columns); rep(i, 0, size) { int c = columns[i]; L[sz] = sz-1; R[sz] = sz+1; D[sz] = c; U[sz] = U[c]; D[U[c]] = sz; U[c] = sz; row[sz] = r; col[sz] = c; ++S[c]; ++sz; } R[sz - 1] = first; L[first] = sz - 1; } void remove(int c) { L[R[c]] = L[c]; R[L[c]] = R[c]; for (int i=D[c]; i!=c; i=D[i]) { for (int j=R[i]; j!=i; j=R[j]) { U[D[j]] = U[j]; D[U[j]] = D[j]; --S[col[j]]; } } } void restore(int c) { L[R[c]] = c; R[L[c]] = c; for (int i=D[c]; i!=c; i=D[i]) { for (int j=R[i]; j!=i; j=R[j]) { U[D[j]] = j; D[U[j]] = j; ++S[col[j]]; } } } bool dfs(int d) { if (R[0] == 0) { ansd = d; ++cnt; rep(i, 0, ansd) ans_[i] = ans[i]; return cnt>1; } int c = R[0]; for (int i=R[0]; i!=0; i=R[i]) { if (S[i] < S[c]) c = i; } remove(c); for (int i=D[c]; i!=c; i=D[i]) { ans[d] = row[i]; for (int j=R[i]; j!=i; j=R[j]) { remove(col[j]); } if (dfs(d + 1)) return true; for (int j=L[i]; j!=i; j=L[j]) { restore(col[j]); } } restore(c); return false; } void solve(vi& v) { dfs(0); if (cnt == 1) { v.clr(); rep(i, 0, ansd) v.pb(ans_[i]); } } } DLX; DLX solver; int n, n2, n2n2; const int maxl = 20; char M[maxl][maxl], M_[maxl][maxl]; const int SLOT = 0; const int ROW = 1; const int COL = 2; const int SUB = 3; int encode(int a, int b, int c) { return a*n2n2 + b*n2 + c + 1; } void decode(int code, int& a, int& b, int& c) { --code; c = code % n2; code /= n2; b = code % n2; code /= n2; a = code; } int getVal(char c) { if (c>='0' && c<='9') return c-'1'; return c-'A'+9; } int getChar(int val) { if (val < 9) return val+'1'; return val-9+'A'; } void init() { n2 = n * n; n2n2 = n2 * n2; } void solve(vi& ans) { solver.init(4 * n2n2); rep(r, 0, n2) { rep(c, 0, n2) { rep(v, 0, n2) { if (M[r][c]=='.' || v==getVal(M[r][c])) { vi columns; columns.pb(encode(SLOT, r, c)); columns.pb(encode(ROW, r, v)); columns.pb(encode(COL, c, v)); columns.pb(encode(SUB, r/n*n+c/n, v)); solver.addRow(encode(r, c, v), columns); } } } } solver.solve(ans); } int main() { ios::sync_with_stdio(false); #ifndef ONLINE_JUDGE freopen("data.in", "r", stdin); freopen("data.out", "w", stdout); #endif vi ans, tmp; while (scanf("%d", &n) != EOF) { init(); rep(i, 0, n2) scanf("%s", M[i]); solve(ans); if (solver.cnt == 0) { puts("No Solution"); continue; } else if (solver.cnt > 1) { puts("Multiple Solutions"); continue; } // check if is minimal bool flag = true; rep(r, 0, n2) { rep(c, 0, n2) { if (M[r][c] != '.') { char ch = M[r][c]; M[r][c] = '.'; solve(tmp); M[r][c] = ch; if (solver.cnt <= 1) { flag = false; goto _output; } } } } _output: if (flag) { int sz = SZ(ans); rep(i, 0, sz) { int r, c, v; decode(ans[i], r, c, v); char ch = getChar(v); M[r][c] = ch; } rep(i, 0, n2) puts(M[i]); } else { puts("Not Minimal"); } } #ifndef ONLINE_JUDGE printf("time = %d.\n", (int)clock()); #endif return 0; }
相关文章推荐
- 【转】轻松记住大端小端的含义(附对大端和小端的解释)
- java+内存分配及变量存储位置的区别
- 函数
- 冒泡,setinterval,背景图的div绑定事件,匿名函数问题--工作中的思考
- Opencv中用at<格式> 与用ptr<格式> 的不同
- leetcode 58:Length of Last Word
- 树莓派2代B model 上手初体验,不用显示器,Python GPIO 点亮一颗LED
- 能源互联网“十三五”迎机遇 发展面临三大障碍
- 在 Lua 里 使用 Cocos Studio 导出的 .csb 文件
- POJ - 3662 Telephone Lines
- 行计数
- java IO流的简单介绍及应用
- 【试错】——人类不断学习、进步的前提
- [IOS开发]模仿微博的客户端(1)
- iOS多线程技术
- CSS利用checkbook实现开关按钮
- 圈奶牛<计算几何><C++>
- 1.Android AlertDialog
- C++语法疑点
- C#中abstract和virtual区别