八皇后問題求解

我今天好不容易上了一次課,然后數(shù)據(jù)結(jié)構(gòu)老師給我們留大作業(yè)也拜,喪心病狂以舒,先解決一個(gè)叫八皇后的問題。

題目背景:

【問題描述】

在一個(gè)8×8的棋盤里放置8個(gè)皇后慢哈,要求每個(gè)皇后兩兩之間不相"沖"(在每一橫列豎列斜列只有一個(gè)皇后)蔓钟。

【問題分析】

數(shù)組a、b卵贱、c分別用來標(biāo)記沖突滥沫,a數(shù)組代表列沖突,從a[0]~a[7]代表第0列到第7列键俱,如果某列上已經(jīng)有皇后兰绣,則為1,否則為0编振;

數(shù)組b代表主對角線沖突缀辩,為b[i-j+7],即從b[0]~b[14]踪央,如果某條主對角線上已經(jīng)有皇后臀玄,則為1,否則為0畅蹂;

數(shù)組c代表從對角線沖突健无,為c[i+j],即從c[0]~c[14]液斜,如果某條從對角線上已經(jīng)有皇后累贤,則為1募胃,否則為0;

【基本要求】

[if !supportLists](1)?[endif]用遞歸算法實(shí)現(xiàn)

[if !supportLists](2)?[endif]輸出所有棋盤狀態(tài)畦浓,其中空的地方為“*”痹束,放置皇后的地方為“@”

11.最小生成樹求解

【問題描述】

在n個(gè)城市之間建設(shè)網(wǎng)絡(luò),只需保證連通即可讶请,求最經(jīng)濟(jì)的架設(shè)方法祷嘶。

【基本要求】

(1)假設(shè)已知n個(gè)城市之間的網(wǎng)絡(luò)是一個(gè)帶權(quán)連通無向圖。

(2)用鄰接矩陣COST表示給定的帶權(quán)連通無向圖夺溢。知陣元素定義為

(3)利用普里姆或克魯斯卡爾算法求圖的最小生成樹论巍。

然后我們現(xiàn)在工具問題的描述進(jìn)行分析:

首先,可歸納問題的條件為风响,8皇后之間需滿足:

???????????? 1.不在同一行上

?????????????2.不在同一列上

???????????? 3.不在同一斜線上

???????????? 4.不在同一反斜線上

???? 這為我們提供一種遍歷的思路嘉汰,我們可以逐行或者逐列來進(jìn)行可行擺放方案的遍歷,每一行(或列)遍歷出一個(gè)符合條件的位置状勤,接著就到下一行或列遍歷下一個(gè)棋子的合適位置鞋怀,這種遍歷思路可以保證我們遍歷過程中有一個(gè)條件是絕對符合的——就是下一個(gè)棋子的擺放位置與前面的棋子不在同一行(或列)。接下來持搜,我們只要判斷當(dāng)前位置是否還符合其他條件密似,如果符合,就遍歷下一行(或列)所有位置葫盼,看看是否繼續(xù)有符合條件的位置残腌,以此類推,如果某一個(gè)行(或列)的所有位置都不合適贫导,就返回上一行(或列)繼續(xù)該行(或列)的其他位置遍歷抛猫,當(dāng)我們順利遍歷到最后一行(或列),且有符合條件的位置時(shí)孩灯,就是一個(gè)可行的8皇后擺放方案闺金,累加一次八皇后可行方案的個(gè)數(shù),然后繼續(xù)遍歷該行其他位置是否有合適的钱反,如果沒有掖看,則返回上一行,遍歷該行其他位置面哥,依此下去。這樣一個(gè)過程下來毅待,我們就可以得出所有符合條件的8皇后擺放方案了尚卫。這是一個(gè)深度優(yōu)先遍歷的過程,同時(shí)也是經(jīng)典的遞歸思路尸红。

????? 接下來吱涉,我們以逐列遍歷刹泄,具體到代碼,進(jìn)一步說明怎爵。

????????首先特石,從第一列開始找第一顆棋子的合適位置,我們知道鳖链,此時(shí)第一列的任何一個(gè)位置都是合適的姆蘸,當(dāng)棋子找到第一個(gè)合適的位置后,就開始到下一列考慮下一個(gè)合適的位置芙委,此時(shí)逞敷,第二列的第一行及第二行顯然就不能放第二顆棋子了,因?yàn)槠渑c第一個(gè)棋子一個(gè)同在一行灌侣,第二列第二行同在一條斜線上推捐。第二列第三行成為第二列第一個(gè)合適的位置,以此類推侧啼,第三列的第5行又會是一個(gè)合適位置牛柒,這個(gè)過程中,我們注意到痊乾,每一列的合適位置都是受到前面幾列的位置所影響焰络,歸納如下:

