题意:在一张形状不规则的棋盘上(用#表示棋盘位置,. 表示非棋盘位置),要放置N个 棋子,且不同行不同列。问有几种放法?
做法:首先做出正方形规则棋盘放个数为边长的棋子的算法,
再加上坐标为“#”才能放的限制,
最后在函数中增加一个没有回溯法的递归用于当棋子数量小于边长时。
代码:
#include <iostream>
#include <cstring>
using namespace std;
const int MaxN = 500;
int n,m,k, tot,num;
bool vis[2][MaxN];
char dot[MaxN][MaxN];
void dfs(int cur)
{
int i, j;
if (k==m)
tot++;
else if(cur<n)
{
if(num<n-m)
{num++;dfs(cur + 1);num--;}
for (i = 0; i < n; i++)
{
if (!vis[0][i]&&dot[cur][i]=='#')
{
vis[0][i] = 1;k++;//该列已用
dfs(cur + 1); //进入下一行
vis[0][i] = 0;k--;//可用该列
}
}
}
}
int main()
{
int i,j;
while(cin>>n>>m)
{
if(n==-1&&m==-1)
break;
if(n==0)
{cout<<0<<endl;continue;}
int k=0;
num=0;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
cin>>dot[i][j];
tot = 0;
memset(vis, 0, sizeof(vis));
dfs(0);
cout << tot << endl;
}
return 0;
}
错误原因:1.无回溯法的递归前面有限制限制条件。
2.回溯中需要增加一个变量用来计算已放棋子数量,不可以再用行数代替!