回溯算法(DFS:深度優先)

1. 八皇后問題ios

八皇后問題,是一個古老而著名的問題,是回溯算法的典型案例。該問題是國際西洋棋棋手馬克斯·貝瑟爾於1848年提出:在8×8格的國際象棋上擺放八個皇后,使其不能互相攻擊,即任意兩個皇后都不能處於同一行、同一列或同一斜線上,問有多少種擺法。算法

思路:使用一個數組gEightQueen存儲第i行的皇后擺在第gEightQueen[i]列的位置上數組

步驟一:對於第0行,一共有八個位置能夠選擇,逐一選擇函數

步驟二:對於之後的每一行,一共有八個位置能夠選擇,肯定位置後須要判斷該位置放置元素是否與前面的行衝突,若是衝突,繼續在剩餘的位置中選擇測試。若是不衝突,則繼續向下遞歸,遞歸結束後應當將改行的元素置0。oop

步驟三:當遞歸到第7行,選擇位置不衝突則找到了一種狀況,將總的狀況統計數加1。測試

#include<iostream>
using namespace std;
static int gEightQueen[8] = { 0 }, gCount = 0;
void print()//輸出每一種狀況下棋盤中皇后的擺放狀況
{
    for (int i = 0; i < 8; i++)
    {   
        int inner;
        for (inner = 0; inner < gEightQueen[i]; inner++)
            cout << "0";
            cout <<"#";
        for (inner = gEightQueen[i] + 1; inner < 8; inner++)
            cout << "0";
        cout << endl;
    }
    cout << "==========================\n";
}
int check_pos_valid(int loop, int value)//檢查是否存在有多個皇后在同一行/列/對角線的狀況
{
    int index;
    int data;
    for (index = 0; index < loop; index++)
    {
        data = gEightQueen[index];
        if (value == data)
            return 0;
        if ((index + data) == (loop + value))
            return 0;
        if ((index - data) == (loop - value))
            return 0;
    }
    return 1;
}
void eight_queen(int index)
{
    int loop;
    for (loop = 0; loop < 8; loop++)
    {
        if (check_pos_valid(index, loop))
        {
            gEightQueen[index] = loop;
            if (7 == index)
            {
                gCount++, print();
                gEightQueen[index] = 0;
                return;
            }
            eight_queen(index + 1);
            gEightQueen[index] = 0;
        }
    }
}
int main(int argc, char*argv[])
{
    eight_queen(0);
    cout << "total=" << gCount << endl;
    return 0;
}

 2. 數獨問題spa

解法:只須要求出一個解,solve()返回布爾類型對於判斷是否完成解十分有用3d

步驟一:依此遍歷數獨中全部的元素,若是不存在'.',說明已經得到了解,若是存在'.',說明須要繼續向下求解。code

步驟二:存在'.',依此遍歷字符1-9,判斷是否知足行,列條件,若是知足,將該值賦給'.'所在位置的元素,繼續向下求解,若是有解,返回true,解已經求得,若是沒有解,將'.'所修改的值繼續改到'.',不然在判斷有效性的函數上會出現問題。blog

#include "pch.h"
#include <iostream>
#include <vector>

using namespace std;

bool isValid(vector<vector<char>>& board, int row, int col, char value) {
    // 測試行,列,3 * 3 矩陣有效
    for (int i = 0; i < board.size(); i++) {
        if (board[row][i] == value) {
            return false;
        }
        if (board[i][col] == value) {
            return false;
        }
        if (board[i / 3 + 3 * (row / 3)][i % 3 + 3 * (col / 3)] == value) {
            return false;
        }
    }
    return true;
}

bool solve(vector<vector<char>>& board) {
    for (int i = 0; i < board.size(); i++) {
        for (int j = 0; j < board[0].size(); j++) {
            if (board[i][j] == '.') {
                for (char k = '1'; k <= '9'; k++) {
                    if (isValid(board, i, j, k)) {
                        board[i][j] = k;
                        if (solve(board)) {
                            return true;
                        }
                        board[i][j] = '.';    // 更換一個k值繼續計算
                    }
                }
                return false;
            }
        }
    }
    return true;
}

void solveSudoku(vector<vector<char>>& board) {
    if (board.empty() || board.size() == 0) {
        return;
    }
    solve(board);
}

int main() {
    vector<vector<char>> board = { {'5', '3', '.', '.', '7', '.', '.', '.', '.'},
                                   {'6', '.', '.', '1', '9', '5', '.', '.', '.'},
                                   {'.', '9', '8', '.', '.', '.', '.', '6', '.'},
                                   {'8', '.', '.', '.', '6', '.', '.', '.', '3'},
                                   {'4', '.', '.', '8', '.', '3', '.', '.', '1'},
                                   {'7', '.', '.', '.', '2', '.', '.', '.', '6'},
                                   {'.', '6', '.', '.', '.', '.', '2', '8', '.'},
                                   {'.', '.', '.', '4', '1', '9', '.', '.', '5'},
                                   {'.', '.', '.', '.', '8', '.', '.', '7', '9'} };
    solveSudoku(board);
    
    for (int i = 0; i < board.size(); i++) {
        for (int j = 0; j < board[0].size(); j++) {
            cout << board[i][j] << ' ';
        }
        cout << endl;
    }
}
相關文章
相關標籤/搜索