1.链接地址:
http://bailian.openjudge.cn/practice/1321
http://poj.org/problem?id=1321
2.题目:
棋盘问题
Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 20403 Accepted: 10138 Description
在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放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 -1Sample Output
2 1Source
3.思路:
dfs+简单剪枝即可
思路和八皇后问题非常类似
比八皇后简单是不需要去除斜线的位置
比八皇后稍微复杂是棋盘不固定大小
4.代码:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 6 using namespace std; 7 8 int **arr; 9 int n; 10 int res; 11 12 void dfs(int m,int k) 13 { 14 int i,j; 15 16 if(k == 0) { res++; return; } 17 18 if(m < n) 19 { 20 if(n - m < k) return;//剪枝一,剩余的行数少于需要摆放的棋盘,则不符合要求 21 22 dfs(m + 1,k); 23 24 for(i = 0; i < n; ++i) 25 { 26 if(arr[m][i] == 0) 27 { 28 for(j = m + 1; j < n; ++j) if(arr[j][i] != -1) ++arr[j][i]; 29 dfs(m + 1,k - 1); 30 for(j = m + 1; j < n; ++j) if(arr[j][i] != -1) --arr[j][i]; 31 32 } 33 } 34 } 35 } 36 37 38 int main() 39 { 40 //freopen("C://input.txt","r",stdin); 41 42 int i,j; 43 44 int k; // n <= 8 , k <= n 45 cin >> n >> k; 46 47 while(n != -1 || k != -1) 48 { 49 arr = new int*[n]; 50 for(i = 0; i < n; ++i) {arr[i] = new int[n];memset(arr[i],0,sizeof(int) * n);} 51 52 char ch; 53 for(i = 0;i < n; ++i) 54 { 55 for(j = 0;j < n; ++j) 56 { 57 cin >> ch; 58 if(ch == '.') arr[i][j] = -1; 59 } 60 } 61 62 /*for(i = 0;i < n; ++i) 63 { 64 for(j = 0;j < n; ++j) 65 { 66 cout << arr[i][j] << " "; 67 } 68 cout << endl; 69 }*/ 70 71 res = 0; 72 73 dfs(0,k); 74 75 cout << res << endl; 76 77 for(i = 0; i < n; ++i) delete [] arr[i]; 78 delete [] arr; 79 80 cin >> n >> k; 81 } 82 83 84 return 0; 85 }