1. 程式人生 > >遞迴求解八皇后問題

遞迴求解八皇后問題

問題描述
會下國際象棋的人都很清楚:皇后可以在橫、豎、斜線上不限步數地吃掉其他棋子。如何將 8 個皇后放在棋盤上(有 8 * 8 個方格),使它們誰也不能被吃掉!這就是著名的八皇后問題。 對於某個滿足要求的 8 皇后的擺放方法,定義一個皇后串 a 與之對應, a=b1b2...b8,即其中 bi 為相應擺法中第 i 行皇后所處的列數。已經知道 8 皇后問題一共有 92 組解(即 92 個不同的皇后串)。給出一個數 b,要求輸出第 b 個串。串的比較是這樣的:皇后串 x 置於皇后串 y 之前,當且僅當將 x 視為整數時比 y 小。

輸入資料
第 1 行是測試資料的組數 n,後面跟著 n 行輸入。每組測試資料佔 1 行,包括一個正整
數 b(1 <= b <= 92)

輸出要求
n 行,每行輸出對應一個輸入。輸出應是一個正整數,是對應於 b 的皇后串
輸入樣例
2
1
92

輸出樣例
15863724
84136275


遞迴解八皇后問題, 從題目的意思可以看出每一個皇后在橫,豎,斜的方向上是佔有控制權的,那麼在一個棋盤上每一行最多隻能擺一個棋子,每擺好一個皇后如果我記錄她的控制範圍,那麼我下一次就從下一行逐列的搜尋沒有被已經擺過的皇后所控制的區域。 依次搜尋下去,直到擺完八個皇后為止。
從每一次擺放皇后的過程中我們可以發現每一個皇后的擺放過程都是一樣的,那麼我們可以只需要寫出一個皇后的擺放過程就可以了,而皇后的總數最多隻有8個,很明顯這樣的特徵已經構成了遞迴的性質。

那麼在實際解的過程中,我們可以用3個一維陣列來記錄列控制,45度角控制,135度角控制。

據此我們可以寫出程式碼:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int resu[92][8], mark[9];
int rang[9], line_45[17], line_135[17];
int count=0;

void f(int i)
{
    int j;
    if(i > 8)
    {
        // 得到一組新解
        for(j=0; j < 8; j++)
            resu[count][j] = mark[j+1];
        count++;
    }
    // 每次均從小到大遍歷,保證最後的結果序列是有序的
    for(j=1; j < 9; j++)
    {
        if(rang[j] && line_45[i+j] && line_135[j+9-i])
        {
            mark[i] = j;
            rang[j] = line_45[i+j] = line_135[j+9-i] = 0;
            f(i+1);
            rang[j] = line_45[i+j] = line_135[j+9-i] = 1;
        }
    }
}

int main()
{
    int nCase, number, i;
    memset(rang, 1, sizeof(rang));
    memset(line_45, 1, sizeof(line_45));
    memset(line_135, 1 , sizeof(line_135));
    scanf("%d", &nCase);
    f(1);
    while(nCase-- > 0)
    {
        scanf("%d", &number);
        for(i=0; i < 8; i++)
            printf("%d", resu[number-1][i]);
        printf("\n");
    }
    return 0;
}


相關推薦

求解皇后問題

問題描述會下國際象棋的人都很清楚:皇后可以在橫、豎、斜線上不限步數地吃掉其他棋子。如何將 8 個皇后放在棋盤上(有 8 * 8 個方格),使它們誰也不能被吃掉!這就是著名的八皇后問題。 對於某個滿足要求的 8 皇后的擺放方法,定義一個皇后串 a 與之對應, a=b1b2..

C語言回溯法求解皇后問題

Problem E 8皇后問題 時限:1000ms 記憶體限制:10000K 總時限:3000ms 描述: 輸出8皇后問題所有結果。 輸入: 沒有輸入。 輸出: 每個結果第一行是No n:的形式,n表示輸出的是第幾個結果;下面8行,每行8個字元,‘A’表示皇后,‘.’

皇后問題

#include <cstdio> #include <iostream> #include <cstdlib> using namespace std; int cnt = 0; int n = 8; int P[10]

求解N皇后問題

#include<stdio.h> #define Debug int count=0; void Queen(int n,int l); bool CanPut(int i,int j,int (*a)[8],int n); void Print(int (*a)[8],int n); int

java利用解決皇后問題

問題簡介: 要求在一個8*8的棋盤上放置8個皇后,使任意兩個皇后都不同行不同列且不在同一條斜對角線上。採用遞迴和回溯的思想解決這一問題是較為直觀的。一開始,棋盤上的任意格子都可落子,因此可任意選擇第一個皇后的位置。放置了第一個皇后之後,棋盤上的可落子格子的分佈將發生改變,然

python基於右解決皇后問題的方法