????? 假設(shè)前面1列的棋子放在第3行,那當(dāng)前列不能放的位置就一定是3行符喝,2行闪彼,4行。因?yàn)槿绻旁谶@三行上就分別跟前一列的棋子同在一行协饲、同在斜線畏腕、同在反斜線上,不符合我們的要求≤猿恚現(xiàn)在我們用cols數(shù)組來表示8個(gè)列棋子所放的行數(shù)描馅,數(shù)組下標(biāo)從0開始,其中數(shù)組下標(biāo)表示列數(shù)而线,數(shù)組的元素值表示該列棋子所在行數(shù)铭污,當(dāng)前列為N(N>=0,N<8),即cols[N-1]=3,則有:

????????????????????? cols[N] != cols[N-1](=3膀篮,表示不在同一行)

???????????????????? ?cols[N] != cols[N-1]-1(=3-1=2嘹狞,表示不在同一斜線上)

???????????????????? ?cols[N]!=cols[N-1]+1(=3+1,表示不在同一反斜線上)

????? 這里我們注意到,如果N-2列存在的話誓竿,那么我們還要考慮當(dāng)前列N不與N-2列的棋子同行磅网,同斜線,同反斜線筷屡。把當(dāng)前列N的前面的某一列設(shè)為m,則m的所有取值為{m>=0,m

??????????????????? cols[N] != cols[m](與第m列的棋子不在同一行)

??????????????????? cols[N] != cols--[m] -(N-m)(>=0 ,與第m列的棋子不在同一斜線上)

??????????????????? cols[N] != cols--[m]?+ (N-m)? (<=8-1,與第m列的棋子不在同一反斜線上) ? ? ? ? ?

?????????? 具體到代碼涧偷,很顯然簸喂,取m的所有值只需要一句循環(huán),同時(shí)我們?yōu)槊恳涣卸x一個(gè)長度為8的布爾數(shù)組row[],下標(biāo)同樣是從0開始燎潮,我們規(guī)定當(dāng)row[i]=true時(shí)喻鳄,表示該列第i行不能放棋子。這樣我們就能寫成下列程序段了:


棋表圖


標(biāo)記

增加一點(diǎn):你其實(shí)也可以這樣子想确封,我某一行和下面一行的橫坐標(biāo)數(shù)字相差不能超出集合下標(biāo)的差除呵。因?yàn)槟氵@樣子想,我兩行最多相差16隅肥,因?yàn)槊看味际窍缺闅v第一行后再遍歷第二行竿奏,所以不能超出這個(gè)范圍。

第二點(diǎn)是:不能出現(xiàn)重復(fù)元素腥放。重復(fù)了還玩?zhèn)€球球泛啸。就是集合表示的元素。

public static int num =0; //累計(jì)方案總數(shù)

public static final int MAXQUEEN =8;//皇后個(gè)數(shù)秃症,同時(shí)也是棋盤行列總數(shù)

public static int[]cols =new int[MAXQUEEN]; //定義cols數(shù)組候址,表示8列棋子擺放情況

public Queen8() {//核心函數(shù)

? ? getArrangement(0);

? ? System.out.print("/n");

? ? System.out.println(MAXQUEEN+"皇后問題有"+num+"種擺放方法。");

}

public void? getArrangement(int n) {

//遍歷該列所有不合法的行种柑,并用rows數(shù)組記錄岗仑,不合法即rows[i]=true

? ? boolean[] rows =new boolean[MAXQUEEN];

? ? for (int i =0; i < n; i++) {

rows[cols[i]] =true;

? ? ? ? int d = n - i;

? ? ? ? if (cols[i] - d >=0) rows[cols[i] - d] =true;

? ? ? ? if (cols[i] + d <=MAXQUEEN -1) rows[cols[i] + d] =true;

? ? }

for (int i =0; i

//判斷該行是否合法

? ? ? ? if (rows[i])continue;

? ? ? ? //設(shè)置當(dāng)前列合法棋子所在行數(shù)

? ? ? ? cols[n] = i;

? ? ? ? //當(dāng)前列不為最后一列時(shí)

? ? ? ? if (n

getArrangement(n +1);

? ? ? ? }else {//累計(jì)方案個(gè)數(shù)

? ? ? ? ? ? num++;

? ? ? ? ? ? //打印棋盤信息

? ? ? ? ? ? printChessBoard();

? ? ? ? }

}

}

public void printChessBoard(){

System.out.print("\n"+"第"+num+"種走法 "+"\n");

? ? for(int i=0;i

for(int j=0;j

if(i==cols[j]){

System.out.print("0 ");

? ? ? ? ? ? }else

? ? ? ? ? ? ? ? System.out.print("+ ");

? ? ? ? }

System.out.print("\n");

? ? }

}

