3074 DLX解決數獨

2021-09-06 20:07:25 字數 1489 閱讀 4816

數獨的dlx構造:9*9個點每個點有9種選擇,這構成了dlx的729行,每行、列、陣有限制,均為9行(/列/陣),然後每行(/列/陣)都有九種數的情況,於是就有了3*9*9列,但是因為乙個位置只能選乙個,所以又有9*9列,每列連線乙個點的九種選數情況。

最終有4*9*9=324列,9*9*9=729行。

具體看處理:

有些點已經有數了,但是這並不重要,我們只需要給這個點加上乙個行,為它已經選的數,而不要把9種情況都加上,這樣在有精確覆蓋的情況下(即有解),第四部分的某列在縱向就只連線乙個節點,顯然這個節點是必選的,所以不會出錯(當然你要是依然給這個有值節點在dlx中加9行的話,那我也沒招,不要問我為什麼錯,好吧你不會這麼傻吧?)。

而其它沒有初始值的數獨點,自然就加舊行了沒疑問吧?

說乙個跟空間複雜度相關的事,就是一行有且僅有4個節點,分別在行、列、陣、位置這四部分的列中,那麼總節點數(不算輔助節點)就應該最多是729*4,而實際上標準數獨都是有唯一解的,所以需要的節點將遠遠小於這個數。

再說說時間複雜度:因為我們可以為dlx加乙個優化,就是每次選乙個列中節點最少的列繼續dlx的過程,所以我們雖然保留了已經有值的節點,但是實際上最開始就選擇了它們,而若數獨有解,這也是必定選擇的,所以並不會出現因為層數過多而導致回溯過度而tle的情況,也就是說它還是很快的。

#include#include#includeusing namespace std;

const int inf=0x3f3f3f3f;const int maxn=3645;//每乙個格仔可能有9個取值。

//所以最多有81*9行。然後243列。

int u[maxn],d[maxn],l[maxn],r[maxn],c[maxn],row[maxn];//上下左右指標。

//c[i]結點i相應的列。row[i]結點i相應的行號。

int s[350],h[800],ans[100];//s[i]為i列1的個數。

//h[i]為i行的尾指標。

int n,m,cnt,deep;

struct node

st[maxn];

char maze[150],path[150];

void init()

r[324]=deep=0;

cnt=325;

}void insert(int r,int c)

s[c]++;//更新附加資訊

row[cnt]=r;

c[cnt++]=c;

}void remove(int c)//移除c列。

void resume(int c)//還原c列。

bool dfs()

resume(c);

return false;

}int main()

}else}}

dfs();

for(i=0;ipath[deep]=0;

printf("%s\n",path);

}return 0;

}

C 解決數獨問題(回溯)

參考鏈結來自於 輸入乙個數獨作為9 9的陣列,例如輸入乙個測試資料map 9 9 為 0 9 0 0 0 0 0 6 0 8 0 1 0 0 0 5 0 9 0 5 0 3 0 4 0 7 0 0 0 8 0 7 0 9 0 0 0 0 0 9 0 8 0 0 0 0 0 6 0 2 0 7 0 0...

數獨c 解決 dfs 減枝

刷華為的機試題 傳送門 數獨 刷到了乙個關於數獨的題目,以為數獨還有什麼特殊的解,自己寫了個減枝的dfs過了83 的資料,但是好多同學都有同樣的問題,估計使題目的問題把,這題有多解但是做法不同,就有不同的答案,但是答案都是正確的,然後test有只有乙個這就很惱火,所以就假裝我這是正確的吧。以前聽說過...

舞蹈鏈 精確覆蓋,解決數獨問題

首先看看數獨問題 9 9的方格 的規則 1 每個格仔只能填乙個數字 2 每行每個數字只能填一遍 3 每列每個數字只能填一遍 4 每宮每個數字只能填一遍 那現在就是利用這個規則把數獨問題轉換為精確覆蓋問題 可是,直觀上面的規則,發現比較難以轉換為精確覆蓋問題。因此,把上面的表述換個說法 1 每個格仔只...