Emmm,我又来 POJ 了,这题感受比上次作的简单点。相似皇后问题。可是稍微作了一点变形,好比棋子数量是不定的。棋盘形状不在是方形等等。web
题目连接:POJ 1321 棋盘问题svg
基本思路:从上往下放旗子,每种状况完成后,复盘继续下一种状况。函数
这里讲一下,void backTrack(int left, int x)
函数。spa
left
表示还剩的棋子数量,显然若是 left
为 0,说明全部棋子已放完,那么方案数 solution
加 1。code
若是不为 0。那么继续检查当前位置的列是否有棋子,若是无棋子,那么当前位置能够放旗子。而后继续递归,棋子数量减 1,行数加 1。若是有棋子,那么悔棋 1 步。继续下一个位置。xml
/** * @author wowpH * @date 2019-9-14 19:54:16 */ #include<stdio.h> #include<string.h> #define TRUE 1 #define FALSE 0 #define MAX_N 8 // 矩阵最大为8 #define BOARD TRUE // 棋盘 #define BLANK FALSE // 空白 int matrix[MAX_N][MAX_N];// 矩阵,BOARD表示棋盘,BLANK表示空白 int n, k, solution;// solution最终结果 int column[MAX_N];// 每列是否有棋子,TRUE表示有棋子,FALSE表示无棋子 void backTrack(int left, int x) {// 回溯,left表示剩余棋子,x表示当前行 if (left == 0) {// 无多余棋子 ++solution; // 方案数加1 return; } // 遍历x行及下方的棋盘 for (int i = x; i < n; ++i) { for (int j = 0; j < n; ++j) { if (matrix[i][j] == BLANK) {// 空白 continue; // 不能放旗子 } if (column[j] == TRUE) {// 第j列有棋子 continue; // 不能放旗子 } column[j] = TRUE; // 当前位置能够放子,设为TRUE backTrack(left - 1, i + 1); // 回溯,棋子数减1,行数加1 column[j] = FALSE; // 复盘,设为无子 } } } int main() { while (scanf("%d %d", &n, &k) && n != -1 && k != -1) { getchar();// '\n' // 输入棋盘 for (int i = 0; i < n; ++i) { for (int j = 0; j < n; ++j) { char ch = getchar(); if (ch == '.') { matrix[i][j] = BLANK;// 空白 } else if (ch == '#') { matrix[i][j] = BOARD;// 棋盘 } } getchar();// '\n' } // 初始化 memset(column, FALSE, sizeof(column)); solution = 0; backTrack(k, 0);// 回溯 printf("%d\n", solution); } return 0; }