问题描述
问题描述
在一个n*n的棋盘中,每个格子中至多放置一个车,且要保证任何两个车都不能相互攻击,有多少中放法(车与车之间是没有差别的)
输入格式
包含一个正整数n
输出格式
一个整数,表示放置车的方法数
样例输入
2
样例输出
7
数据规模和约定
n<=8
【样例解释】一个车都不放为1种,放置一个车有4种,放置2个车有2种。
解题思路
根据题干的要求,每一辆车放置的位置所在行与列都不能有其它车,因此可以指定一套摆放规则,使车的摆放方式满足要求:
1.新车需要摆放在前一辆车的下一行以下(因为辆车交换摆放位置不会增加摆法的总数);
(假设有num辆车没摆放(包括当前这辆车),一共有n行,)每一辆车所能摆放的行数范围,从其起始行row,到终止行n+num-1;
算法思路
考虑使用深度优先搜索,依次将num辆车摆放在n*n棋盘中,需要先确定摆放的行标,再扫描该行的所有列,找到一个没有其他车的列,将该车摆放在该列上并做好标记,紧接摆放下一辆车。当该车取消摆放时,务必取消标记。
代码实现
#include<iostream>
using namespace std;
//注意:行标从1开始
//判断该列是否有车
bool is_parked[9]={0};
//输入的行数n
int n;
//计算摆法的总数
int sum;
//num表示当前待摆放的车辆个数,row表示其摆放的起始行标
void DFS(int num,int row)
{
//当无车时,说明已经摆放全部车辆,sum++
if(num==0)
{
sum++;
return ;
}
else
{
//从row行开始摆放,n-num+1是其摆放范围
int i,j;
for(i=row;i<=n-num+1;i++)
{
//依次尝试摆放在1~n列
for(j=1;j<=n;j++)
{
if(!is_parked[j])
{
is_parked[j]=true;
//摆放下一辆车,注意从i+1行开始
DFS(num-1,i+1);
//若后面一辆车摆放失败,则调整当前车的摆放位置,需要取消标记
is_parked[j]=false;
}
}
}
}
}
int main()
{
//依次讨论0~n辆车子在n*n棋盘上的摆放方法
cin>>n;
int i;
for(i=0;i<=n;i++)
{
DFS(i,1);
}
cout<<sum<<endl;
return 0;
}
多多关注+点赞+收藏,持续更新中!😘😘
![](https://img-blog.csdnimg.cn/img_convert/133790685e038238aa11781ed4c59606.gif)