POJ - 1321 棋盘问题
思路:
- 如果是自己用笔做的话,应该就是按照行(列也可以)来进行放棋子。
- 然后标记哪一列已经放了棋子了
- 注意的一点是不要重复
- 比如:我从第五行找第一个棋子的位置,之后的寻找过程就不要在第一行开始了,应该在开始的下一行开始,也就是在第六行开始寻找下一个棋子的位置。这一点非常重要,因为如果继续从第一行开始找的话,就有可能重复.。
- 传统的深搜不能解决该问题,如一点为起点,然后向上下左右相邻的位置进行查找。为什么不行呢?因为可以放棋子的位置不一定连续。我开始就是用的这种,发现不行。
- 下面为代码实现,c++版本(其实和c差不多φ(* ̄0 ̄))
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=8;
int mapp[N][N];
int book[N][N];
int column[N];
char str[N+1];
int n, k;
void init()
{
for(int i=0; i<N; i++)
for(int j=0; j<N; j++)
{
mapp[i][j]=0;
}
}
ll ans;
void search(int x, int y, int step)
{
if(step==k){
ans++; return ;
}
int tx, ty;
for(int i=1; i<n; i++)
{
for(int j=0; j<n; j++)
{
tx=x+i; ty=j;
if(tx>=n || ty>=n)
break;
if(column[j]==1 || mapp[tx][ty]==0 || book[tx][ty]==1)
continue;
book[tx][ty]=1;
column[j]=1;
search(tx, ty, step+1);
book[tx][ty]=0;
column[j]=0;
}
}
}
int main()
{
while( ~scanf("%d%d", &n,&k) && n+k!=-2)
{
init();
for(int i=0; i<n; i++)
{
scanf("%s", str);
for(int j=0; str[j]!='\0'; j++)
{
if(str[j]=='#'){
mapp[i][j]=1;
}
}
}
ans=0;
for(int i=0; i<n; i++)
{
for(int j=0; j<n; j++)
{
if(mapp[i][j]==0) continue;
memset(book, 0, sizeof(book));
memset(column, 0, sizeof(column));
book[i][j]=1;
column[j]=1;
search(i, j, 1);
}
}
printf("%d\n", ans);
}
return 0;
}