POJ 1321 棋盘问题 (N皇后变形)

题意:在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案C。

分析:这题其实就是N皇后变形,不懂N皇后的,可以参考这篇博客

因为每一行或者每一列都只能放一个棋子,所以我们直接递归每一行,用一个数组标记每一列的访问状态,然后直接DFS就行了

#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<stack>
#include<cstdio>
#include<vector>
#include<utility>
#include<cctype>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define inf 0x3f3f3f3f
#define maxn 15
#define Clear(x) memset(x,0,sizeof(x))
#define fup(i,a,b) for(int i=a;i<b;i++)
#define rfup(i,a,b) for(int i=a;i<=b;i++)
#define fdn(i,a,b) for(int i=a;i>b;i--)
#define rfdn(i,a,b) for(int i=a;i>=b;i--)
typedef long long ll;
using namespace std;
const double pi=acos(-1.0);
char maze[maxn][maxn];
int vis[maxn];/**标记第i列是否已经放置过*/
int n,k,sum;

void init()
{
    Clear(maze);
    Clear(vis);
    sum=0;
}

void dfs(int step,int row)
{
    if(step==k){
        sum++;
        return;
    }
    if(row>n) return;
    for(int j=0;j<n;j++)
    {
        if(maze[row][j]=='#'&&!vis[j])
        {
            vis[j]=1;
            dfs(step+1,row+1);
            vis[j]=0;
        }
    }
    dfs(step,row+1);/**注意,这一条语句的作用,可以这样理解,如果有一行(不是最后一行)
                    字符全部都是".",没有#,如果没有这一条语句,那么由于没有"#",所以上面的for
                    循环的时候,不会递归到下一行,for循环结束就回溯到上一行了,但事实上呢,这一行
                    的下面还有图,但是都不会再跑,所以这就是这一条语句的作用*/
}

int main()
{
    while(scanf("%d%d",&n,&k)==2)
    {
        if(n==-1||k==-1) break;
        init();
        for(int i=0;i<n;i++)
            scanf("%s",maze[i]);
        dfs(0,0);
        cout<<sum<<endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41311604/article/details/81220225
今日推荐