1. 程式人生 > >藍橋杯 VIP 基礎練習 2n皇后問題

藍橋杯 VIP 基礎練習 2n皇后問題

基礎練習 2n皇后問題   時間限制:1.0s   記憶體限制:512.0MB 問題描述   給定一個n*n的棋盤,棋盤中有一些位置不能放皇后。現在要向棋盤中放入n個黑皇后和n個白皇后,使任意的兩個黑皇后都不在同一行、同一列或同一條對角線上,任意的兩個白皇后都不在同一行、同一列或同一條對角線上。問總共有多少种放法?n小於等於8。 輸入格式   輸入的第一行為一個整數n,表示棋盤的大小。
  接下來n行,每行n個0或1的整數,如果一個整數為1,表示對應的位置可以放皇后,如果一個整數為0,表示對應的位置不可以放皇后。 輸出格式   輸出一個整數,表示總共有多少种放法。 樣例輸入 4
1 1 1 1
1 1 1 1
1 1 1 1
1 1 1 1 樣例輸出 2 樣例輸入 4
1 0 1 1
1 1 1 1
1 1 1 1
1 1 1 1 樣例輸出 0 典型的八皇后問題,這裡採用比較傳統的思路,就是遞迴搜尋,這裡,我以行為界限,因為不同的元素一定在不同的行,所以,我設定一個數組q[i]表示第i個元素(所在行也是i)所在的列為q[i],也就是說第i個元素的座標為(i,q[i]),之所以寫成這種形式,是為了判斷方便,因為這類問題普遍要求不在同一行,不在同一列,不在統一對角線,這就意味著,每次找到一個位置,需要與之前所有的元素的座標進行計算比較,如果是一個滿足條件的位置,就記下這個位置,並繼續搜尋下一個位置,這裡關鍵問題是怎樣判斷一個位置是否合法:

1.因為我們本來就是讓不同的元素在不同的行,所以不存在同行這種情況。

2.如果當前所列舉的是第r個元素,需要判斷(r,i)這個位置是否合法,那麼需要遍歷j從0到r-1,每一個元素的座標為(j,q[j]),如果兩個元素在同一列,那麼i==q[j],如果兩個元素在對角線上,那麼abs(r-j)==abs(i-q[j]),只要這兩個條件不滿足,就說明這個位置是合法的。

以上是完成一次n皇后的搜尋,題目實際上是要求完成兩次,並且兩次搜尋所得到的皇后位置不能重合,所以還要一個visit陣列來記錄訪問情況。

#include <iostream>
#include <cmath>
#include <stdio.h>
#include <string>
#include <cstring>
#include <map>
#include <set>
#include <vector>
#include <stack>
#include <queue>
#include <iomanip>
#include <algorithm>
#include <memory.h>
using namespace std;
const int MAX=10;
int Map[MAX][MAX];
int visit[MAX][MAX];
int q_w[MAX],q_b[MAX];//第i個元素所在的列,行肯定是不同的
int n;
int sum;

void init()
{
    memset(visit,0,sizeof(visit));
    memset(q_w,0,sizeof(q_w));
    memset(q_b,0,sizeof(q_b));
    sum=0;
}


int place(int *q,int r,int c)//判斷位置是否合法
{
    int i;
    int t_r,t_c;
    for(i=0;i<r;i++)
    {
        t_r=i;
        t_c=q[i];
        if(abs(r-t_r)==abs(c-t_c)||(c-t_c==0))//不在同一對角線,不在同一列
            return 0;
    }
    return 1;
}

void dfs_w(int r)//搜尋白皇后
{
    if(r==n)
    {
        sum++;
        return;
    }
    for(int i=0;i<n;i++)
    {
        if(visit[r][i]==0&&Map[r][i]==1&&place(q_w,r,i))
        {
            q_w[r]=i;
            dfs_w(r+1);
        }
    }
}

void dfs_b(int r)//搜尋黑皇后
{
    if(r==n)//找到一個黑皇后的的滿足條件
    {
        dfs_w(0);//搜尋白皇后
        return;
    }
    for(int i=0;i<n;i++)
    {
        if(Map[r][i]==1&&place(q_b,r,i))
        {
            q_b[r]=i;
            visit[r][i]=1;
            dfs_b(r+1);
            visit[r][i]=0;
        }
    }
}

void input()
{
    cin>>n;
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<n;j++)
        {
            cin>>Map[i][j];
        }
    }
}



int main()
{
    init();
    input();
    dfs_b(0);
    cout<<sum<<endl;
    return 0;
}



相關推薦

藍橋 VIP 基礎練習 2n皇后問題

基礎練習 2n皇后問題   時間限制:1.0s   記憶體限制:512.0MB 問題描述   給定一個n*n的棋盤,棋盤中有一些位置不能放皇后。現在要向棋盤中放入n個黑皇后和n個白皇后,使任意的兩個黑皇后都不在同一行、同一列或同一條對角線上,任意的兩個白皇

藍橋基礎練習 2n皇后問題

我們先學習下經典案例中的八皇后問題接著學習2n皇后問題問題描述  給定一個n*n的棋盤,棋盤中有一些位置不能放皇后。現在要向棋盤中放入n個黑皇后和n個白皇后,使任意的兩個黑皇后都不在同一行、同一列或同一條對角線上,任意的兩個白皇后都不在同一行、同一列或同一條對角線上。問總共有

藍橋vip基礎練習 BASIC-28 Huffman樹

問題描述  Huffman樹在編碼中有著廣泛的應用。在這裡,我們只關心Huffman樹的構造過程。  給出一列數{pi}={p0, p1, …, pn-1},用這列數構造Huffman樹的過程如下:  1. 找到{pi}中最小的兩個數,設為pa和pb,將pa和pb從{pi}中

