国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

八皇后問題,秒懂遞歸回溯(有圖詳解|c語言)

這篇具有很好參考價值的文章主要介紹了八皇后問題,秒懂遞歸回溯(有圖詳解|c語言)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

目錄

????前言

????題目介紹

????引入:

????解決思路:

????理論存在,實踐開始!

????難點1:如何表示對角線被占領(lǐng)?

????難點2:如何用遞歸的方法來放皇后?

????難點3:如何實現(xiàn)回溯?

????難點4:如何實現(xiàn)皇后位置的輸出?

????全部代碼如下:

????總結(jié):?

Love?is?worth?years.?熱愛可抵歲月漫長。


前言

各位和我一樣的剛學(xué)完遞歸的小白們,是不是突然遇見了一個大BOSS,八皇后????問題??!把自信的說著“老子遞歸學(xué)好了!”的你一棒子打回了出生點,就像你剛玩只狼遇到的那個大胖子,剛玩原神遇到的雪山。今天,我就和大家一起學(xué)習(xí)一下這個著名的八皇后????問題。

八皇后問題c語言,c語言,c語言,算法,學(xué)習(xí)


題目介紹

八皇后問題,是一個古老而著名的問題,是回溯算法的典型例題。該問題是十九世紀(jì)著名的數(shù)學(xué)家高斯1850年提出:在8×8格的國際象棋上擺放八個皇后,使其不能互相攻擊,即任意兩個皇后都不能處于同一行、同一列或同一斜線上,問有多少種擺法并輸出每一種擺法。

八皇后問題c語言,c語言,c語言,算法,學(xué)習(xí)

?升華:我在做這個東西的時候本來想用人腦將他們擺進(jìn)去,發(fā)現(xiàn)太!麻!煩!可能這就是計算機(jī)存在的意義吧!


引入:

不知道大家有沒有在前面學(xué)習(xí)遞推的時候?qū)W過馬攔過河卒的問題沒看過的可以點這,這個問題和那個問題都是一個棋類的問題,他們也有相同之處,都是需要用一個數(shù)組來表示這個地方有沒有被占領(lǐng),象棋的那個題是馬占領(lǐng)的地方需要標(biāo)記,而這個題是皇后占領(lǐng)的每一行每一列每一個對角線都需要標(biāo)記。所以我們可以采用一些個數(shù)組來表示這個地方被皇后占領(lǐng)了。當(dāng)然這個題還用到了一個重要的算法就是遞歸算法和回溯的思想


解決思路:

1.首先定義三個數(shù)組分別表示列被占領(lǐng),左對角線被占領(lǐng),和右對角線被占領(lǐng)。因為我們一行一行的放進(jìn)去所以不用考慮行的問題。????

2.利用遞歸算法在沒有被占領(lǐng)的地方一行一行的放入我們的皇后。????

3.利用遞歸和回溯算法一行一行的放入皇后。????


理論存在,實踐開始!

難點1:如何表示對角線被占領(lǐng)?

用數(shù)組來表示列被占領(lǐng)很簡單,只要讓皇后所在的那一列的數(shù)組的值都等于0,就可以解決這個問題,但如何用數(shù)組來表達(dá)對角線呢??你知道吧!你數(shù)一數(shù),這一共有多少個對角線?一共有15條對角線,所以我們可以定義兩個數(shù)組d1和d2來用來表示兩個方向的對角線。如果被占領(lǐng)就是0沒有被占領(lǐng)就是1

定義代碼如下:

int d1[15]={1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};//定義上對角線
int d2[15]={1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} ;//定義下對角線

如何在擺放的時候來確定哪一行哪一列呢?這樣定義十五行太好定義了但是想要表示就難了,我們來研究一下這個東西。看下圖,如這個第五列第三行的這個女皇,這個皇后占領(lǐng)了這兩個對角線,?如何來表示上對角線(皇后????的左上和右下從右上腳開始1、2、3、4、5...)?d1[n-col+7]=0;(col為女皇所在的列)也就是讓行減去列再加上7就是表示的上對角線的個數(shù)。八皇后問題c語言,c語言,c語言,算法,學(xué)習(xí)

