回溯算法解決八皇后問題(包含C語言實現代碼)

2021-03-05 編程大師

八皇后問題是以西洋棋為背景的問題:有八個皇后(可以當成八個棋子),如何在 8*8 的棋盤中放置八個皇后,使得任意兩個皇后都不在同一條橫線、縱線或者斜線上。



圖 2 八皇后問題示例(#代表皇后)


八皇后問題是使用回溯算法解決的典型案例。算法的解決思路是:

從棋盤的第一行開始,從第一個位置開始,依次判斷當前位置是否能夠放置皇后,判斷的依據為:同該行之前的所有行中皇后的所在位置進行比較,如果在同一列,或者在同一條斜線上(斜線有兩條,為正方形的兩個對角線),都不符合要求,繼續檢驗後序的位置。

如果該行所有位置都不符合要求,則回溯到前一行,改變皇后的位置,繼續試探。

如果試探到最後一行,所有皇后擺放完畢,則直接列印出 8*8 的棋盤。最後一定要記得將棋盤恢復原樣,避免影響下一次擺放。


實現代碼:

#include <stdio.h>int Queenes[8]={0},Counts=0;int Check(int line,int list){        for (int index=0; index<line; index++) {                int data=Queenes[index];                if (list==data) {            return 0;        }                if ((index+data)==(line+list)) {            return 0;        }                if ((index-data)==(line-list)) {            return 0;        }    }        return 1;}void print(){    for (int line = 0; line < 8; line++)    {        int list;        for (list = 0; list < Queenes[line]; list++)            printf("0");        printf("#");        for (list = Queenes[line] + 1; list < 8; list++){            printf("0");        }        printf("\n");    }    printf("================\n");}void eight_queen(int line){        for (int list=0; list<8; list++) {                if (Check(line, list)) {                        Queenes[line]=list;                        if (line==7) {                                Counts++;                                print();                                Queenes[line]=0;                return;            }                        eight_queen(line+1);                        Queenes[line]=0;        }    }}int main() {        eight_queen(0);    printf("擺放的方式有%d種",Counts);    return 0;}

大家可以自己運行一下程序,查看運行結果,由於八皇后問題有 92 種擺法,這裡不一一列舉。

相關焦點

  • 漫畫:什麼是八皇后問題?
    如何解決八皇后問題?所謂遞歸回溯,本質上是一種枚舉法。這種方法從棋盤的第一行開始嘗試擺放第一個皇后,擺放成功後,遞歸一層,再遵循規則在棋盤第二行來擺放第二個皇后。八皇后問題的代碼實現?解決八皇后問題,可以分為兩個層面:1.
  • C/C+編程筆記:在C+中如何調用C語言的代碼?你可以這樣做
    這樣說也沒錯,因為C++本來就包含了C。比如在C文件中存在一個函數func_c(), 該文件與C++的工程混編在一起時,可以直接在C++中調用C文件中的func_c();不需要做任何額外處理。
  • 拓撲排序算法及C語言實現
    拓撲排序算法的實現過程對有向無環圖進行拓撲排序,只需要遵循兩個原則:在圖中選擇一個沒有前驅的頂點 V;從圖中刪除頂點 V 和所有以該頂點為尾的弧。例如,在對圖 1 中的左圖進行拓撲排序時的步驟如圖 2 所示:
  • 在學C語言的人,怎能不了解這些經典算法問題?
    C語言中有有許多經典的算法,這些算法都是許多人的智慧結晶,也是編程中常用的算法,這裡面包含了眾多算法思想,掌握這些算法,對於學習更高級的、更難的算法都會有很大的幫助,會為自己的算法學習打下堅實的基礎。
  • C語言?c+?到底先學哪個才能更好的理解編程,這些你造嗎
    最近大一新生們剛剛結束第一個學期的學習,接踵而來的問題也越來越多,不同的學校有不同的學習節奏,但是基本上都是從C語言或者c++開始學起。現在越來越多的人對於「學習C語言還有必要嗎?」這件事比較糾結。
  • 教你輕鬆學習C語言系列之——從「Hello World」開始夢想起航
    看到密密麻麻的代碼,對於很多初學者來說,即覺得好玩又新奇,但同時也在不停地問自己:「我能學得會嗎?」其實編程難也不難。說它難,是因為隨著學習的深入,抽象的概念、交叉的學科、複雜的問題交織在一起,對學習者的邏輯思維確實是一項挑戰;說它不難,對於喜歡編程、想要學習編程的愛好者來說,其實也很容易上手。
  • 算法思想簡介(分制),貪心(DJS)動態分配(dp)回溯(萬能)
    算法思想簡介(分制(分開在遞歸),貪心(DJS),動態分配(dp,解決多變化條件),回溯(萬能,深度優先))不管是動態規劃,還是回溯都是在可選擇 條件固定時,進行選擇 ,都會用到遞歸調用。不同的是:貪心最好理解,從頭開始找最優結果一直到最後。
  • 兩種曲線點抽稀算法-Python實現 附代碼
    比較常用的兩種抽稀算法是:道格拉斯-普克(Douglas-Peuker)算法和垂距限值法。 下面是Python代碼實現: # -*- coding: utf-8 -*- """ ----   File Name:    DouglasPeuker   Description :  道格拉斯-普克抽稀算法   Author :        J_hao   date:          2017/8/16 ----   Change Activity:
  • 用AI實現C++、Java、Python代碼互譯,運行成功率最高達80.9%
    而且TransCoder是一種無監督學習算法,意味著不需要大量成對的、標記的編程代碼數據集進行訓練。如果這項技術達到實用化程度,對廣大程式設計師來說真是巨大福音啊!難怪論文作者之一Guillaume Lample在Twitter上宣布了這篇論文後很快引起了熱議。翻譯程式語言,什麼原理?
  • 清華畢業生開發嵌入Python的程式語言,99行代碼實現《冰雪奇緣》
    因為他用99行代碼,實現了《冰雪奇緣》的特效。據悉,當時艾莎施展魔法的特效鏡頭,儘管僅僅呈現短暫的一秒鐘,但卻需要高性能計算機,運算一周的時間。《冰雪奇緣》雖然沒有真人出演,預算卻高達1.5億美元,每一秒的鏡頭都是經費在燃燒。一般人想用電腦做出CG特效簡直不可想像。
  • C語言代碼實現:6174數學黑洞(卡普雷卡爾常數)
    6174 經過了7次最大減最小的動作 請輸入一個互不相同的四位數:5287 輸入的四位數是:5287 第1次:8752 - 2578 = 6174 經過了1次最大減最小的動作 3:C語言代碼的實現
  • C語言編程核心要點
    類型C是強類型語言,有short、long、int、char、float、double等build-in數據類型,類型是貫穿c語言整個課程的核心概念。struct、union、enum屬於c的構造類型,用於自定義類型,擴充類型系統。變量變量用來保存數據,數據是操作的對象,變量的變字意味著它可以在運行時被修改。
  • 一行Python 代碼能實現這麼多喪心病狂的功能?
    最近看知乎上有一篇名為《一行 Python 能實現什麼喪心病狂的功能?》(https://www.zhihu.com/question/37046157)的帖子,點進去發現一行Python代碼可以做這麼多喪心病狂的功能!整理了一下知乎上這篇文章的內容,頗覺有趣,分享給大家。
  • 集合三大類無模型強化學習算法,BAIR開源RL代碼庫rlpyt
    其中大部分屬於無模型算法,共分為三類:深度 Q 學習(DQN)、策略梯度和 Q 值策略梯度(QPG)。由於它們依賴不同的學習機制、解決不同(但有重合)的控制問題、處理不同屬性的動作集(離散或連續),因此這三類算法沿著不同的研究路線發展。目前,很少有代碼庫同時包含這三類算法,很多原始實現仍未公開。因此,從業者通常需要從不同的起點開始開發,潛在地為每一個感興趣的算法或基線學習新的代碼庫。
  • C語言怎麼樣?今天聊聊C語言的發展史!
    第一個C語言編譯器是怎樣編寫的? 不知道你有沒有想過,大家都用C語言或基於C語言的語言來寫編譯器,那麼世界上第一個C語言編譯器又是怎麼編寫的呢?這不是一個「雞和蛋」的問題…… 回顧一下C語言歷史:Tomphson在BCPL的基礎上開發了B語言,Ritchie又在B語言的基礎上成功開發出了現在的C語言。
  • JavaScript實現排序算法
    O(N^2)的大關,為了紀念該算法裡程碑式的意義,用Shell來命名該算法;插入排序的問題:假設一個很小的數據項在很靠近右端的位置>以下代碼實現中採用希爾排序原稿中建議的增量即N / 2。代碼實現: 這裡解釋一下上述代碼中的三層循環:第一層循環:while循環,控制gap遞減到1;第二層循環:
  • Libra 的 Move 語言初探,10 行代碼實現你第一個智能合約
    ,據稱可以在Libra區塊鏈中實現自定義交易邏輯和『智能合約」。  Move語言最主要的特性  可編程的Move交易腳本    每一個Libra區塊鏈上交易都包含 Move交易腳本 用來對交易邏輯的編碼,同時驗證器據此驗證客戶端的行為(例如,將Libra幣從Alice的帳戶移動到Bob的帳戶)。
  • AEA人工智慧可視化編程及代碼教育解決方案:打開算法黑箱
    2020年6月,國內領先人工智慧教育技術提供商聯合偉世發布了新一代「人工智慧可視化編程及代碼教育套件」——AEA600系列。人工智慧實現全過程②AEA100/200/600系列課程讓學生與人工智慧技術零距離接觸,
  • 【愛找茬】都是C語言,單片機C語言和普通的C語言究竟有什麼差異呢?
    許多小夥伴在學完C語言後想入門單片機,但學著學著發現明明都是C語言,為什麼單片機C語言和我當初學的C語言有差異呢?今天小編就來梳理我們平時所學的C語言與單片機C語言的有什麼樣的不同。
  • C 語言,你真的懂遞歸了嗎?
    遞歸求階乘使用遞歸求階乘是很經典的方法,我們看一下代碼。scanf("%d",&x); x = fact(x);//調用函數返回int值 printf("%ld\n",x); return (0);}int fact(unsigned long n){//定義階乘函數 if(n==1) return 1;//輸入的參數是1,直接返回1 else return n*fact(n-1);//遞歸算法