1. 程式人生 > >hdu2553 N皇后問題(回溯dfs)

hdu2553 N皇后問題(回溯dfs)

剛開始怎麼也想不通怎麼斜向判斷,看了詳解,服了。。戳這裡N皇后詳解

準確的說他是用了滾動陣列,分別用三行記錄正對角線,縱向,反對角線方向所放置過皇后所能影響的狀態記錄。若在攻擊範圍內,則標記1。而且越想越覺得精妙,陣列是動態的,dfs遍歷每行,for遍歷每列,每個狀態的判斷都在前一個判斷的基礎上,而且加之回溯節省時間,再加上打表的小技巧,這樣的程式真的難得一見哪。。。

ps:開學感覺浪費好多時間,如果這些能利用起來就好了哭

#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <queue>
#include <iostream>

using namespace std;

const int N = 30;
const int INF = 1000000;

int vis[3][N], ans[N];
int n, sum;

void dfs(int row)
{
    int i;
    if(row == n + 1)
    {
        sum ++;
        return;
    }
    for(i = 1; i <= n; i ++)
    {
        if(vis[0][row - i + n] == 0 && vis[1][i] == 0 && vis[2][i + row] == 0)
        {
            vis[0][row - i + n] = vis[1][i] = vis[2][i + row] = 1;
            dfs(row + 1);
            vis[0][row - i + n] = vis[1][i] = vis[2][i + row] = 0;//回溯
        }
    }
}

int main()
{
  //  freopen("in.txt", "r", stdin);
    for(n = 1; n <= 10; n ++) //注意這裡是n而不能為i因為n必須同步
    {
        memset(vis, 0, sizeof(vis));
        sum = 0;
        dfs(1);
        ans[n] = sum;
    }
    while(~scanf("%d", &n) && n)
        printf("%d\n", ans[n]);
    return 0;
}