凡是線性回溯都可以歸結為右遞迴的形式,也即是二叉樹,因此對於只要求一個解的問題,採用右遞迴實現的程式要比回溯法要優美的多。def Test(queen,n): '''這個就不用說了吧,就是檢驗第n(下標,0-7)行皇后的位置是否合理''' q=queen for i in xrange(n): i

[工作準備--演算法] 皇后問題--求解

目標 在8*8的的國際象棋中擺上八個皇后 使其不能相互攻擊 問題分析 問題的解向量:(x0,x2,x3,….,x7) 採用陣列的下標i 表示皇后的所在行 採用陣列元素x[i]表示皇后的所在列向量 約束條件

求解單鏈表中的最大值

1 #include<iostream> 2 using namespace std; 3 4 typedef struct LNode { 5 int data; 6 LNode *next; 7 }Lnode, *LinkList; 8 9 bool

求解走臺階問題,一次可以走一步、兩步、三步、...、n步(經典面試題——增強版走臺階)

1、問題描述       現在有一個臺階,一共有n階,你一次性可以走1步、2步、3步、......、n步。問:一共有多少種走法。 2、求解思路       第一步走1階:那麼這種情況下的走法數量和剩下n-1階的走法數量有關;

Java:利用求解分桔子問題

問題描述:        日本著名數學遊戲專家中村義作教授提出這樣一個問題:父親將2520個桔子分給六個兒子。分完 後父親說:“老大將分給你的桔子的1/8給老二;老二拿到後連同原先的桔子分1/7給老三;老三拿到後連同原先的桔子分1/6給老四;老四拿到後連同

Java 通過求解漢諾塔問題 原始碼 經典問題講解

漢諾塔問題描述:有三根柱子 A、B、C ,在A從下向上按照從大到小的順序放著64個圓盤,以B為中介,把盤子全部移動到C上。移動過程中,要求任意盤子的下面要麼沒有盤子,要麼只能有比它大的盤子。 分析:為了將N個盤子從A移動到C,需要先把第N個盤子上面的N-1個盤子移動到B上,這樣才能將第

【劍指offer】斐波那契數列非求解第N項

public class Solution {    public int Fibonacci(int n) {       //錯誤輸入處理       if

:N皇后問題

1.問題 在國際象棋中,皇后的移動方式為橫豎交叉的,因此在任意一個皇后所在位置的水平、豎直、以及45度斜線上都不能出現皇后的棋子,例子 2.思路 每個皇后必須放在不同行、不同列上、不同斜線上 3.程式碼 #include <iostream> #include

漢諾塔問題求解(python)

漢諾塔問題遞迴求解(python) 漢諾塔(Hanoi)問題 古代有一個梵塔,塔內有三個座x,y,z壇,x座上有64個盤子,盤子大小不等,大的在下,小的在上。有一個和尚想把這64個盤子從x座移到z座,但每次只能允許移動一個盤子,並且在移動過程中,3個座上的盤子始終

整數劃分問題(路徑輸出)【求解方式】

簡述 具體的函式可以參照 這個連結 程式碼 #include <iostream> using namespace std; #include <string> vo

Java解決n皇后問題

題目 八皇后問題是一個以國際象棋為背景的問題:如何能夠在 8×8 的國際象棋棋盤上放置八個皇后,使得任何一個皇后都無法直接吃掉其他的皇后?這道題目也可以稍微延伸一下,變為 N×N的棋盤上放置N個皇后,其他條件相同。 下面介紹一種比較簡單易懂的實現方式。 程式碼 impo

演算法(Java筆記)—推&求解斐波拉契數列

遞推演算法——理性思維模式的代表,其原理是根據已有的資料和關係,逐步推導而得到結果。 演算法的執行過程: 根據已知結果和關係,求解中間結果。 判定是否達到要求,未達到則繼續重複第一步,直到尋找到正

演算法 歸回溯 皇后問題

/* 八皇后問題: 其實就是在全排列的基礎上加了不能在對角線這個條件,第一個程式碼直接用暴力法判斷這個條件,第二個程式碼用回溯法,回溯法減少了很多計算量 */ #include<iostream> #include<cmath> using names

區域性搜尋演算法(求解皇后問題)

區域性搜尋演算法是一種簡單的貪心搜尋演算法,是解決最優化問題的一種啟發式演算法,該演算法每次從當前解的臨近解空間中根據啟發函式選擇一個最優解(也不一定是最優解)作為當前解,直到達到一個區域性最優解。本文以求解八皇后問題來描述爬山法,模擬退火法以及遺傳演算法。 目錄 一、

求解整數的分劃問題

整數劃分問題是演算法中的一個經典命題之一,有關這個問題的講述在講解到遞迴時基本都涉及到。     所謂整數劃分,是指把一個正整數n寫成如下形式:     n=m1+m2+m3+....+mi;