POJ1321

来源:互联网 发布:淘宝买发票 搜索什么 编辑:程序博客网 时间:2024/06/07 00:32
棋盘问题
Time Limit: 1000MS Memory Limit: 10000KTotal Submissions: 39910 Accepted: 19457

Description

在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放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

2

1

好吧,比较简单的回溯法

#include <iostream>using namespace std;int n,k,ma[10][10]={0},cou,chess[10];bool isok(int m,int x){    int i;    for(i=0;i<m;i++)    {        if(chess[i]==x)            return false;    }    return true;}void fd(int m,int num){    //cout<<m<<"-"<<num<<endl;    if(num==k)    {        cou++;        return;    }    else{    if(m==n)        return ;    else    {        int i;        fd(m+1,num);        for(i=0;i<ma[m][0];i++)        {            if(isok(m,ma[m][i+1]))            {                chess[m]=ma[m][i+1];                fd(m+1,num+1);            }        }        chess[m]=0;    }    }}int main(){    cin>>n>>k;    int i,j;    char mn[10][10],aa;    while(n!=-1 && k!=-1)    {        for(i=0;i<n;i++)        {            for(j=0;j<n;j++)            {                cin>>aa;                if(aa=='#')                {                    ma[i][0]++;                    ma[i][ma[i][0]]=j+1;                }            }        }        cou=0;        fd(0,0);        cout<<cou<<endl;        for(i=0;i<=n;i++)        {            for(j=0;j<=n;j++)            {            ma[i][j]=0;            }        }        cin>>n>>k;    }    return 0;}

0 0