public static void main(String args[]){

Queen8 queen =new Queen8();

? ? queen.printChessBoard();

}

????????思路嘛其實(shí)很簡單,就是為了避免兩個(gè)棋子有相互接觸的空間聚请,然后先遍歷第一行荠雕,然后得到位置以后放到數(shù)組里面,然后遍歷第二行驶赏,獲取位置放到數(shù)組炸卑,然后進(jìn)行比對,看是否合適煤傍,合適繼續(xù)遍歷盖文,不合適就重新返回第一行重新規(guī)劃位置,繼續(xù)遍歷蚯姆。

? ? ? ? 這種題目屬于深度優(yōu)先遍歷的算法五续,當(dāng)然也很無聊。就是平常下棋的時(shí)候的用的招數(shù)龄恋,只是平常沒有想到還可以做算法疙驾,不過作為鍛煉思維,倒是一種很好的玩具篙挽。這個(gè)算法可以運(yùn)用到遞歸荆萤,不斷判斷然后return,繼續(xù)遍歷铣卡。

OK链韭,介紹完畢。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末煮落,一起剝皮案震驚了整個(gè)濱河市敞峭,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌蝉仇,老刑警劉巖旋讹,帶你破解...
    沈念sama閱讀 218,122評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異轿衔,居然都是意外死亡沉迹,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評論 3 395
  • 文/潘曉璐 我一進(jìn)店門害驹,熙熙樓的掌柜王于貴愁眉苦臉地迎上來鞭呕,“玉大人,你說我怎么就攤上這事宛官『桑” “怎么了?”我有些...
    開封第一講書人閱讀 164,491評論 0 354
  • 文/不壞的土叔 我叫張陵腋么,是天一觀的道長。 經(jīng)常有香客問我亥揖,道長,這世上最難降的妖魔是什么费变? 我笑而不...
    開封第一講書人閱讀 58,636評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮胡控,結(jié)果婚禮上扳剿,老公的妹妹穿的比我還像新娘昼激。我一直安慰自己,他們只是感情好橙困,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,676評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著凡傅,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上哼转,一...
    開封第一講書人閱讀 51,541評論 1 305
  • 那天,我揣著相機(jī)與錄音壹蔓,去河邊找鬼趟妥。 笑死佣蓉,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的勇凭。 我是一名探鬼主播疚膊,決...
    沈念sama閱讀 40,292評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼虾标!你這毒婦竟也來了寓盗?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,211評論 0 276
  • 序言:老撾萬榮一對情侶失蹤夺巩,失蹤者是張志新(化名)和其女友劉穎贞让,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體柳譬,經(jīng)...
    沈念sama閱讀 45,655評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡喳张,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,846評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了美澳。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片销部。...
    茶點(diǎn)故事閱讀 39,965評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖制跟,靈堂內(nèi)的尸體忽然破棺而出舅桩,到底是詐尸還是另有隱情,我是刑警寧澤雨膨,帶...
    沈念sama閱讀 35,684評論 5 347
  • 正文 年R本政府宣布擂涛,位于F島的核電站,受9級特大地震影響聊记,放射性物質(zhì)發(fā)生泄漏撒妈。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,295評論 3 329
  • 文/蒙蒙 一排监、第九天 我趴在偏房一處隱蔽的房頂上張望狰右。 院中可真熱鬧,春花似錦舆床、人聲如沸棋蚌。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,894評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽谷暮。三九已至蒿往,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間坷备,已是汗流浹背熄浓。 一陣腳步聲響...
    開封第一講書人閱讀 33,012評論 1 269
  • 我被黑心中介騙來泰國打工情臭, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留省撑,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,126評論 3 370
  • 正文 我出身青樓俯在,卻偏偏與公主長得像竟秫,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子跷乐,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,914評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 前言 八皇后問題是一個(gè)古老而著名的問題肥败,是回溯算法的典型例題。該問題是十九世紀(jì)著名的數(shù)學(xué)家高斯1850年提出:在8...
    jacky123閱讀 1,556評論 0 3
  • 望江南 花滿樓愕提,滿心頭馒稍,香浮襲人柔。道是也還羞浅侨。 人如舊,如心休如输,情動(dòng)惹人愁。恰似...
    一席之賓閱讀 239評論 0 1
  • 第四節(jié) 下 總是想將與你的距離拉近一點(diǎn)再拉近一點(diǎn)澳化,可又是那樣容易自我否定自我逃離。在迷離的距離里缎谷,又出現(xiàn)了更多的...
    葉子程閱讀 167評論 1 1
  • 吳軍老師的文章中寫道 職業(yè)選手和業(yè)余選手的區(qū)別并不在于后者發(fā)揮不好灶似,而只是他們不穩(wěn)定,情緒波動(dòng)較大...
    山澗百合Y閱讀 588評論 1 1