标签:n皇后 eof 题解 color col div 程序 出现 专题
题意:在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案C。
#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\n",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; } } } }
标签:n皇后 eof 题解 color col div 程序 出现 专题
原文地址:https://www.cnblogs.com/mld-code-life/p/12482865.html