Codevs 1295 N皇后问题
2017-08-15 15:01
288 查看
题目描述 Description
在n×n格的棋盘上放置彼此不受攻击的n个皇后。按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。n后问题等价于再n×n的棋盘上放置n个皇后,任何2个皇后不妨在同一行或同一列或同一斜线上。
输入描述 Input Description
给定棋盘的大小n (n ≤ 13)
输出描述 Output Description
输出整数表示有多少种放置方法。
样例输入 Sample Input
8
样例输出 Sample Output
92
数据范围及提示 Data Size & Hint
n<=13
(时限提高了,不用打表了)
八皇后问题是一个经典的深度优先搜索问题,在此说一下这个题的难点和剪枝。
来表示皇后能够攻击到的区域。
具体怎么实现呢?
因为皇后能够攻击一整行和一整列,所以我们只需要用”bool hang[15],lie[15];”这样来记录就好了。
难点来了,斜向怎么实现呢?
让我们观察一个6*6的棋盘:
发现了吗?从右上到左下↙的这条线中,所有x+y的值都是一样的。
例如,(1,3)=4;(2,2)=4;(3,1)=4;
这样我们就解决了一条对角线,开一个”bool xian[30];”用x+y的值表示数组下标。
例如,我们在(4,5)放置了皇后,那么就让”xian[9]=true;”
另一条对角线怎么办呢?
我们似乎无法从表中得出什么规律了,但我们可以为每一条↘对角线标上一个序号。
将最长的那条标为1,然后以横行为起点的线依次标为2,3,4… ,以竖列为起点的依次标为2+n,3+n,4+n…
突然发现,以横行为起点的标号就是x-y+2啊。
get√
贴码
然而我们无论我们怎样优化,也没法做到十五皇后不超时QAQ
在n×n格的棋盘上放置彼此不受攻击的n个皇后。按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。n后问题等价于再n×n的棋盘上放置n个皇后,任何2个皇后不妨在同一行或同一列或同一斜线上。
输入描述 Input Description
给定棋盘的大小n (n ≤ 13)
输出描述 Output Description
输出整数表示有多少种放置方法。
样例输入 Sample Input
8
样例输出 Sample Output
92
数据范围及提示 Data Size & Hint
n<=13
(时限提高了,不用打表了)
八皇后问题是一个经典的深度优先搜索问题,在此说一下这个题的难点和剪枝。
思考
首先,皇后的攻击范围是米字型,也就是四条互不平行的直线,所以我们想到使用四个布尔数组来表示皇后能够攻击到的区域。
具体怎么实现呢?
因为皇后能够攻击一整行和一整列,所以我们只需要用”bool hang[15],lie[15];”这样来记录就好了。
难点来了,斜向怎么实现呢?
让我们观察一个6*6的棋盘:
x+y | 1 | 2 | 3 | 4 | 5 | 6 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
2 | 3 | 4 | 5 | 6 | 7 | 8 |
3 | 4 | 5 | 6 | 7 | 8 | 9 |
4 | 5 | 6 | 7 | 8 | 9 | 10 |
5 | 6 | 7 | 8 | 9 | 10 | 11 |
6 | 7 | 8 | 9 | 10 | 11 | 12 |
例如,(1,3)=4;(2,2)=4;(3,1)=4;
这样我们就解决了一条对角线,开一个”bool xian[30];”用x+y的值表示数组下标。
例如,我们在(4,5)放置了皇后,那么就让”xian[9]=true;”
另一条对角线怎么办呢?
我们似乎无法从表中得出什么规律了,但我们可以为每一条↘对角线标上一个序号。
将最长的那条标为1,然后以横行为起点的线依次标为2,3,4… ,以竖列为起点的依次标为2+n,3+n,4+n…
突然发现,以横行为起点的标号就是x-y+2啊。
get√
贴码
#include<cstdio> #include<iostream> #include<cstring> #include<string> #include<cstdlib> #include<cmath> using namespace std; const int maxn=15; int m,n,k,tot,ans,day,year; int a[maxn]; bool hang[maxn],lie[maxn],xian[maxn<<2],xian2[maxn<<2]; void f(int k) { if(k==n) { ans++; /*if(tot<3) { for(int i=1;i<=n;i++) printf("%d ",a[i]);这一段是过洛谷P1219加的代码。 puts(""); } tot++;*/ return; } for(int i=1;;i++) 4000 { if(hang[i]==false) { hang[i]=true; for(int j=1;j<=n;j++) { if(lie[j]==false&&xian[i+j]==false) { bool mmp=false;int ll; if(j>=i) { ll=j-i+2; if(xian2[ll]==false) { xian2[ll]=true; mmp=true; } } else { ll=i-j+n+1; if(xian2[ll]==false) { xian2[ll]=true; mmp=true; } } if(mmp) { lie[j]=true;xian[i+j]=true; //printf("%d,%d\n",i,j);//调试时这样写其实很方便 a[k+1]=j;//P1219 f(k+1); lie[j]=false;xian[i+j]=false; xian2[ll]=false; } } } hang[i]=false; break;//这一句可以让你的DFS快N倍 } } return; } int main() { scanf("%d",&n); f(0);//从一个皇后都没有放开始搜 printf("%d",ans); return 0; }
然而我们无论我们怎样优化,也没法做到十五皇后不超时QAQ
相关文章推荐
- 深度优先搜索 之 CODE[VS] 1295 N皇后问题
- codevs1295 N皇后问题 解题报告
- Code[VS] 1295 Nqueens N皇后问题
- 【codevs1295】 N皇后问题
- Codevs P1295 N皇后问题
- 【codevs1295 N皇后问题(不输出方案)】回溯法
- 从零开始的暴搜复习生活—DFS(CODE[VS] 1116 四色问题 1294 全排列 1295 N皇后问题)
- CODE[VS] 1295 N皇后问题
- 【题解】 状态压缩 CSYZOJ 1040 || codevs 1295 || hdu 2553 N皇后问题
- CODE[VS] 1295 N皇后问题
- 【题解】 状态压缩 CSYZOJ 1040 || codevs 1295 || hdu 2553 N皇后问题
- CODE[VS] 1295 N皇后问题
- 【DFS】CODE[VS] 1295 N皇后问题(刷题记录)
- code【vs】1295 N皇后问题(dfs(回溯))
- CodeVS 1295 N皇后问题 题解
- 【codevs1295 N皇后问题(不输出方案)】回溯法
- [CODEVS1295]N皇后(位运算+搜索)
- codevs1295N皇后问题
- CODEVS 1295N皇后问题
- codevs N皇后问题 回溯法