版权声明: https://blog.csdn.net/qq_40828060/article/details/79364577
码字格式总有问题,,,换图了
【实现代码】
#include <iostream>
#include<stdio.h>
using namespace std;
int n,ans,End,map[20];
void dfs(int row,int ld,int rd,int d) {
if(d>n) {
ans++;return;
}
int pos=End&(~(row|ld|rd|map[d])),p; //可以分三步来理解:1、先|方向找到最终的位置 2、取反(~) 3、用End &上,去掉多余的1。至于End是什么,其实就是(1>>n)-1即n位的1,n位前的0回被抹掉,表示可放置的1(0取反)不受影响
while(pos) {
p=pos&(-pos);//用lowbit原理
pos-=p; //把用过的可能性减掉
dfs(row+p,(ld+p)<<1,(rd+p)>>1,d+1); //状态转移方程,下一行的状态
}
}
int main() {
char s[20];
scanf("%d\n",&n); //这是个坑点!!!cin会读进换行符
End=(1<<n)-1; //上文有解释
for(int i=1; i<=n; i++) {
gets(s);
for(int j=1; j<=n; j++)
map[i]=(s[j-1]=='.')+(map[i]<<1);//这个东西其实就是手动造出表示起始状态的二进制数,就是遇到" . " 就放1表示不能放,如果没到第n列,就不停的往后补零}
dfs(0,0,0,1);
printf("%d",ans);
return 0;
}