有小朋友要問了:你咋知道的???給你看一個上對角線的圖??!

用行-列得到的圖是這樣的(我的那個棋盤沒有第零行,大家可以看成有第零行的和列的,這個圖太難改了你懂我的意思吧):

八皇后問題c語言,c語言,c語言,算法,學(xué)習(xí)

?而把這個數(shù)加7也就是行-列+7,是這樣的:八皇后問題c語言,c語言,c語言,算法,學(xué)習(xí)

?這樣我們不就可以用行標(biāo)和列標(biāo)來表示他所在的上對角線了嘛,神器吧?。?/p>

希望各位xdm都把這個背過說實話我要是自己推我也推不出來這個玩意??!

下對角線:用行加列就會神奇的發(fā)現(xiàn)變成了下面這個樣子:八皇后問題c語言,c語言,c語言,算法,學(xué)習(xí)


好了xdm現(xiàn)在讓我們大聲背三遍:

上對角線:行-列+7?。⌒?列+7??!行-列+7!!

下對角線:行+列?。⌒?列??!行+列!!


好了記住了吧?。。〔灰浟?!像對待女朋友的生日一樣對待這幾個字!??!

這樣我們就可以用:d1[n-col+7],d2[n+col]來讀取皇后的對角線的占領(lǐng)情況了!

這個難點解決了,我們來進(jìn)入下一個難點遞歸。


難點2:如何用遞歸的方法來放皇后?

1.皇后的放置問題:place[8]={0};來表示皇后的位置的話,用table[8][8]={0};來表示一個8*8的大棋盤用一個for循環(huán)來訪問棋盤的每一行,如果這個位置可以放(那幾個約束條件都是1沒有被占領(lǐng)的話)我們就可以讓這一行的皇后的位置棋盤上放上皇后即place[n]=col;,表示皇后在此列????(一會打印的時候可以用的到)然后讓皇后的列和那兩個對角線為0,表示占領(lǐng)!?flag[col]=0;?d1[n-col+7]=0;d2[n+col]=0;

2.皇后的遞歸調(diào)用問題:

我們想要一行一行的擺放皇后,然后一列一列的嘗試對不對

用col來表示列的話,用一個循環(huán):?? ?for (col=0;col<8;col++)來訪問每一列!

放置皇后用數(shù)組place[n]=col;(n表示行)來表示這個列,我皇后????占了!??!

flag[col]=0;? d1[n-col+7]=0;d2[n+col]=0;//將該皇后所在的行、列、對角線設(shè)置為被占領(lǐng)

這樣我們皇后在一行的放置問題解決了!,那么如何訪問每一行呢?

這時候我們就需要用到神奇的遞歸神器!

如果queen(n+1);發(fā)現(xiàn),老資????沒座位了!他就會對queen(n);說:“姐姐,姐姐你能不能去下一個座位讓妹妹我坐下呀”如果queen(n);發(fā)現(xiàn)她如果向下面去她也沒座位了她會向queen(n-1)說:....直到這8個皇后全坐下了,他們不吵架了,我們才能把這個棋盤輸出出來?。。?/p>

這不就是老和尚給小和尚講故事的遞歸嘛,而這個故事的大結(jié)局是皇后全都坐下!

我們?nèi)绻@個行數(shù)小于七行(初始行為0你要是初始行為一可以加一)我們就可以繼續(xù)向下擺放,對不對,就繼續(xù)使用遞歸,來擺這個棋盤的下一行。

if(n<7)?? ?{queen(n+1);}//當(dāng)行數(shù)小于7時;遞歸調(diào)用下一行。

如果我們的皇后把這次棋盤的擺好了我們就可以把這個棋盤輸出出來了!

else{print();}(這個函數(shù)我們下面講)//調(diào)用輸出函數(shù),

請大家看代碼:

