1. 程式人生 > >8皇后-----回溯法C++程式設計練習

8皇后-----回溯法C++程式設計練習

/*
 * 八皇后問題回溯法程式設計練習
 * 在8×8的棋盤上,放置8個皇后,兩個皇后之間不能兩兩攻擊
 * 也即,直線,垂直45度、135度方向不能出現兩個皇后
 *
 * copyright Michael 2014-12-19
 * QQ 1192065414
 **/

#include <iostream>
#include <stack>
#include <stdlib.h>
#include <string.h>
using namespace std;

struct Sposition
{
    int iRow;
    int iColumn;
};

/*
 * 儲存結果使用的棧
 **/
stack<Sposition> ResultStack;


/*
 * 判斷在水平方向x,垂直方向y,是否可以放置新皇后
 **/
bool JudgeIsAcceptable(int x ,int y)
{
    struct Sposition pos;

    stack<Sposition> resultS(ResultStack);
    int stackSize = resultS.size();
    for ( ; stackSize > 0 ; --stackSize )
    {
        pos = resultS.top();
        if( pos.iRow == x )  //判斷同一直線上是否已經有皇后
        {
            return false;
        }

        if( (x-pos.iRow) == (y-pos.iColumn) )  //判斷45度角是否已經有皇后
        {
            return false;
        }

        if( (x-pos.iRow) == (pos.iColumn-y) ) //判斷-45度角是否已經有皇后
        {
            return false;
        }

        resultS.pop();
    }

    return true;
}


/*
 * 皇后放置演算法
 * 0 0 0...
 * 0 0 0...
 * 0 0 0...
 * ......
 * 遍歷第0列,取第0列的第一個、第二個...
 * 從第1列開始嘗試,然後嘗試第2列,當嘗試到一列,8行都不能放置皇后,則回溯,返回前一列的下一行繼續嘗試
 **/
void SolveQueue()
{
    Sposition pos;
    for (int i = 0 ; i < 8 ; ++i )
    {
        //The first line of the queue
        pos.iRow = i;
        pos.iColumn = 0;
        ResultStack.push(pos);

        int x = 0; //標記當前行,0~7行
        int y = 1; //標記當前列,0~7列
        while( y<8 )  //從第一列開始
        {
            for ( ; x < 8 ; ++x )  //從第0行開始探索
            {
                if ( JudgeIsAcceptable(x,y) )
                {
                    pos.iRow = x;
                    pos.iColumn = y;
                    ResultStack.push(pos);

                    //放置完成,輸出結果
                    if ( 8 == ResultStack.size() )
                    {
                        while ( !ResultStack.empty() )
                        {
                            pos = ResultStack.top();
                            cout<<pos.iRow<<"\t"<<pos.iColumn<<endl;
                            ResultStack.pop();
                        }
                    }
                    x = 0;   //這一列放置完成,繼續下一列放置
                    break;
                }
            }

            if ( 8 == x )  //這一列,8行都不能放置皇后,回溯到上一列的下一行
            {
                pos = ResultStack.top();
                x  = pos.iRow+1;
                if ( 8 <= x )
                {
                    y = y-2;  //如果上一列放置的地方已經是最後一列,則無需繼續嘗試,應該回溯兩列,從前兩列繼續嘗試
                    ResultStack.pop();
                    pos = ResultStack.top();
                    x = pos.iRow+1;
                }
                else
                {
                    --y;  //回溯到前一列的下一行繼續嘗試
                }
                ResultStack.pop();
                continue;   //控制列數,不進行 ++y 操作
            }

            ++y;;
        }

        if ( (8 == y) && (ResultStack.size() != 8) )   //如果8行已經嘗試完,但是放置不夠8行,出錯狀態,處理下一種可能性
        {
            while ( !ResultStack.empty() )
            {
                ResultStack.pop();
            }
        }

        cout<<endl;
        cout<<endl;
    }
}

int main()
{
    SolveQueue();
}

相關推薦

8皇后-----回溯C++程式設計練習

/* * 八皇后問題回溯法程式設計練習 * 在8×8的棋盤上,放置8個皇后,兩個皇后之間不能兩兩攻擊 * 也即,直線,垂直45度、135度方向不能出現兩個皇后 * * copyright Michael 2014-12-19 * QQ 1192065414 *

迷宮問題-----深度優先回溯演算法C++程式設計練習

沒有對程式進行優化,使用最原始的想法進行程式設計。/* 迷宮問題的深度優先回溯法---C++程式設計練習 Author : Michael Date : 2014-12-31 E-mail : [email protected] **/ #include <

C++程式設計練習——巴比倫演算法求平方根

#include<iostream> using namespace std; int main() { double n, r, last_guess, new_guess; cout << "Which number you w

C++程式設計練習——一個簡單的石頭剪刀布遊戲

#include<iostream> using namespace std; int main() { char player1, player2; int start; cout << "這是一個石頭剪刀布的遊戲,如果你想開

C++程式設計練習——計算利息

