洛谷P1562 还是N皇后

题目描述

正如题目所说,这题是著名的N皇后问题。

输入输出格式

输入格式:

 

第一行有一个N。接下来有N行N列描述一个棋盘,“*”表示可放“.”表示不可放。

 

输出格式:

 

输出方案总数

 

输入输出样例

输入样例#1: 

4
**.*

****

****

****

输出样例#1:

 1

 

这一道题和n皇后问题非常像,不同的是这一道题有些位置无法放置皇后,如果用搜索的话会超时,不过限制皇后的位置却为状态压缩(位运算)提供了契机

限制皇后的位置无非就是这3种情况:

1.地形限制(输入的限制)

2.行的限制(皇后会吃掉同行的皇后),这个其实可以忽略不计

3.列的限制(皇后会吃掉同列的皇后)

4.斜的限制(皇后会吃掉左斜和右斜的皇后)

代码:

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define lowbit(x) x&-x
using namespace std;
inline int read(){
	int x=0,f=0;char s=getchar();
	while(!isdigit(s))f|=s=='-',s=getchar();
	while( isdigit(s))x=(x<<1)+(x<<3)+s-48,s=getchar();
	return !f?x:-x;
}
inline void print(int x){
	if(x/10>0)print(x/10);
	putchar(x%10+'0');
}
const int N=21;
int n,sta[N];//sta表示每一行的限制 
int flag,ans;//flag表示n个1,ans记录结果 
char st[N];//st输入的时候用 
void dfs(int now,int zuo,int you,int k){
	if(now==flag){ans++;return;}//如果放完了 
	int p,pos=flag&(~(now|zuo|you|sta[k]));//pos表示限制 
	while(pos){
		p=lowbit(pos);//树状数组中的lowbit()可以求出第一个出现的1 
		pos^=p;//把1删掉 
		dfs(now|p,(zuo+p)<<1,(you+p)>>1,k+1);//左斜到下一行就会左移一位,右斜右移一位 
		//我也不知道为什么把(zuo+p)<<1改成(zuo|p)<<1会变慢 
	}
}
int main(){
	//freopen("data.in","r",stdin);
	//freopen("std.out","w",stdout);
	n=read();flag=(1<

 

你可能感兴趣的:(题解)