洛谷-----P1219 八皇后

一、題目描述

        題目連接:https://www.luogu.org/problem/P1219ios

二、分析

        n後問題有四個限制條件,首先是行,這一行不能再有其餘皇后,因爲咱們是使用行來作遞歸,在放置第i個皇后時,必然行的條件是知足的,那麼就須要考慮列和對角線的條件,首先在遞歸程序裏須要遍歷全部的列,要在這些列裏找到沒有被標記過的點,若是找到,那麼這個點就是當前第i個皇后所在的列,能夠將其記錄,以後,咱們須要對這個皇后所在的列和對角線進行標記,對列的標記很簡單,使用一個數組A[i]=j,表示第i個皇后佔有了在第j列。這個j就是遞歸函數裏的遍歷的條件。至於對角線的標記,假設兩個皇后的位置分別是(x1,y1)(x2,y2),那麼怎麼證實他們在一條斜線上,其實很簡單,分兩種狀況,從左上角到右下角,這條線上的點座標的(x1,y1)和(x2,y2), 且 x1-y1 = x2- y2 或 x1+y1 = x2+y2,則說明這2個皇后處於同一斜線上。這裏能夠用i+j表示表示一個佔用過的斜線,用i-j表示一個佔用的斜線,i-j有可能小於0,能夠爲其加上N來讓其不至於小於0,以下程序,輸入N小於等於13,那麼i+j小於等於26,因此能夠用一個數組來表示。因此一共須要三個數組來表示佔用過的列,和兩個對角線。須要注意的是遞歸完了以後須要回溯。數組

三、代碼

#include<stdio.h>
#include<iostream>
using namespace std;
int res[14];//存儲每一行放置的位置
int check_res[3][28];//判斷列和對角線
int N;
int answer=0;
void dfs(int step){
    if (step > N){
        answer++;
        if (answer > 3){
            return;
        }
        else{
            for (int i = 1; i <= N; ++i){
                cout << res[i] << " ";
            }
            cout << endl;
            return;
        }
    }
    for (int j = 1; j <= N; j++){
        if (!check_res[0][j] && !check_res[1][step + j] && !check_res[2][step - j + N]){
            res[step] = j;
            check_res[0][j] = 1;
            check_res[1][step + j] = 1;
            check_res[2][step - j + N] = 1;
            dfs(step + 1);
            check_res[0][j] = 0;
            check_res[1][step + j] = 0;
            check_res[2][step - j + N] = 0;
        }
    }
}

int main(){
    cin >> N;
    dfs(1);
    cout << answer;
    return 0;
}

四、相關知識點

        遞歸和回溯。函數

相關文章
相關標籤/搜索