POJ1321 摆放棋子(DFS)


问题描述:

在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。
 要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,
 摆放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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值