這是乙個課設的作業,對於理解回溯法很有用,所以把他碼住。好久沒敲這種**了,邊界居然調了半天,尷尬!
作業描述:寫個數獨遊戲,具有自動生成數獨的功能和人工設定初始盤的功能,並且具有ui介面。
作業分析:
任務一:對於自動生成數獨的功能,他的功能實現邏輯是:回溯生成乙個數獨,然後隨機性讓部分區域可視(對於玩家),當玩家選擇提交時,再判斷是否與生成的數獨一致。
**任務二:**對於人工設定初始盤的功能,他和上面的自動生成有一些不同,當玩家選擇手動生成數獨並提交給後台之後,後台通過回溯法對提交的陣列進行有解檢查,如果無解返回「設定失敗」,否則就找到所有的解,並儲存全部。當玩家提交answer時,匹配每一種解。
回溯邏輯:對於乙個用來儲存生成的陣列game,我們對其進行自上而下從左到右的填充,每次在當前位置(x,y)填充乙個數字時,對該數字進行合法判斷iscorrect(x,y),如果不合法,進行回溯;合法進行下一次填充。
注:回溯法一定注意迴圈的邏輯,以及對continue一定要有充分的了解,不清楚的建議改為break,單步除錯幾次。特別注意,j=j-2而不是j=j-1!!!
private static int game=new int [9][9];//儲存數獨
private static int rannum= ;//隨機數生成陣列
private int generategame()
else
}//如果可以獲得數字,說明嘗試的次數並沒有用完
//對數字的合法性進行檢查
if(iscorrect(i,j))
else }}
return game;
}
1、自動生成隨機數函式getnum(int time)
對於乙個第一次,生成隨機數的情況來說(time=0),我們初始化陣列。
對於乙個進行第九次挑選隨機數的情況來說(time=9),我們已經沒有數可以供他使用,所以返回不存在。
當進行數字生成時,我們只要保證生成隨機數的下標是在max(未被使用的數字的下標),就可以實現,千萬別忘了把已經使用過的數字和末位交換。
注:這個自己一定要寫一下,我錯了好幾次!!
//生成隨機數獨
private
intgetnum
(int time)
}// 第10次填充,表明該位置已經卡住,則返回0,由主程式處理退回
if(time ==9)
// 不是第一次填充
// 生成隨機數字,該數字是陣列的下標,取陣列num中該下標對應的數字為隨機數字
// int rannum = (int) (math.random() * (9 - time));//j2se
int num=r.
nextint(9
- time)
;//j2me
// 把數字放置在陣列倒數第time個位置,
int temp = rannum[
8- time]
; rannum[
8- time]
= rannum[num]
; rannum[num]
= temp;
// 返回數字
return rannum[
8-time]
;}
2.合法性判斷(一定不要越界)
注:最好寫個邊界判斷函式,我寫**時候越界了,沒有輸出就狠煩。
private
boolean
iscorrect
(int i,
int j)
else
}//檢查3*3是否有重複
private
boolean
checkbox
(int i,
int j)
for(
int n=m+
1;n<
9;n++)}
}// todo auto-generated method stub
return
true;}
//檢查每行是否有重複
private
boolean
checkline
(int i)
}return
true;}
//檢查每列是否有重複
private
boolean
checkcol
(int j)
}return
true
;}
public
static
void
main
(string[
] args)
int[
] game=
newint[9
][9]
; game=sd.
generategame()
;for
(int i=
0;i<
9;i++
) system.out.
println()
;}}
更新:
package leetcode;
public
class
code36,,
,,,,
,,};
code36.
isvalidsudoku
(board);}
public
boolean
isvalidsudoku
(string[
] board)
else}}
//輸出map
system.out.
println
("map");
for(
int[
] ints : map)
system.out.
println()
;}//dfs搜尋,從0,0開始搜尋,並輸出結果陣列,count作為結束標註
findanswer
(map,result,count)
; system.out.
println
("是否能成功到達"
+isarrive)
;return
false;}
private
boolean
findanswer
(int
map,
int[
] result,
int count)
private
void
dfs(
int[
] map,
int[
] result,
int count,
int i,
int j)
} isarrive++
;return;}
if(result[i]
[j]==2)
else
}else
if(result[i]
[j]==0)
else
// result[i][j]=0;
// map[i][j]=0;}}
result[i]
[j]=0;
map[i]
[j]=0;
count++
;//如果所有的嘗試都嘗試完了,就沒有情況了,該種嘗試應該作廢
return;}
}private
boolean
checklegal
(int
map,
int i,
int j)
}//檢查列
for(
int k =
0; k < map.length; k++)}
//檢查3*3,計算3*3座標
int sx=i/3*
3;int sy=j/3*
3;for(
int m=
0;m<
8;m++
)for
(int n = m +
1; n <
9; n++)}
}return
true;}
}
之後,會盡快把任務二發上來,人機互動介面還不會,慘啊,swing咱也沒學過。 C 回溯法生成數獨
演算法思路 首先第一行肯定是1 9的一種排列,直接使用shuffle進行隨機。從第二行第乙個開始,嘗試填入數字,填入後依據數獨規則進行可行性判斷。如果可以填入該數字,則對下一格進行相同的判斷。如果某一格對於任何數字的填入都違反了數獨規則,則進行回溯,重新填上一格的數字。當獲得乙個可行結果時,演算法終...
回溯法的應用之 數獨遊戲
數獨我就不多說話了 沒玩過的可以自己玩玩,或者百科下 關鍵是回溯法。這次是巧妙的利用八皇后的基礎搞出來的 下面我就來好好講將回溯法。上面的話一大推,你會發現很多廢話,其實回溯就是倒著來,返回。我們來回顧下本演算法的回溯演算法 1 include 2 3using namespace std 45 d...
唯一解的數獨題目生成器 理解回溯法
在生成數獨題目時,流程是 生成乙個完整的數獨 隨機挖空 解題 如果只有乙個解,則生成該題目,如果有多個解,則重新挖空。數獨題目的生成涉及的乙個演算法是回溯法,這裡面的完整數獨的生成 求解都用到了回溯法。1.生成完整數獨 在生成部分,先生成所有宮的1,再生成所有宮的2,以此類推。主要有三個值 bool...