hduoj2553——N皇后问题,dfs回溯

hduoj 2553  dfs,回溯

N皇后问题

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 10297    Accepted Submission(s): 4634

Problem Description
在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上。
你的任务是,对于给定的N,求出有多少种合法的放置方法。

Input
共有若干行,每行一个正整数N≤10,表示棋盘和皇后的数量;如果N=0,表示结束。
 
Output
共有若干行,每行一个正整数,表示对应输入行的皇后的不同放置数量。
 
Sample Input
1 8 5 0
 
Sample Output
1 92 10
 
经典题,题目卡了回溯,打表过了。。关键是要以行为单位进行深搜,把vis数组设成int型,vis为0表示可行域,vis=m>0表示在m个棋子的攻击范围内,放置棋子或移除棋子是时用增量或减量改变可行域
//题目卡了dfs,所以TLE了。。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>

using namespace std;

int map[10][10],cnt,n;

void puts(int x,int y)
{
    for(int i=0;i<n;i++){
        map[i][y]++;
        map[x][i]++;
        if(x+y-i<n&&x+y-i>=0) map[i][x+y-i]++;
        if(y-x+i<n&&y-x+i>=0) map[i][y-x+i]++;
    }
}

void remove(int x,int y)
{
    for(int i=0;i<n;i++){
        map[i][y]--;
        map[x][i]--;
        if(x+y-i<n&&x+y-i>=0) map[i][x+y-i]--;
        if(y-x+i<n&&y-x+i>=0) map[i][y-x+i]--;
    }
}

void search(int cur)
{
    if(cur==n) cnt++;
    else{
        for(int i=0;i<n;i++){
            if(map[i][cur]) continue;
            puts(i,cur);
            search(cur+1);
            remove(i,cur);
        }
    }
}

int main()
{
    while(cin>>n,n){
        cnt=0;
        memset(map,0,sizeof(map));
        search(0);
        cout<<cnt<<endl;
    }
    return 0;
}
N皇后问题_dfs
//打表,表中数据来自dfs
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>

using namespace std;

const int maxn=30;
const int INF=(1<<28);

int a[]={1,0,0,2,10,4,40,92,352,724};

int main()
{
    int n;
    while(cin>>n,n){
        cout<<a[n-1]<<endl;
    }
    return 0;
}
打表

 

posted @ 2015-03-12 23:25  __560  阅读(329)  评论(0编辑  收藏  举报