poj 1321 棋盘问题
Description
在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案C。
Input
输入含有多组测试数据。
每组数据的第一行是两个正整数,n k,用一个空格隔开,表示了将在一个n*n的矩阵内描述棋盘,以及摆放棋子的数目。 n <= 8 , k <= n
当为-1 -1时表示输入结束。
随后的n行描述了棋盘的形状:每行有n个字符,其中 # 表示棋盘区域, . 表示空白区域(数据保证不出现多余的空白行或者空白列)。
每组数据的第一行是两个正整数,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
1 #include <iostream> 2 #include <stdio.h> 3 #include <string.h> 4 using namespace std; 5 int n,k; 6 char map[10][10]; 7 bool flag[10][10]; 8 int count,cnt; 9 struct node 10 { 11 int x,y; 12 }dd[70]; 13 14 void dfs(int step,int row) 15 { 16 if(step==k) 17 { 18 count++; 19 return; 20 } 21 int i,j; 22 for(i=0;i<cnt;i++) 23 { 24 if(!flag[dd[i].x][dd[i].y] && dd[i].x>row) 25 { 26 node ff[70]; 27 int p=0; 28 for(j=0;j<n;j++) 29 { 30 if(map[dd[i].x][j]=='#' && !flag[dd[i].x][j]) 31 { 32 ff[p].x=dd[i].x; 33 ff[p++].y=j; 34 } 35 } 36 for(j=0;j<n;j++) 37 { 38 if(map[j][dd[i].y]=='#' && !flag[j][dd[i].y]) 39 { 40 ff[p].x=j; 41 ff[p++].y=dd[i].y; 42 } 43 } 44 for(j=0;j<p;j++) 45 { 46 flag[ff[j].x][ff[j].y]=true; 47 } 48 dfs(step+1,dd[i].x); 49 for(j=0;j<p;j++) 50 { 51 flag[ff[j].x][ff[j].y]=false; 52 } 53 } 54 } 55 56 } 57 int main() 58 { 59 while(~scanf("%d%d",&n,&k)) 60 { 61 if(n==-1 && k==-1) 62 break; 63 int i,j; 64 for(i=0;i<n;i++) 65 { 66 scanf("%s",map[i]); 67 } 68 cnt=0; 69 for(i=0;i<n;i++) 70 { 71 for(j=0;j<n;j++) 72 { 73 if(map[i][j]=='#') 74 { 75 dd[cnt].x=i; 76 dd[cnt++].y=j; 77 } 78 } 79 } 80 count=0; 81 memset(flag,false,sizeof(flag)); 82 dfs(0,-1); 83 printf("%d\n",count); 84 } 85 return 0; 86 }
题目意思很明显,简单的DFS
注意:
标记每一行和每一列时最好用额外的数组装起来,避免把一些不应该改变的值进行了改变
放到数组里面的条件是,那一点必须是棋盘区域,以及没有被标记过。