POJ 1321 棋盘问题

来源:互联网 发布:linux如何查看登录情况 编辑:程序博客网 时间:2024/06/07 08:32

题目大意:中文

题目链接

注释代码:

/*                                * Problem ID : POJ 1321 棋盘问题 * Author     : Lirx.t.Una                                * Language   : C++                    * Run Time   : 16 ms                                * Run Memory : 132 KB                               */ #include <iostream>#include <cstring>#include <cstdio>#defineMAXW8intn;//棋盘大小intcnt;//当前方案数//下标都是从0开始的charm[MAXW][MAXW + 1];//存储棋盘信息boolc[MAXW];//col,表示该列是否被占用过voiddfs( int r, int lft ) {//逐行深搜,即一行放一个,每一行中试探每一列//lft表示还有多少个棋子没放//r表示当前搜索到的行inti;//计数变量if ( !lft ) {//表示搜索完成cnt++;return ;}if ( r >= n ) return ;//搜索超出棋盘范围直接退出for ( i = 0; i < n; i++ )//搜索当前行的每一列if ( '#' == m[r][i] && !c[i] ) {//发现该位置可以摆放并且该行没被占用过c[i] = true;//试探性占用dfs( r + 1, lft - 1 );//继续向下搜索c[i] = false;//还原现场,搜索下一列}//!!!如果k < n,可能出现中间空出几行不用的情况//以上的搜索的含义是如果r行有位置可以摆就搜索,如果没位置摆就无解//不考虑是否跳过改行试一下下面的行//因此需要再试一下改行跳到下一行搜索//其中,如果剩余行和剩余棋子数超过宽度则无需再跳,最后必然会跳出棋盘之外,这是重要的剪枝!!if ( lft + r < n ) dfs( r + 1, lft );}intmain() {intk;//要摆放的棋子数inti;//计数变量while ( scanf("%d%d", &n, &k), n != -1 ) {memset(m, 0, sizeof(m));//空白和0都表示棋子不能放,所以不影响for ( i = 0; i < n; i++ ) scanf("%s", m[i]);if ( k > n ) {//棋子数大于棋盘宽度必定不能完成puts("0");continue;}cnt = 0;dfs( 0, k );//初始时从0行开始搜,剩余棋子是k个printf("%d\n", cnt);}return 0;}
无注释代码:

#include <iostream>#include <cstring>#include <cstdio>#defineMAXW8intn;intcnt;charm[MAXW][MAXW + 1];boolc[MAXW];voiddfs( int r, int lft ) {inti;if ( !lft ) {cnt++;return ;}if ( r >= n ) return ;for ( i = 0; i < n; i++ )if ( '#' == m[r][i] && !c[i] ) {c[i] = true;dfs( r + 1, lft - 1 );c[i] = false;}if ( lft + r < n ) dfs( r + 1, lft );}intmain() {intk;inti;while ( scanf("%d%d", &n, &k), n != -1 ) {memset(m, 0, sizeof(m));for ( i = 0; i < n; i++ ) scanf("%s", m[i]);if ( k > n ) {puts("0");continue;}cnt = 0;dfs( 0, k );printf("%d\n", cnt);}return 0;}

0 0