棋盘问题 poj

在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放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
题目解析:这个题的意思就是让你在能放入棋盘的空格中,给你棋盘的个数,在满足题目条件的前提下,让你判断一共有多少种放法,比如说第一组数,一共有一个棋子,但是有两个能放棋盘的空位,所以一共有两种情况。
具体思路:基本框架是用dfs,但是这个地方需要一点技巧。首先从第一行开始,首先找到第一行中第一个能放置棋子的空位,并且把这一列标记一下,如果下一次走的时候这一列有能放置棋子的空位,这个地方是不能走的。判断搜索终止的条件是所有的棋子已放置完毕,然而这只是一种情况,再去找第二种情况的时候,需要返回到上一级,找到已经放置了k个棋子的状态,这个时候再去重新找第k个棋子的放置位置。//这个地方有一个疑问,在所有棋子都安置好的时候,在寻找另一种放置方式是市,需要返回上一个状态,也就是返回已经放置了k-1个棋子,准备放置第k个棋子的状态。但是由于visited【k】已经被清零,那么在寻找第k个数的放置时,这第k个数不就又放置到原来的位置了吗?这样不就有了一个死循环了?。ac代码如下:#include<iostream>
#include<cstring>
using namespace std;
int n,k;
char a[10][10];
int visited[100];
int num;
void DFS(int t1,int t2)
{
    if(t2==0)
    {
        num++;
        return ;
    }
    for(int i=t1; i<=n; i++)
    {
        for(int j=1; j<=n; j++)
        {
            if(visited[j]==1||a[i][j]=='.')continue;
            visited[j]=1;
            DFS(i+1,t2-1);//传参很重要,注意dfs中第一个参数传递的是i+1还是t1+1。。。。
            visited[j]=0;
        }
    }
}
int main()
{
    while(cin>>n>>k)
    {
        num=0;
        memset(visited,0,sizeof(visited));
        if(n==-1&&k==-1)
            break;
        else
        {
            for(int i=1; i<=n; i++)
            {
                cin>>a[i]+1;//我个人比较喜欢从1开始跑
            }
            DFS(1,k);
            cout<<num<<endl;
        }
    }
    return 0;
}


猜你喜欢

转载自blog.csdn.net/let_life_stop/article/details/80488245