搜索算法之棋盘问题

                               A – 棋盘问题

Time Limit:1000MS     Memory Limit:10000KB     64bit IO Format:%I64d & %I64u
Submit
 
Status
 
Practice
 
POJ 1321
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<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
using namespace std;
int n,k,ans,qizi;//qizi为棋子的数量
char s[10][10];
int a[100];
void f(int x)
{
    int i;
    if(qizi==k)//如果棋子的数量与所给数量相等则为一种方法
    {
        ans++;
        return ;
    }
    else
    {
        if(x>=n)//超过边界
            return ;
        else
        {
            for(i=0; i<n; i++)//第一行第一列开始搜索
            {
                if(s[x][i]=='#'&&!a[i])//遇到棋盘区域,且未被标记
                {
                    a[i]=1;//标记此处
                    qizi++;//棋子数量加一
                    f(x+1);//遍历失败或者棋子数满足了
                    qizi--;//经过一轮递归后棋子数量始终保持不变,因为没有放棋子
                    a[i]=0;//取消标记
                }
            }
            f(x+1);//该行已经满足棋子总数,所以第i行不放棋子,进行剩下的k-1个棋子的遍历
        }
    }
}
int main()
{
    while(scanf("%d%d",&n,&k)!=EOF)
    {
        getchar();
        if(n==-1&&k==-1)
            break;
        int i,j;
        ans=0;
        memset(a,0,sizeof(a));
        for(i=0; i<n; i++)
            scanf("%s",s[i]);
        f(0);
        printf("%d\n",ans);
    }
    return 0;
}

 

 

 

    原文作者:骑士周游问题
    原文地址: https://blog.csdn.net/lee371042/article/details/79071751
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