int queen(int n )//定義遞歸回溯函數(shù)
{
	int col;
	for (col=0;col<8;col++)
	{
		if (flag[col]&&d1[n-col+7]&&d2[n+col])//判斷皇后是否沖突
		{
			place[n]=col;//放置皇后
			flag[col]=0;
			d1[n-col+7]=0;
            d2[n+col]=0;//將該皇后所在的行、列、對角線設(shè)置為被占領(lǐng)
			if(n<7)	{queen(n+1);}//當(dāng)行數(shù)小于7時;遞歸調(diào)用下一行
		else{print();}//調(diào)用輸出函數(shù)
			flag[col]=1;//回溯
			d1[n-col+7]=1;
			d2[n+col]=1;
		}
	}
	return count;
}

輸出了一個棋盤還不夠,我們要輸出所有的棋盤,怎么辦呢??這時候我們就要請我們的回溯算法登場了!?


難點3:如何實現(xiàn)回溯?

因為我們用的是遞歸算法如果這一行輸出不了我們就把責(zé)任退回給上一行,直到我們找到了一個棋盤上面正好能夠放著這八個皇后的時候我們就把他打印出來了。邏輯是不是這樣的

那么如果我們在循環(huán)的最后加上flag[col]=1;?d1[n-col+7]=1;?d2[n+col]=1;是不是就是把這個占領(lǐng)的皇后踢出去了,然后再把這個皇后放在下一列來看看后面的那些皇后能不能成功擺放?

什么時候會觸發(fā)這個回溯算法呢??

答案是:當(dāng)上面的遞歸算法全執(zhí)行完了一次,并且輸出了一個棋盤后,我們就可以讓她執(zhí)行第二次了!!

我們來繼續(xù)講一個故事:最后那個????在自己家里呆夠了,老娘不想呆了,她又和樓上說,我要去下一個地方玩玩,你們看看怎么給我協(xié)調(diào)一下,原來我的位置就空出來了。樓上想;你去下面我去哪??!于是他只好和樓上說,樓下和他說過的話。

這就是flag[col]=1;?d1[n-col+7]=1;?d2[n+col]=1;老娘不想待了,全給我搬家!

運行完這個以后呢,for循環(huán)中的col就進(jìn)入下一列了,他這樣一進(jìn)不要緊,又觸發(fā)了遞歸算法,一層一層的倒換,來滿足需求。

當(dāng)這個皇后全嘗試了一遍其他能嘗試的地方,就安穩(wěn)了。

這樣講應(yīng)該能講明白為什么使用這個回溯算法,以及回溯算法為什么在if里面了吧如果不在if里面,這個回溯算法就沒有意義了。

            flag[col]=1;//回溯
			d1[n-col+7]=1;
			d2[n+col]=1;

難點4:如何實現(xiàn)皇后位置的輸出?

這個時候我們可以直接用一個輸出函數(shù)來輸出

這部分簡單直接上代碼:

void print()//定義輸出函數(shù)
{
	int i,j;
    count++;//每調(diào)用一次輸出函數(shù)number自加一次,記錄擺放方法個數(shù)
	printf("No.%2d\n",count);
	int table[8][8]={0};//設(shè)置一個8*8的棋盤
	for (i=0;i<8;i++)
	{
		table[i][place[i]]=1;//將每一行皇后所在位置賦值為1
	}
	for (i=0;i<8;i++)
	{
		for (j=0;j<8;j++)
		{
	printf("%d|",table[i][j]);
		}printf("\n");
	}
}

這樣我們就能輸出這些傲嬌的皇后們了!!


全部代碼如下:

#include<stdio.h>
int place[8]={0};//皇后位置
int flag[8]={1,1,1,1,1,1,1,1};//定義列
int d1[15]={1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};//定義上對角線(共有15個對角線,
//因此定義一個長度為15的數(shù)組,初值為1代表該對角線沒有被皇后占領(lǐng),
//若被皇后占領(lǐng)則賦值為0
int d2[15]={1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} ;//定義下對角線
int count=0;//記錄輸出次數(shù)
void print()//定義輸出函數(shù)
{
	int i,j;
    count++;//每調(diào)用一次輸出函數(shù)number自加一次,記錄擺放方法個數(shù)
	printf("No.%2d\n",count);
	int table[8][8]={0};//設(shè)置一個8*8的棋盤
	for (i=0;i<8;i++)
	{
		table[i][place[i]]=1;//將每一行皇后所在位置賦值為1
	}
	for (i=0;i<8;i++)
	{
		for (j=0;j<8;j++)
		{
	printf("%d|",table[i][j]);
		}printf("\n");
	}
}
int queen(int n)//定義遞歸回溯函數(shù)
{
	int col;
	for (col=0;col<8;col++)
	{
		if (flag[col]&&d1[n-col+7]&&d2[n+col])//判斷皇后是否沖突
		{
			place[n]=col;//放置皇后
			flag[col]=0;
			d1[n-col+7]=0;
            d2[n+col]=0;//將該皇后所在的行、列、對角線設(shè)置為被占領(lǐng)
			if(n<7)	{queen(n+1);}//當(dāng)行數(shù)小于7時;遞歸調(diào)用下一行
            else{print();}//調(diào)用輸出函數(shù)
            flag[col]=1;//回溯
			d1[n-col+7]=1;
			d2[n+col]=1;
		}
	}
	return count;
}
int main()
{
count=queen(0);//從第0行開始擺放皇后
printf("共有%d種方法",count);//輸出擺放皇后的方法個數(shù)
	return 0;}

運行結(jié)果部分如下:

八皇后問題c語言,c語言,c語言,算法,學(xué)習(xí)

可以看到一共有92種方法。


總結(jié):?

遞歸問題就是推責(zé)任問題,下邊不行就推給上邊,上邊不行,就推給上上邊。

而回溯就像一個追求完美主義的人,我這邊成了,我還要試試另一種解法行不行,等我把所有的結(jié)果都試出來就完美了!

我們?nèi)四?,既不能追求完美,也不能推卸?zé)任,只有做好自己。

大家仔細(xì)的把這個八皇后算法搞懂,就會發(fā)現(xiàn)原來遞歸和回溯這么簡單,不要得過且過?。?/strong>

八皇后問題c語言,c語言,c語言,算法,學(xué)習(xí)文章來源地址http://www.zghlxwxcb.cn/news/detail-782343.html

Love?is?worth?years.? 熱愛可抵歲月漫長。

