個人GitHub:mmbhwhhpython
PSP | 預估耗時(小時) | 實際耗時(小時) |
---|---|---|
計劃 | 2 | 3 |
估計這個任務須要多少時間 | 16 | 20 |
開發 | 1 | 2 |
需求分析 (包括學習新技術) | 2 | 2 |
生成設計文檔 | 2 | 3 |
設計複審 | 3 | 3 |
具體設計 | 2 | 3 |
具體編碼 | 3 | 5 |
代碼複審 | 3 | 3 |
測試(自我測試,修改代碼,提交修改) | 1 | 2 |
報告 | 2 | 3 |
過程改進計劃 | 1 | 2 |
總計 | 22 | 31 |
開始拿到題目的時候,覺得是我想象中的數獨,就簡單的想着只要把每一個已經肯定的數對它當前所在的行、列、宮格的影響擴散出去,題目又說給的數獨都是惟一解的,這更加讓我確信用個人思路能夠解出來,而後就試了試。git
大致和第一位交做業的莫多同窗同樣,就是對數獨遍歷兩次,第一次找到入口(由於題目說測試的數據都是惟一解),找到一個肯定的點,而後將它的影響擴散給行、列、宮格,最終就會將整個表格填滿。寫了好久的代碼,卻發現個人思路只能填寫一部分數據,沒玩過數獨的我仍是太嫩了,後面冷靜下來思考一番,若是數獨有這麼簡單還叫什麼數獨呢,從個人那些錯誤的數據我知道了,儘管一個數獨只有一個解,可是它也不必定能夠用邏輯直接肯定所有的值,由於我從我錯誤的代碼打出來的錯誤結果顯示,沒填的那部分數據的確不能肯定,必需要填入數值進去試探,雖然填的數字合法,可是解不出來。這結果讓我原地自閉。github
經歷了上次的教訓,索性直接用暴力的辦法解這道題。思路就是從第一個格子一直找到最後一個格子,若是找到了空格子,那就給它賦上合法的數值,而後繼續找,若是找不到了就出現了兩種狀況。一是已經填完了,結果出來了,而且它是合法的也就是它的解了;二是,找不到合法的值了,可是它卻仍是空着的,說明前面賦的值不對,此時再回去改,直到正確爲止。代碼以下:函數
bool check(int u, int t) { int x, y; x = (u - 1) / type + 1; y = (u - 1) % type + 1;//找到u這個位置的座標 for (int i = 1; i <= type; i++) { if (gg[x][i] == t && i != y) return false; if (gg[i][y] == t && i != x) return false; }//判斷這個位置填入的數會不會與行和列衝突 if (type == 4 || type == 6 || type == 8 || type == 9) { int xs, ys; int beginx, beginy;//當前座標所在宮格的左上角座標,可當作起始座標 switch (type)//判斷宮格的規模 { case 4: xs = 2; ys = 2; break; case 6: xs = 2; ys = 3; break; case 8: xs = 4; ys = 2; break; case 9: xs = 3; ys = 3; break; } int flogx = xs; int flogy = ys;//flogx和flogy只是待會下面用到的循環次數 beginx = (x - 1) / xs * xs + 1; beginy = (y - 1) / ys * ys + 1; for (int i = beginx; flogx > 0; flogx--, i++) { for (int j = beginy; flogy > 0; flogy--, j++) { if (t == gg[i][j] && (x != i || y != j)) return false; } flogy = ys; } flogy = xs; }//判斷此位置填入的數會不會與宮格里的衝突 return true;//能走到這裏說明填的數合法 }
bool dfs(int u) { if (u > type*type) return true;//迭代到編號之外,說明前面填的數都是合法的 int x, y; x = (u - 1) / type + 1; y = (u - 1) % type + 1;//給它座標化 if (gg[x][y]) return dfs(u + 1);//若是這個位置有數字,就去下一個點 else { for (int i = 1; i <= type; i++) { if (check(u, i)) { gg[x][y] = i; if (dfs(u + 1))return true; gg[x][y] = 0; } }//這個位置還沒填入數據,就隨便給它一個值,而後再執行下一個點,若是下一個點不能夠了就會回來這個點從新賦值 return false; } }