POJ棋盘问题(kuangbin带你飞搜索专题)
Posted mld-code-life
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ棋盘问题(kuangbin带你飞搜索专题)相关的知识,希望对你有一定的参考价值。
题意:在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案C。
每组数据的第一行是两个正整数,n k,用一个空格隔开,表示了将在一个n*n的矩阵内描述棋盘,以及摆放棋子的数目。 n <= 8 , k <= n
当为-1 -1时表示输入结束。
随后的n行描述了棋盘的形状:每行有n个字符,其中 # 表示棋盘区域, . 表示空白区域(数据保证不出现多余的空白行或者空白列)。
#include<cstdio> #include<cstring> int n,k; int ans; char mp[10][10]; bool vis[10];//标记哪一列被使用 void dfs(int x,int cnt){ if(cnt==k){ ans++; return; } if(x==n){ return; } //这一行可以放棋子 for(int i=0;i<n;i++){ //在可以放置棋子的前提下判断是否有可以放棋子的位置 if(!vis[i] && mp[x][i]==‘#‘){ vis[i]=true; //标记这一列已经放置棋子 dfs(x+1,cnt+1); vis[i]=false;//递归返回时清除标记,保证能再次搜索这个位置 } } //这一行不放棋子 dfs(x+1,cnt); } int main() { while(scanf("%d%d",&n,&k)!=EOF){ if(n==-1 && k==-1) break; //初始化变量 ans=0; memset(mp,0,sizeof(mp)); memset(vis,0,sizeof(vis)); for(int i=0;i<n;i++){ scanf("%s",mp[i]); } dfs(0,0);//从第0行第0个元素开始搜索 printf("%d ",ans); } return 0; }
写法二:
从当前行开始,搜索下面的每一行,在每一层递归中,都可以从当前行x的任意一行开始搜索,那么也代表着每一行可能放棋子,也可能不放棋子。(额,二层for循环的递归不知该怎么解释是好了,如果谁有更好的解释可以在下面评论)
理解二重for循环+递归
一重for循环加上递归可以搜到每一列,对于二重for循环,在递归的每一层程序中(每一层函数),可以任意选择每一行的棋盘。例如第一层递归程序,可以选择使用第1行、第2行、...第n行棋盘,第二层递归,可以选择第2、3...n行棋盘,第三层递归可以选择第3行、第4行、...、第n行棋盘。所以当每一层递归程序任意选择一行棋盘,这样就构成了搜索的所有选择。 (解法一的两个搜索分支也组成了所有的搜索选择)
void dfs(int x,int cnt){ if(cnt==k){ ans++; return; } for(int i=x;i<n;i++){ for(int j=0;j<n;j++){ if(!vis[j] && mp[i][j]==‘#‘){ vis[j]=true; dfs(i+1,cnt+1); vis[j]=false; } } } }
以上是关于POJ棋盘问题(kuangbin带你飞搜索专题)的主要内容,如果未能解决你的问题,请参考以下文章
[kuangbin带你飞]专题一 简单搜索 A - 棋盘问题
Dungeon Master POJ - 2251 [kuangbin带你飞]专题一 简单搜索
Catch That Cow POJ - 3278 [kuangbin带你飞]专题一 简单搜索
kuangbin带你飞专题POJ - 3126 Prime Path