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,求出有多少种合法的放置方法。
你的任务是,对于给定的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; }
//打表,表中数据来自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; }