N皇后问题
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 10703 Accepted Submission(s): 4797
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
--------------------------------------------------------------------------------------------------------------------------------
2015-11-14
vis[x] = y 表示第x行第y列已经有棋子了,
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string.h>
using namespace std;
int g[15][15],vis[15],sum[15];
int n,ans;
void dfs(int x,int cnt)
{
if(cnt == n)
{
ans ++;
return ;
}
for(int i = x; i < n; i++)
{
if(vis[i] == -1) //如果这一行没有棋子就按列搜索
{
for(int j = 0; j < n; j++)
{
int flag = 1;
for(int k = 0; k < x; k++) //判断每一列是否满足条件:枚举上面的每一行k,看看k行的这一列有没有元素,同时还有判断这两个位置是否斜成一行,已经放完的棋子(k,vis[k])和要放的(i,j)
{
if(vis[k] == j || abs(j - vis[k]) == abs(i - k))
{
flag = 0;
break;
}
}
if(flag)
{
vis[i] = j;
dfs(i + 1,cnt + 1);
vis[i] = -1;
}
}
}
}
}
int main()
{
for(int i = 1; i <= 10; i++)
{
ans = 0;
memset(vis,-1,sizeof(vis));
n = i;
dfs(0,0);
sum[i] = ans;
}
while(scanf("%d", &n) != EOF && n != 0)
{
printf("%d\n",sum[n]);
}
}
------------------------------------------------------------------------------------------------------------------------------
#include<iostream>
using namespace std;
int map[11];
bool place(int row,int col,int k)
{
for(int i=1;i<k;i++)
{
if(col==map[i]||abs(row-i)==abs(col-map[i]))
return false;
}
return true;
}
int main()
{
int n;
while(cin>>n)
{
if(n==0)
return 0;
memset(map,0,sizeof(map));
map[1]=1;
int k=1,count=0;
while(k>0)
{
if(k<=n && map[k]<=n)
{
if(place(k,map[k],k))
{
k++;
map[k]=1;
}
else
{
map[k]++;
}
}
else
{
if(k>n)
count++;
k--;
map[k]++;
}
}
cout<<count<<endl;
}
return 0;
}
上面是超时的,每次输入都要重新计算。可以把1到10都计算出来放在一个数组然后每次输入直接查表
还一个知识点,整数绝对值abs(),浮点数用fabs()
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
int map[11];
int num[11];
int place(int k,int ma)
{
for(int i=1;i<k;i++)
if(ma==map[i]||abs(k-i)==abs(ma-map[i]))
return 0;
return 1;
}
int main()
{
int n;
for(int i=1;i<11;i++)
{
memset(map,0,sizeof(map));
int k=1, countn=0;
map[k]=1;
while(k>0)
{
if(k<=i&&map[k]<=i)
{
if(place(k,map[k]))
{
k++;
map[k]=1;
}
else
map[k]++;
}
else
{
if(k>i)
countn++;
k--;
map[k]++;
}
}
num[i]=countn;
}
while(scanf("%d",&n)!=EOF&&n)
{
cout<<num[n]<<endl;
}
return 0;
}