题意:在一个n*n的棋盘上放k个棋子(任意两个棋子不同行不同列)有几种放法。(n <= 8, k <= n)
题目链接:http://poj.org/problem?id=1321
——>>和八皇后问题很像,只是这里不用每行都有,简单回溯。
时间复杂度 O(4^n)
#include <cstdio>
#include <cstring>
const int MAXN = 8 + 10;
int n;
int k;
int C;
char G[MAXN][MAXN];
bool vis[MAXN];
void Dfs(int curRow, int curCnt)
{
if (curCnt == k)
{
++C;
return;
}
if (curRow == n) return;
for (int i = 0; i < n; ++i)
{
if (G[curRow][i] == '#' && vis[i] == false)
{
vis[i] = true;
Dfs(curRow + 1, curCnt + 1);
vis[i] = false;
}
}
Dfs(curRow + 1, curCnt);
}
void Read()
{
for (int i = 0; i < n; ++i)
{
getchar();
for (int j = 0; j < n; ++j)
{
G[i][j] = getchar();
}
}
}
void Solve()
{
C = 0;
memset(vis, 0, sizeof(vis));
Dfs(0, 0);
}
void Output()
{
printf("%d\n", C);
}
int main()
{
// freopen("poj_1321.in", "r", stdin);
while (scanf("%d%d", &n, &k) == 2)
{
if (n == -1 && k == -1) break;
Read();
Solve();
Output();
}
return 0;
}
old code:
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 10;
int cnt, n, k;
char MAP[maxn][maxn];
bool vis[maxn];
void dfs(int x, int cur)
{
if(cur == k)
{
cnt++;
return;
}
else
{
for(int i = x; i < n; i++)
for(int j = 0; j < n; j++)
if(MAP[i][j] == '#' && !vis[j])
{
vis[j] = 1;
dfs(i+1, cur+1);
vis[j] = 0;
}
}
}
int main()
{
int i, j;
while(scanf("%d%d", &n, &k) == 2)
{
if(n == -1 && k == -1) return 0;
for(i = 0; i < n; i++)
{
getchar();
for(j = 0; j < n; j++)
MAP[i][j] = getchar();
}
cnt = 0;
memset(vis, 0, sizeof(vis));
dfs(0, 0);
printf("%d\n", cnt);
}
return 0;
}