回溯算法
来源:互联网 发布:粉红色的火烈鸟知乎 编辑:程序博客网 时间:2024/06/05 23:48
使用回溯算法解决N皇后问题.
1. 问题描述:
棋盘为N*N的,在该棋盘上放置N个皇后,使得任意两个皇后不在同一行或者同一列或者同一对角线(主对角线和副对角线)。
2. 解题思路:
分析得:必定使得棋盘的每一行每一列均存在且只存在一个皇后,所以遍历所有的行,对每一行,遍历所有的列,使用判断条件排除。
3. 原始程序:
#include<iostream>
using namespace std;
int n,ans;// n是棋盘边的格子数;ans是解决方案的个数
int c[100];//存取每一行的列数
void recall(int cur);//回溯函数
int main()
{
while(cin>>n)
{
ans=0;//每一组必须清空
recall(0);/下标从0开始
cout<<ans<<endl;
}
return 0;
}
void recall(int cur)
{
if(cur==n)//递归边界:只要走到这里,所有皇后必定不冲突,即得解决方案
{
ans++;
}
else
{
for(int i=0;i<n;i++)
{
int ok=1;
c[cur]=i;//尝试将第cur行的皇后放在第I列
for(int j=0;j<cur;j++)//检查该皇后是否与以前放的皇后冲突
{
if(c[cur]==c[j]||cur+c[cur]==j+c[j]||cur-c[cur]==j-c[j])
/*
因为逐行放置,所以所在的行必定不会冲突;c[cur]==c[j]是列冲突;cur+c[cur]==j+c[j]是副对角线冲突;cur-c[cur]==j-c[j]是主对角线冲突
*/
{
ok=0;
break;
}
}
if(ok)
{
recall(cur+1);
}
}
}
}
运行结果:
1
1
2
0
3
0
4
2
5
10
6
4
7
40
8
92
9
352
10
724
4. 优化程序(速度更快)
思路:直接用vis[][]这个二维数组来判断当前尝试放的位置所在的列(vis[0][i])、主对角线(vis[1][cur+i])、副对角线(vis[2][cur-i+n])是否已经放了皇后(放了为1,没放为0)。如果没放,那么放上(c[100]用来存储路径,如果不需要打印路径,则不需要该数组);如果放了尝试下一个位置。注意:recall(cur+1)语句执行完以后,表明对于当前的位置已经是求得了结果,所以向上一层程序返回的时候,一定将状态改回:“没被访问”。一般的:如果在回溯法中修改了辅助的全局变量,则一定要及时将他们恢复原状。若函数有多个出口,则需要在每个出口的地方恢复被修改的值。
#include<iostream>
#include<cstring>
using namespace std;
int vis[100][100];
int n,ans;
int c[100];
void recall(int cur);
int main()
{
while(cin>>n)
{
memset(vis,0,sizeof(vis));
ans=0;
recall(0);
cout<<ans<<endl;
}
return 0;
}
void recall(int cur)
{
if(cur==n)
{
ans++;
}
else
{
for(int i=0; i<n; i++)
{
if(!vis[0][i]&&!vis[1][cur+i]&&!vis[2][cur-i+n])
{
c[cur]=i;
vis[0][i]=vis[1][cur+i]=vis[2][cur-i+n]=1;
recall(cur+1);
vis[0][i]=vis[1][cur+i]=vis[2][cur-i+n]=0;
}
}
}
}
运行结果:
1
1
2
0
3
0
4
2
5
10
6
4
7
40
8
92
9
352
10
724
- 回溯算法
- 回溯算法
- 回溯算法
- 回溯算法
- 回溯算法
- 回溯算法
- 回溯算法
- 回溯算法
- 回溯算法
- 回溯算法
- 回溯算法
- 回溯算法
- 回溯算法
- 回溯算法
- 回溯算法
- 回溯算法
- 回溯算法
- 回溯算法
- 缓慢地成长的步伐
- LUA脚本语言
- POJ 计算几何入门题目推荐
- E430C基本完美安装OS X Yosemite 10.10 MAS 14A389
- 文件夹复制,通过配置文件来更改条件
- 回溯算法
- A and B and Interesting Substrings(学习利用map容器提高效率的技巧)
- java中的IO整理
- 快速幂
- 玩转AWK
- TextView实现圆角效果.
- 模运算
- UILabel加删除线
- UVA - 11584 Partitioning by Palindromes DP