另一個數獨求解c++程式
來自這裡,他用多種語言實現了同一種方法。包括c++、python、cs等。
#include <iostream> #include <queue> #include <string> #include <vector> using namespace std; typedef int coord; typedef int block; enum view { GRD, ROW, COL, BOX }; const int VIEW = 4; const int UNIT = 3; const int SIZE = UNIT * UNIT; const int COORD = SIZE * SIZE * SIZE; const int BLOCK = VIEW * SIZE * SIZE; const int DEFINED = 0xDEF; const string DIGITS = "123456789"; inline coord coord_of(int i, int j, int k) { return (i * SIZE + j) * SIZE + k; } inline block block_of(view v, int p, int q) { return (v * SIZE + p) * SIZE + q; } vector<block> parents[COORD]; vector<coord> children[BLOCK]; void init() { for (int i = 0; i < SIZE; i++) { for (int j = 0; j < SIZE; j++) { int p = i / UNIT * UNIT + j / UNIT; for (int k = 0; k < SIZE; k++) { coord c = coord_of(i, j, k); parents[c].push_back(block_of(GRD, i, j)); parents[c].push_back(block_of(ROW, i, k)); parents[c].push_back(block_of(COL, j, k)); parents[c].push_back(block_of(BOX, p, k)); } } } for (coord c = 0; c < COORD; c++) for (block b : parents[c]) children[b].push_back(c); } class no_solution_exception {} NO_SOLUTION_EXCEPTION; class sudoku { public: static string solve(string input) { try { sudoku s; return s.read(input).search().to_string(); } catch (no_solution_exception) { return "NO SOLUTION"; } } private: bool admit[COORD]; int count[BLOCK]; sudoku() { for (coord c = 0; c < COORD; c++) admit[c] = true; for (block b = 0; b < BLOCK; b++) count[b] = SIZE; } sudoku(const sudoku& s) { for (coord c = 0; c < COORD; c++) admit[c] = s.admit[c]; for (block b = 0; b < BLOCK; b++) count[b] = s.count[b]; } sudoku& search() { int min = DEFINED; int bmin = -1; for (block b = 0; b < BLOCK; b++) { if (count[b] < min) { min = count[b]; bmin = b; } } if (min == DEFINED) return *this; for (coord c : children[bmin]) { if (admit[c]) { try { sudoku s(*this); return s.assign(c).search(); } catch (no_solution_exception) { } } } throw NO_SOLUTION_EXCEPTION; } sudoku& read(string input) { int l = min(int(input.length()), SIZE * SIZE); for (int ij = 0; ij < l; ij++) { int k = DIGITS.find(input[ij]); if (k != -1) assign(coord_of(ij / SIZE, ij % SIZE, k)); } return *this; } sudoku& assign(coord c) { queue<coord> queue; queue.push(c); while (! queue.empty()) { int c0 = queue.front(); queue.pop(); if (! admit[c0]) throw NO_SOLUTION_EXCEPTION; for (block b1 : parents[c0]) { count[b1] = DEFINED; for (coord c2 : children[b1]) if (c2 != c0 && admit[c2]) { admit[c2] = false; for (block b3 : parents[c2]) if (b3 != b1) { count[b3]--; if (count[b3] == 0) throw NO_SOLUTION_EXCEPTION; if (count[b3] == 1) for (coord c4 : children[b3]) if (admit[c4]) queue.push(c4); } } } } return *this; } string to_string() { string output; for (int i = 0; i < SIZE; i++) { for (int j = 0; j < SIZE; j++) { vector<int> ks; for (int k = 0; k < SIZE; k++) if (admit[coord_of(i, j, k)]) ks.push_back(k); if (ks.size() == 1) output += DIGITS[ks[0]]; else output += '.'; } } return output; } }; int main() { init(); string input; while (cin >> input) cout << sudoku::solve(input) << endl; return 0; }
原始碼中用到了部分c++ 2011標準的功能,但vc 2015沒有實現,比如and和not關鍵字。把它們改為 &&和!後,編譯通過,在連結時,預設需要和windows sdk中的uuid.lib連結,改用/MD選項,與kernel32.lib連結通過。
D:\>cl sudoku.cpp /EHsc /MD /O2 /link D:\VS2010SP1\WINSDK_v7.0A\Lib\kernel32.lib 用於 x86 的 Microsoft (R) C/C++ 優化編譯器 19.00.23026 版 版權所有(C) Microsoft Corporation。保留所有權利。 sudoku.cpp Microsoft (R) Incremental Linker Version 14.00.23026.0 Copyright (C) Microsoft Corporation. All rights reserved. /out:sudoku.exe D:\VS2010SP1\WINSDK_v7.0A\Lib\kernel32.lib sudoku.obj D:\>a\timer sudoku <sudoku17.16000.txt >sudoku17.16000_vc15.txt Timer 3.01 Copyright (c) 2002-2003 Igor Pavlov 2003-07-10 Kernel Time = 0.156 = 00:00:00.156 = 9% User Time = 0.998 = 00:00:00.998 = 60% Process Time = 1.154 = 00:00:01.154 = 70% Global Time = 1.638 = 00:00:01.638 = 100%
最終時間是1.6秒,同樣的機器上,pypy執行python版本是3.76秒,csc編譯cs後執行是3.9秒。命令列引數分別是
\timer pypy d:\sudoku.py d:\sudoku17.16000.txt >d:\sudoku17_16000py.txt \timer sudoku <d:\sudoku17.16000.txt >d:\sudoku17_16000cs.txt
說明:他的cs版本也用到了新功能,除了安裝.net framwork 4.62外,還要更新c#編譯器。 nuget工具是從csc提示的連線處下載的。
D:\>c:csc sudoku.cs Microsoft (R) Visual C# Compiler version 4.6.1590.0 for C# 5 Copyright (C) Microsoft Corporation. All rights reserved. This compiler is provided as part of the Microsoft (R) .NET Framework, but only supports language versions up to C# 5, which is no longer the latest version. For compilers that support newer versions of the C# programming language, see http://go.microsoft.com/fwlink/?LinkID=533240 D:\>nuget install Microsoft.Net.Compilers D:\>Microsoft.Net.Compilers.1.3.2\tools\csc sudoku.cs Microsoft (R) Visual C# Compiler version 1.3.1.60621 Copyright (C) Microsoft Corporation. All rights reserved.
相關文章
- 又一個數獨求解c++程式C++
- 我目前找到的最快的數獨求解程式
- 僅50行Python程式碼!數獨求解!4秒!Python
- 改進版的python求解數獨Python
- [LeetCode] Sudoku Solver 求解數獨LeetCode
- 一個解數獨的程式
- 求解c++C++
- 同樣演算法的Python和C求解數獨程式速度比較演算法Python
- 羅塞塔網站上的c++解數獨程式網站C++
- 據說用概率去解數獨的c++程式C++
- c++求解獎券題目C++
- 求區間不同數的個數【樹狀陣列求解】陣列
- 另一個Swoole偵錯程式 - Yasd
- java程式中編譯另一個java程式Java編譯
- 列表切片賦值給另一個變數賦值變數
- c++求解李白喝酒問題C++
- 檔案正由另一個程式使用
- 一個利用DLX演算法的Python解數獨程式演算法Python
- python中怎麼呼叫另一個程式Python
- 華納雲:linux怎麼將一個變數賦給另一個變數Linux變數
- 另一個go命令列引數處理器 - cmdrGo命令列
- 具有獨特魅力的一本程式設計師心得書《程式設計師,你傷不起》。另一個角度的《程式碼大全》!程式設計師
- 程式設計題求解程式設計
- 淺析一個函式呼叫另一個函式的變數函式變數
- uniapp js 數獨小遊戲 寫死的簡單數獨 數獨 3.0APPJS遊戲
- [演算法] 兩個質數的乘積是707829217,求解該質數演算法
- vue 數獨Vue
- 數獨遊戲遊戲
- 第一個C++程式C++
- 用vue開發一個所謂的數獨Vue
- 梯度下降法中導數的求解梯度
- java解數獨Java
- 【機器學習】求解邏輯迴歸引數(三種方法程式碼實現)機器學習邏輯迴歸
- 請教:如何透過一個Java程式關閉或者啟動另一個Java程式?Java
- 變數C++邏輯程式碼變數C++
- C++啟動一個程式C++
- C++的另一種錯誤處理策略C++
- (字串動態規劃)一個字串變成另一個字串的步驟數字串動態規劃