问题描述:
在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。
要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,
摆放k个棋子的所有可行的摆放方案C。
一个n*n的矩阵内描述棋盘。
n <= 8 , k <= n
方法:
看了网上的解题报告后,感觉有点抽像,基本上都是采用 逐行搜索,代码很短但是写起来和理解起来有点抽象。
运行结果:
156K 47MS C++ 1895B 2013-11-28 16:40:52
代码1:
#include<iostream>
#include<vector>
#include<map>
#include <string>
#include <set>
#include <stack>
#include <queue>
using namespace std;
#include <stdio.h>
#include <string.h>
#define N 8
#define range(m) (m >= 0 && m < N)
int g_chessboard[N][N] = {};
int g_row[N] = {};
bool g_col[N] = {};
int g_varN = 0;
int g_varK = 0;
int g_Num = 0;
void dfs(int iR, int iStep)
{
if(iStep == g_varK)
{
g_Num++;
return ;
}
if(iR >= g_varN)
{
return ;
}
for(int j = 0; j < g_varN; j++)
{
if(g_chessboard[iR][j] && !g_col[j])
{
g_col[j] = true;
dfs(iR + 1, iStep + 1);
g_col[j] = false;
}
}
dfs(iR + 1, iStep);
return ;
}
int visits()
{
memset(g_row, 0, sizeof(g_row));
memset(g_col, 0, sizeof(g_col));
g_Num = 0;
//for(int i = 0; i < g_varN; i++)
//{
dfs(0, 0);
//}
return g_Num;
}
void init()
{
//int iSize = (sizeof(g_chessboard) / sizeof(g_chessboard[0])) * (sizeof(g_chessboard[0]) / sizeof(g_chessboard[0][0]));
//memset(g_chessboard, 0, iSize * sizeof(int));
char szRow[N+1] = {};
for(int i = 0; i < g_varN; i++)
{
scanf("%s", szRow);
for(int j = 0; j < g_varN; j++)
{
if(szRow[j] == '.')
{
g_chessboard[i][j] = 0;
}
else if(szRow[j] == '#')
{
g_chessboard[i][j] = 1;
}
}
}
}
int main()
{
//int take = ::GetTickCount();
freopen("in48.txt", "r", stdin);
//freopen("out47.txt", "w", stdout);
while(true)
{
scanf("%d %d", &g_varN, &g_varK);
if(-1 == g_varN)
{
break;
}
init();
visits();
printf("%d\n", g_Num);
}
//cout<<::GetTickCount() - take<<endl;
return 0;
}
代码2:
#include<iostream>
#include<vector>
#include<map>
#include <string>
#include <set>
#include <stack>
#include <queue>
using namespace std;
#include <stdio.h>
#include <string.h>
#define N 8
int g_chessboard[N][N] = {};
bool g_col[N] = {};
int g_varN = 0;
int g_varK = 0;
int g_Num = 0;
int g_step = 0;
void dfs(int iR)
{
if(iR >= g_varN)
{
return ;
}
for(int j = 0; j < g_varN; j++)
{
if(g_chessboard[iR][j] && !g_col[j])
{
g_col[j] = true;
g_step++;
if(g_step == g_varK)
{
g_col[j] = false;
g_step--;
g_Num++;
}
else
{
dfs(iR + 1);
g_col[j] = false;
g_step--;
}
}
}
dfs(iR + 1);
return ;
}
void init()
{
char szRow[N+1] = {};
for(int i = 0; i < g_varN; i++)
{
scanf("%s", szRow);
for(int j = 0; j < g_varN; j++)
{
if(szRow[j] == '.')
{
g_chessboard[i][j] = 0;
}
else if(szRow[j] == '#')
{
g_chessboard[i][j] = 1;
}
}
}
}
int main()
{
//int take = ::GetTickCount();
freopen("in48.txt", "r", stdin);
//freopen("out47.txt", "w", stdout);
while(true)
{
scanf("%d %d", &g_varN, &g_varK);
if(-1 == g_varN)
{
break;
}
init();
memset(g_col, 0, sizeof(g_col));
g_Num = 0;
g_step = 0;
dfs(0);
printf("%d\n", g_Num);
}
//cout<<::GetTickCount() - take<<endl;
return 0;
}