323_棋盘问题
2017-07-15 15:48
246 查看
/* Name: 323_棋盘问题 Copyright: Author: Date: 15-07-17 14:59 Description: 323_棋盘问题 查看 提交 统计 提问 总时间限制: 1000ms 内存限制: 65536kB 描述 在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列, 请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案C。 输入 输入含有多组测试数据。 每组数据的第一行是两个正整数,n k,用一个空格隔开,表示了将在一个n*n的矩阵内描述棋盘,以及摆放棋子的数目。 n <= 8 , k <= n 当为-1 -1时表示输入结束。 随后的n行描述了棋盘的形状:每行有n个字符,其中 # 表示棋盘区域, . 表示空白区域(数据保证不出现多余的空白行或者空白列)。 输出 对于每一组数据,给出一行输出,输出摆放的方案数目C (数据保证C<2^31)。 样例输入 2 1 #. .# 4 4 ...# ..#. .#.. #... -1 -1 样例输出 2 1 算法思想: 与八皇后问题类似,基本方法是回溯,区别在于本题只要求不同行列就行(相当于k个车), 需要注意的是k<=n,故中间有可能有空行(该行一个棋子也不摆),可用列举第t个棋子可以取的行号进行循环。 */ #include<iostream> #include<string> #include<cmath> using namespace std; const int N = 8; //皇后的个数 int cel ;//记录n个皇后的列坐标 bool b ; //b[j]==0表示列j可用 char map ; int sum = 0;//保存可以放置的方案数 int n, k; void DFS(int r, int t); //递归回溯,r表示第r行,t表示第t个棋子 int main() { cin >> n >> k; while (n != -1 && k != -1) { for (int i=0; i<n; i++) { for (int j=0; j<n; j++) { cin >> map[i][j]; } b[i] = 0; } sum = 0; for (int i=0; i<=n-k; i++) //第一个棋子所能摆放的行号,为避免重复,棋子按从上到下的顺序摆放 { DFS(i, 1); } cout << sum << endl; cin >> n >> k; } return 0; } void DFS(int r, int t) //递归回溯,r表示第r行,t表示第t个棋子 { if(n - r < k - t) //剩余行数少于棋子数,则无解 return; for(int j=0; j<n; j++)//可能的列号 { if(map[r][j]=='#' && !b[j]) { cel[r] = j; if (k == t) //k个棋子均已摆好 { sum++; } else { b[j] = 1; for (int i=r+1; i<n; i++)//第t+1个棋子所能摆放的行号,为避免重复,棋子按从上到下的顺序摆放 { DFS(i, t+1); } b[j] = 0; //复原 } } } }
/* Name: 323_棋盘问题 Copyright: Author: Date: 15-07-17 14:59 Description: 323_棋盘问题 查看 提交 统计 提问 总时间限制: 1000ms 内存限制: 65536kB 描述 在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列, 请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案C。 输入 输入含有多组测试数据。 每组数据的第一行是两个正整数,n k,用一个空格隔开,表示了将在一个n*n的矩阵内描述棋盘,以及摆放棋子的数目。 n <= 8 , k <= n 当为-1 -1时表示输入结束。 随后的n行描述了棋盘的形状:每行有n个字符,其中 # 表示棋盘区域, . 表示空白区域(数据保证不出现多余的空白行或者空白列)。 输出 对于每一组数据,给出一行输出,输出摆放的方案数目C (数据保证C<2^31)。 样例输入 2 1 #. .# 4 4 ...# ..#. .#.. #... -1 -1 样例输出 2 1 算法思想: 与八皇后问题类似,基本方法是回溯,区别在于本题只要求不同行列就行(相当于k个车), 需要注意的是k<=n,故中间有可能有空行(该行一个棋子也不摆),故可以分成行r摆子和不摆子两种情况 */ #include<iostream> #include<string> #include<cmath> using namespace std; const int N = 8; //皇后的个数 int cel ;//记录n个皇后的列坐标 bool b ; //b[j]==0表示列j可用 char map ; int sum = 0;//保存可以放置的方案数 int n, k; void DFS(int r, int t); //递归回溯,r表示第r行,t表示第t个棋子 int main() { cin >> n >> k; while (n != -1 && k != -1) { for (int i=0; i<n; i++) { for (int j=0; j<n; j++) { cin >> map[i][j]; } b[i] = 0; } sum = 0; DFS(0, 1); cout << sum << endl; cin >> n >> k; } return 0; } void DFS(int r, int t) //递归回溯,r表示第r行,t表示第t个棋子 { if(n - r < k - t) //剩余行数少于棋子数,则无解 return; DFS(r+1, t); //该行不摆子 for(int j=0; j<n; j++)//可能的列号 { if(map[r][j]=='#' && !b[j]) { cel[r] = j; if (k == t) //k个棋子均已摆好 { sum++; } else { b[j] = 1; DFS(r+1, t+1); //该行摆子 b[j] = 0; //复原 } } } }
相关文章推荐
- OpenJudge-Mooc 323:棋盘问题(dfs)
- 323:棋盘问题
- 323:棋盘问题题解
- Poj 1321 棋盘问题(搜索)
- POJ 1321(A)棋盘问题
- POJ 1321 棋盘问题 (DFS)
- POJ1321棋盘问题
- 201301 JAVA 题目2-3级_棋盘问题
- poj1321_dfs_棋盘问题
- POJ 1321----棋盘问题(dfs+回溯)
- 棋盘问题
- POJ 1321 棋盘问题
- 棋盘问题(dfs)
- poj1321——棋盘问题——————【状态压缩、动态规划】
- 棋盘问题 poj1321
- POJ1321:棋盘问题(状压dp & DFS)
- 棋盘问题
- poj 1321 棋盘问题
- POJ 1321 棋盘问题 dfs回溯
- poj 1321 棋盘问题