棋盘问题系列

来源:互联网 发布:lovecloud是什么软件 编辑:程序博客网 时间:2024/04/30 08:25
在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案C。
Input
输入含有多组测试数据。
每组数据的第一行是两个正整数,n k,用一个空格隔开,表示了将在一个n*n的矩阵内描述棋盘,以及摆放棋子的数目。 n <= 8 , k <= n
当为-1 -1时表示输入结束。
随后的n行描述了棋盘的形状:每行有n个字符,其中 # 表示棋盘区域, . 表示空白区域(数据保证不出现多余的空白行或者空白列)。
Output
对于每一组数据,给出一行输出,输出摆放的方案数目C (数据保证C<2^31)。
Sample Input
2 1#..#4 4...#..#..#..#...-1 -1
Sample Output
21 

这道题跟皇后问题有相似的地方也有不一样的地方,比如遍历到某一行可以选择放棋子也可以选择不放。
#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;int n,k,ans,tot;char a[10][10];bool vis[10][10];bool can(int x,int y){    if(vis[x][y]||a[x][y]=='.')        return false;    for(int i=x-1;i>=0;i--)    {        if(vis[i][y])            return false;    }    for(int i=y-1;i>=0;i--)        if(vis[x][i])            return false;    return true;}void dfs(int step,int sum){    if(sum==k)//放了k个棋子那么就是一种符合方案,tot+1    {        tot++;        return ;    }    if(step==n)//到最后一排,结束遍历,ans取最大值    {        ans=max(ans,tot);        return ;    }    for(int i=0;i<n;i++)    {        if(can(step,i))        {            vis[step][i]=true;            dfs(step+1,sum+1);            vis[step][i]=false;        }    }    dfs(step+1,sum);//这里就是不一样的地方了,不在这一行放置棋子}int main(){    while(~scanf("%d%d",&n,&k))    {        if(n==-1&&k==-1)            break;        ans=0,tot=0;        for(int i=0;i<n;i++)            scanf("%s",a[i]);        dfs(0,0);        printf("%d\n",ans);    }}



原创粉丝点击