POJ -1321 棋盘问题 解题思路 c/c++实现

本文详细解析了POJ-1321棋盘问题的求解思路,采用C++代码实现,通过标记地图和棋子位置避免重复搜索,实现了对特定条件下棋子放置方案的高效计算。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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; //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)); //不要忘记初始化book数组和column数组
				memset(column, 0, sizeof(column));
				book[i][j]=1;
				column[j]=1;
				search(i, j, 1);
			}
		}
		printf("%d\n", ans);
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值