到了這里,關(guān)于八皇后問題,秒懂遞歸回溯(有圖詳解|c語言)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 算法:回溯算法(以解決n皇后問題為例)

    算法:回溯算法(以解決n皇后問題為例)

    基本思想:回溯算法的基本思想是:從一條路往前走,能進(jìn)則進(jìn),不能進(jìn)則退回來,換一條路再試。八皇后問題就是回溯算法的典型,第一步按照順序放一個皇后,然后第二步符合要求放第2個皇后,如果沒有位置符合要求,那么就要改變第一個皇后的位置,重新放第2個皇后

    2024年02月05日
    瀏覽(17)
  • python中級篇1:n皇后問題(回溯算法)

    hello!大家好,我是浪矢秀一。最近經(jīng)歷了許多事情,終于是恢復(fù)1次更新了。那么今天呢,我們來學(xué)習(xí)中級篇,需要學(xué)過不少python知識的人來學(xué)習(xí)。好了,廢話不多說,我們進(jìn)入今天的課程! ? 在1個n*n的國際象棋棋盤上,放置n個皇后,要求:同1行、同1列、同1斜線上只能有1個皇后。 ? 既然

    2024年02月03日
    瀏覽(24)
  • 遞歸算法學(xué)習(xí)——N皇后問題,單詞搜索

    遞歸算法學(xué)習(xí)——N皇后問題,單詞搜索

    目錄 ?編輯 一,N皇后問題 1.題意 2.解釋 3.題目接口 4.解題思路及代碼 二,單詞搜索 1.題意 2.解釋 3.題目接口 4.思路及代碼 1.題意 按照國際象棋的規(guī)則,皇后可以攻擊與之處在同一行或同一列或同一斜線上的棋子。 n?皇后問題 ?研究的是如何將? n ?個皇后放置在? n×n ?的

    2024年02月09日
    瀏覽(26)
  • 【算法】遞歸、回溯、剪枝、dfs 算法題練習(xí)(組合、排列、總和問題;C++)

    【算法】遞歸、回溯、剪枝、dfs 算法題練習(xí)(組合、排列、總和問題;C++)

    后面的練習(xí)是接著下面鏈接中的文章所繼續(xù)的,在對后面的題練習(xí)之前,可以先將下面的的文章進(jìn)行了解??: 【算法】{畫決策樹 + dfs + 遞歸 + 回溯 + 剪枝} 解決排列、子集問題(C++) 思路 題意分析 :要求根據(jù)給出的數(shù)字,算出合法的括號組成個數(shù)。根據(jù)題目,我們可以總

    2024年02月22日
    瀏覽(24)
  • 回溯法--n皇后問題

    回溯法--n皇后問題

    回溯法有兩個模板--子集樹、排列樹,他們有回溯法的共同特點:深度優(yōu)先搜索,如果一條路走不通,再退回來(類似遞歸) 八皇后問題最早是由國際象棋棋手馬克斯·貝瑟爾(Max Bezzel)于1848年提出。第一個解在1850年由弗朗茲·諾克(Franz Nauck)給出。并且將其推廣為更一般

    2024年02月02日
    瀏覽(20)
  • 八皇后問題(回溯法)

    八皇后問題(回溯法)

    目錄 什么是八皇后 八皇后問題怎么解決? 什么是回溯法 回溯法的模板 八皇后問題的核心代碼 判斷皇后位置是否可行 總體實現(xiàn)代碼 每日一句: 種一棵樹的最好時間是十年前,其次是現(xiàn)在。 八皇后問題(英文:Eight queens),是由國際西洋棋棋手馬克斯·貝瑟爾于1848年提出的

    2023年04月09日
    瀏覽(19)
  • 回溯法求解八皇后問題

    回溯法求解八皇后問題

    問題提出 :八皇后問題是一個古老而著名的問題。該問題是十九世紀(jì)著名的數(shù)學(xué)家高斯1850 提出在 8x8 格的國際象棋上擺放八皇后,使其不能互相攻擊,即任意兩個皇后都不能處于同一行、同一列或同一斜線上,問有多少種擺法。高斯認(rèn)為有76種方案。1854年在柏林的象棋雜志

    2023年04月08日
    瀏覽(22)
  • 3.2 回溯法—N皇后問題

    3.2 回溯法—N皇后問題

    1. 問題描述 在 n × n ntimes n n × n 的棋盤上擺放 n n n 個皇后,使任意兩個皇后都不能處于同一行、同一列或同一斜線上 2. 問題分析 下以求解4皇后問題為例,分析4皇后問題的排列樹以及回溯過程: 搜索及回溯過程: 解空間樹: 3. 算法設(shè)計 1. 算法思想 ①用數(shù)組x[]存放皇后的

    2024年02月04日
    瀏覽(17)
  • 遞歸求解n皇后問題的解析和求解(矩陣儲存版)

    遞歸求解n皇后問題的解析和求解(矩陣儲存版)

    1. n皇后問題問題描述 ? n皇后問題來源于著名的十九世紀(jì)著名數(shù)學(xué)家提出的八皇后問題。問題為:在8×8的棋盤上擺放八個皇后,皇后之間不能互相攻擊,既任意兩個皇后不在同一行、同一列,也不再同一斜線上。n皇后則是在八皇后的基礎(chǔ)上,將棋盤擴(kuò)充為n×n,皇后的數(shù)量也

    2024年01月19日
    瀏覽(13)
  • C#八皇后算法:回溯法 vs 列優(yōu)先法 vs 行優(yōu)先法 vs 對角線優(yōu)先法

    目錄 1.八皇后算法(Eight Queens Puzzle) 2.常見的八皇后算法解決方案 (1)列優(yōu)先法(Column-First Method): (2)行優(yōu)先法(Row-First Method): (3)對角線優(yōu)先法(Diagonal-First Method): (4)回溯法(Backtracking): ???????皇后問題是一個古老而著名的問題,它實質(zhì)上就是使棋

    2024年03月22日
    瀏覽(15)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包