题目大意:
给定一个n*m的中国象棋棋盘,现在希望放上k只马,这些马之间不能相互攻击,共有多少种方案?
第一行是一个t,代表有t组数据。
每一组数据的第一行是n(n<=8),m(m<=8),k(k<=5)
接下来是一个n*m的字符矩阵。
矩阵中只含有两种字符‘.’,‘#’,‘.’代表是空的,‘#’代表已经有子放在上面了。
总方案数
Sample Input
2 2 3 1 ... ... 2 3 2 ... ...
Sample Output
6
13
思路:
暴力搜索
之前有同学说我要好好写,格式不对,以后一定好好写
#include <iostream> #include <cstdio> #include <cstring> using namespace std; char mapp[10][10]; int dir[8][2]={{-1,2},{1,2},{-1,-2},{1,-2},{-2,1},{-2,-1},{2,-1},{2,1}};//马走的8个方向 int dir1[4][2]={{0,1},{0,-1},{-1,0},{1,0}}; //蹩马脚的情况,与马走的情况1对2 int n,m,k,sum; int judge() { int i,j,p; for(i=0;i<n;i++) { for(j=0;j<m;j++) { if(mapp[i][j]=='#')//找到马的位置时,要对可以走的8个方向进行判断 { int x; int y; for(p=0;p<8;p++) { x=i+dir[p][0]; y=j+dir[p][1]; if(x<0||y<0||x>=n||y>=m)continue;//越界的不用判断 if(mapp[x][y]=='#') //在可以走的方向上有马 { int x1,y1; x1=i+dir1[p/2][0]; y1=j+dir1[p/2][1]; if(mapp[x1][y1]=='.') //不蹩马脚说明此路可以通行,不成立,返回0 return 0; } } } } } return 1; //判断完所有情况,可以成立 ,返回1 } void DFS(int d,int cnt) { if(cnt==k) { if(judge())sum++; //判断此种情况能不能成立,能成立,情况数加1 return; } if(d==n*m)return; //超过范围,return int x=d/m; int y=d%m; if(mapp[x][y]=='.') { mapp[x][y]='#'; DFS(d+1,cnt+1); mapp[x][y]='.'; //回溯 } DFS(d+1,cnt); // 继续搜索 } int main() { int t,i,j; scanf("%d",&t); while(t--) { scanf("%d%d%d",&n,&m,&k); sum=0; for(i=0;i<n;i++) { scanf("%s",mapp[i]); //读图 } DFS(0,0); printf("%d\n",sum); } return 0; }