一、N皇后问题
在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上。
你的任务是,对于给定的N,求出有多少种合法的放置方法。
input
共有若干行,每行一个正整数N≤10,表示棋盘和皇后的数量;如果N=0,表示结束。
Output
共有若干行,每行一个正整数,表示对应输入行的皇后的不同放置数量
Sample
Inputcopy | Outputcopy |
|
|
思路:
可以先从第一行开始,然后逐渐dfs下一行
放置皇后需要满足:不允许在同一排或者同一列或者主副对角线上
用打表来存储答案,防止超时问题
ps:row:行 ,db[N]打表存储不同的n放置的皇后的个数
主副对角线规律
主对角线:row+i(类似:y=-x+b,可得:b=y+x)
副对角线:row-i+n;(类似:y=x+b,可得:b=y-x+n)
ps:加n是因为数组中没有负数
代码1:
#include<bits/stdc++.h>
using namespace std;
const int N=200;
int a[N],db[N];
int n,cnt=0;
//int nex[4][2]={{0,-1},{0,1},{-1,0},{1,0}};
bool check(int x,int y)
{
for(int i=1;i<=x;i++)
{
if(a[i]==y) return false;
if(i+a[i]==x+y) return false;
if(i-a[i]==x-y) return false;
}
return true;
}
void dfs(int row)
{
if(row==n+1)
{
cnt++;
return ;
}
for(int i=1;i<=n;i++)
{
if(check(row,i))
{
a[row]=i;
dfs(row+1);
a[row]=0;
}
}
}
int main()
{
for(n=1;n<=10;n++)
{
cnt=0;
dfs(1);
db[n]=cnt;
}
while(~scanf("%d",&n)&&(n!=0))
{
printf("%d\n",db[n]);
}
return 0;
}
二、搜索
题目描述
DFS全称是Depth First Search,中文名是深度优先搜索,是一种用于遍历或搜索树或图的算法。所谓深度优先,就是说每次都尝试向更深的节点走。 常常用来指代用递归函数实现的搜索,最显著的特征在于其递归调用自身。DFS 会对其访问过的点打上访问标记,在遍历图时跳过已打过标记的点, 以确保每个点仅访问一次。符合以上两条规则的函数,便是广义上的 DFS。
对于一个6×6的棋盘,有六个棋子被放置在棋盘上,要求任意两个棋子都不能处于同一行、同一列或同一斜线上。 第i个数字表示在第 i 行的相应位置有一个棋子,如下: 行号 1 2 3 4 5 6 列号 2 4 6 1 3 5 这只是棋子放置的一个解。请编一个程序找出所有棋子放置的解。 并把它们以上面的序列方法输出,解按字典顺序从小到大排列。(字典序是基于字母顺序排列的单词按字母顺序排列的方法。例如对于5个数字的排列 12354和12345,排列12345在前,排列12354在后。) 请输出前3个解。最后一行是解的总个数。
输入描述
一行一个正整数n,表示棋盘是 n×n 大小的。
输出描述
前三行为前三个解,每个解的两个数字之间用一个空格隔开。第四行只有一个数字,表示解的总数。
样例输入
6
样例输出
2 4 6 1 3 5
3 6 2 5 1 4
4 1 5 2 6 3
4
数据范围
6≤n≤13
代码:
#include<bits/stdc++.h>
using namespace std;
const int N=200;
int a[N],x[N],y[N],zhu[N],fu[N];
int n,cnt=0;
void print()
{
if(cnt<=3)
{
for(int i=1;i<=n;i++)
printf("%d ",a[i]);
printf("\n");
}
}
void dfs(int row)
{
if(row>n)
{
cnt++;
print();
return ;
}
for(int i=1;i<=n;i++)
{
if(!x[row]&&!y[i]&&!zhu[row+i]&&!fu[row-i+n])
{
a[row]=i;
x[row]=i;
y[i]=zhu[row+i]=fu[row-i+n]=1;
dfs(row+1);
x[row]=0;
y[i]=zhu[row+i]=fu[row-i+n]=0;
}
}
}
int main()
{
cnt=0;
scanf("%d",&n);
dfs(1);
printf("%d\n",cnt);
return 0;
}