https://vjudge.net/contest/65959#problem
A题POJ1321
题目类型:DFS类型题目
难易程度:1
被吊打的老年选手,现在连字符串图的读入都有点问题了。不过多写几下就好了。
思路:
DFS的参数是 当前遍历到的层数 和 当前放置的棋子的个数。
用一个标记数组来标记当前列有没有被访问过。
DFS具体过程,对当前行的每一列进行判断(看当前位置是否是棋盘,当前位置是否被标记过),如果是棋盘,且没有被标记过,那么就将当前列标记,并进入下一行进行DFS(row+1,num+1)。(DFS前后要对放置棋子的个数进行标记和取消标记)。
当对整行都遍历了之后,再 DFS(row+1,num),跨过当前行用下一行。
DFS的出口是:当num == k(即放置的棋子数到达要求的棋子数时,停止。还有就是当访问的行row 越界后,也停止)
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std;
char c;
int n, k;
int vis_col[10];
int g[10][10];
int ans = 0;
void DFS(int row, int num)
{
if(num == k)
{
ans ++;
return;
}
if (row >= n)
return;
for(int icol = 0; icol < n; ++icol)
{
if(g[row][icol] && !vis_col[icol])
{
vis_col[icol] = 1;
DFS(row+1, num+1);
vis_col[icol] = 0;
}
}
DFS(row+1, num);
}
int main()
{
//freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
while(scanf("%d %d", &n, &k) != EOF && n!=-1 && k!=-1)
{
memset(g, 0, sizeof(g));
ans = 0;
memset(vis_col, 0, sizeof(vis_col));
for(int i = 0; i < n; ++i)
{
for(int j = 0; j < n; ++j)
{
cin >> c;
if(c == '#')
g[i][j] = 1;
}
}
DFS(0,0);
printf("%d
", ans);
}
return 0;
}