VJ 棋盘问题(NOIP1997)(POJ-1321)

刚刚开始学习算法,这是接触dfs后做的第一道题。如有局限之处(显然会有),还请大佬们多多指教!
在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放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

------------------------------------------我是分割线--------------------------------------------------
首先关注数据范围(!!),可知用int就够了。
下面是经过改进的代码(大佬的东西我自己想办法写出来就是我的了(大雾)),用英语写了些注释,希望可以促进大家理解。

#include 
#include 
#include 
int n,k;int c[10];/*a flag to judge the column situation*/
int res=0;/*actual number of situations*/
char ch[10][10];/*global variables in order to control in func dfs*/
int main()
{
    while(((scanf("%d%d",&n,&k)!=EOF)&&(n!=-1&&k!=-1))){/*break when -1 -1*/
        res=0;
        memset(c,0,sizeof(c));/*components in array c are random values*/
        for(int i=0;i<n;i++){
            scanf("%s",ch[i]);
        }
        dfs(0,0);
        printf("%d\n",res);
    }
}
void dfs(int a,int b){
    if(b==k){/*the request is done,and start the next circle*/
        res++;
        return ;
    }
    if(a>=n){
        return ;/*when the searching process meets its limit,break*/
    }
    for(int i=0;i<n;i++){
        if(c[i]) continue;/*if 1 goto the next circle*/
        if(ch[a][i]=='#'){
            c[i]=1;/*skip the ones in the same column*/
            dfs(a+1,b+1);/*start from the next row,adding 1 to the found times*/
            c[i]=0;/*clear the flag to calculate the actual amount of different situations*/
        }
    }
    dfs(a+1,b);/*clear and test the next row*/
}

我对dfs的理解:不断向下检索至无元素可被检索(depth first嘛),之后再返回规定的起点进行下一次检索。所以说:要用递归来解决问题!

———————————————————————————————————
まいにち いっしょうけんめいで,自分をたすけはできるでしょう?

你可能感兴趣的:(dfs)