[Java] 藍橋BASIC-27 基礎練習 2n皇后問題

問題描述給定一個n*n的棋盤,棋盤中有一些位置不能放皇后。現在要向棋盤中放入n個黑皇后和n個白皇后,使任意的兩個黑皇后都不在同一行、同一列或同一條對角線上,任意的兩個白皇后都不在同一行、同一列或同一條對

藍橋 基礎練習 2n皇后問題【DFS + 回溯】

時間限制:1.0s 記憶體限制:512.0MB 問題描述   給定一個n*n的棋盤,棋盤中有一些位置不能放皇后。現在要向棋盤中放入n個黑皇后和n個白皇后,使任意的兩個黑皇后都不在同一行、同一列或同一條對角線上,任意的兩個白皇后都不在同一行、同一列或同

藍橋java 基礎練習 Huffuman樹

i++ 整數 ans java 輸入格式 ava sca new 下一個 問題描述   Huffman樹在編碼中有著廣泛的應用。在這裏,我們只關心Huffman樹的構造過程。  給出一列數{pi}={p0, p1, …, pn-1},用這列數構造Huffman樹的過程如下:

藍橋java 基礎練習 龜兔賽跑預測

空格 time 所有 tint 請求 一行 void scan clas 問題描述   話說這個世界上有各種各樣的兔子和烏龜,但是研究發現,所有的兔子和烏龜都有一個共同的特點——喜歡賽跑。於是世界上各個角落都不斷在發生著烏龜和兔子的比賽,小華對此很感興趣,於是決定研究不同兔

藍橋基礎練習 十六進位制轉八進位制

問題描述   給定n個十六進位制正整數,輸出它們對應的八進位制數。 輸入格式   輸入的第一行為一個正整數n (1<=n<=10)。   接下來n行,每行一個由0~9、大寫字母A~F組成的字串,表示要轉換的十六進位制正整數,每個十六進位制數長度不超過100000。 輸出格式   輸出n行,每行

藍橋基礎練習 查詢整數

  http://lx.lanqiao.cn/problem.page?gpid=T9 題目描述   基礎練習 查詢整數   時間限制:1.0s   記憶體限制:256.0MB      

藍橋基礎練習 矩形面積交

問題描述   平面上有兩個矩形,它們的邊平行於直角座標系的X軸或Y軸。對於每個矩形,我們給出它的一對相對頂點的座標,請你程式設計算出兩個矩形的交的面積。 輸入格式   輸入僅包含兩行,每行描述一個矩形。   在每行中,給出矩形的一對相對頂點的座標,每個點的座標都用兩個絕對值

藍橋基礎練習】十六進位制轉十進位制、八進位制

十六進位制轉十進位制 問題描述   從鍵盤輸入一個不超過8位的正的十六進位制數字符串,將它轉換為正的十進位制數後輸出。   注:十六進位制數中的10~15分別用大寫的英文字母A、B、C、D、E、F表示。 樣例輸入 FFFF 樣例輸出 65535 方法一:巧用C語言的輸入輸

藍橋基礎練習 十六進位制轉十進位制

問題描述   從鍵盤輸入一個不超過8位的正的十六進位制數字符串,將它轉換為正的十進位制數後輸出。   注:十六進位制數中的10~15分別用大寫的英文字母A、B、C、D、E、F表示。 樣例輸入 FF

藍橋基礎練習 數列排序

  問題描述:   給定一個長度為n的數列,將這個數列按從小到大的順序排列。1<=n<=200 輸入格式:   第一行為一個整數n。   第二行包含n個整數,為待排序的數,每個整數的絕對值小於10000。 輸出格式:   輸出一行,按從小到大的順序輸出排

基礎練習 2n皇后問題 (兩次DFS)

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

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

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

藍橋Java基礎練習

最近有在看一些小演算法,於是看到了藍橋杯,覺得藍橋杯的測試系統還是蠻有意思的,就把裡面的題目做了一遍,在此做下筆記1.Fibonacci數列問題描述Fibonacci數列的遞推公式為:Fn=Fn-1+Fn-2,其中F1=F2=1。當n比較大時,Fn也非常大,現在我們想知道,Fn除以10007的餘數是多少。輸入

藍橋基礎練習 楊輝三角形【JAVA演算法實現】

題目描述 楊輝三角形又稱Pascal三角形,它的第i+1行是(a+b)i的展開式的係數。 它的一個重要性質是:三角形中的每個數字等於它兩肩上的數字相加。 下面給出了楊輝三角形的前4行: 1 1 1 1 2 1 1 3 3 1 給出n,輸出它的前n行。 輸

藍橋基礎練習 特殊迴文數

基礎練習 特殊迴文數   時間限制:1.0s   記憶體限制:512.0MB 問題描述   123321是一個非常特殊的數,它從左邊讀和從右邊讀是一樣的。   輸入一個正整數n, 程

藍橋基礎練習 01字串【JAVA演算法實現】

題目描述 對於長度為5位的一個01串,每一位都可能是0或1,一共有32種可能。它們的前幾個是: 00000 00001 00010 00011 00100 請按從小到大的順序輸出這32種01串。 輸入格式 本試題沒有輸入。 輸出格式 輸出32行,按從

藍橋基礎練習】 特殊迴文數

問題一:迴文數 問題描述   1221是一個非常特殊的數,它從左邊讀和從右邊讀是一樣的,程式設計求所有這樣的四位十進位制數。 輸出格式   按從小到大的順序輸出滿足條件的四位十進位制數。 思路:分別求出這個四位數的每一個位上的數,然後做比較 #include&l