#include<iostream> using namespace std; int main() { double intrest, total, min; int start, loan; cout << "如果你想要開始計

C#程式設計練習(03):北斗時間系統、GPS時間系統及其與UTC時間系統之間的轉換

需求說明:北斗周-周內秒轉化為日曆時,轉化為UTC時,轉化為GPS週週內秒 GPS周-周內秒轉化為日曆時,轉化為UTC時,轉化為北斗周-周內秒 設計示意圖: 原始碼: using System; using System.Collections.Generic; using S

C#程式設計練習(02):大地座標系(LBH)向空間直角座標系(XYZ)的轉換及其逆轉換

需求說明:以WGS-84軟體為例,實現大地座標系(LBH)向空間直角座標系(XYZ)的轉換及其逆轉換 原理說明: 程式原始碼: using System; using System.Collections.Generic; using System.Linq; using S

c++程式設計練習之刪除序列中相同的數

  #include<iostream> using namespace std; class arr { int m; int a[100]; public: arr(int x[],int size) { m=size; for(int i=0

Linux C程式設計練習(一)

1、定製自己的ls命令 #include <stdio.h> #include <sys/types.h> #include <dirent.h> #include <stdlib.h> #include &

USACO1.5.4 Checker Challenge跳棋的挑戰 解題報告(N皇后 回溯)

Description 檢查一個如下的6 x 6的跳棋棋盤,有六個棋子被放置在棋盤上,使得每行,每列,每條對角線(包括兩條主對角線的所有對角線)上都至多有一個棋子。 列號 0 1 2 3 4 5 6 ----------------------

C++程式設計練習】任意給定 n 個有序整數,求這 n 個有序整數序列的最大值,中位數和最小值

題目來源 CCF模擬試題>>小中大>>201903-1 題目描述 老師給了你n個整陣列成的測量資

回溯(八皇后問題)及C語言實現

       回溯法,又被稱為“試探法”。解決問題時,每進行一步,都是抱著試試看的態度,如果發現當前選擇並不是最好的,或者這麼走下去肯定達不到目標,立刻做回退操作重新選擇。這種走不通就回退再走的方法就是回溯法。 回溯VS遞迴 很多人認為回溯和遞迴是一樣的,其實不然。在回溯

C Primer Plus 第6版 第8程式設計練習

-- 這章的練習要使用重定向,如果不能使用,可以用特殊字元代替EOF 1.統計讀到檔案結尾之前讀取的字元數。 #include<stdio.h> int main(void) { char ch; int char_num = 0; while ((ch

回溯解決八皇后c++)

八皇后問題是一個以國際象棋為背景的問題:如何能夠在 8×8 的國際象棋棋盤上放置八個皇后,使得任何一個皇后都無法直接吃掉其他的皇后?為了達到此目的,任兩個皇后都不能處於同一條橫行、縱行或斜線上。八皇后問題可以推廣為更一般的n皇后擺放問題:這時棋盤的大小變為n1×n1,而皇后個數也變成n2。而且僅當

回溯解決八皇后問題的思路,並求出17皇后解的數量(c#,c++,python表示)

1.解決思路借用網上一張圖,中間那個紅點表示的就是皇后,這圖的意思也就是一個皇后的影響範圍為這這個皇后所在的那一列,那一行,對角線以及次對角線。其它的皇后不能在它的影響範圍裡否則會衝突。八皇后也就是在一個8x8的棋盤上後置8個皇后,皇后的數量與棋盤的行列數一樣。這是基礎,再來

回溯解決2n皇后8皇后)問題

8皇后問題是演算法入門的經典,在8*8的國際象棋上擺放八個皇后,使其不能相互攻擊,即任意兩個皇后都不能處於同一 今天要說的2n皇后問題與傳統的8皇后問題有些不同,在一個n*n的棋盤中,有些位置不允許放皇后,現在要向棋盤中 放入n個黑皇后和n個白皇后,使任意的兩個黑白皇后

基礎練習 2n皇后問題 ——回溯,貪心演算法

/*基礎練習 2n皇后問題問題描述  給定一個n*n的棋盤,棋盤中有一些位置不能放皇后。現在要向棋盤中放入n個黑皇后和n個白皇后,使任意的兩個黑皇后都不在同一行、同一列或同一條對角線上,任意的兩個白皇后都不在同一行、同一列或同一條對角線上。問總共有多少种放法?n小於等於8。輸

C語言回溯遞迴求解八皇后問題

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

回溯解決8皇后問題

#include <iostream> #define N 8 using namespace std; int position[N][N]; void Initial_position() { for(int i = 0;i < N;i++) {

經典演算法(1)——8皇后問題求解(回溯

問題描述: 八皇后問題是大數學家高斯於1850年提出來的。該問題是在8×8的國際象棋棋盤上放置8個皇后,使得沒有一個皇后能“吃掉”任何其他一個皇后,即沒有任何兩個皇后被放置在棋盤的同一行、同一列或同一斜線上。 要求: 編一個程式求出該問題的所有解。 演算法思想: