【搜索】八皇后

  这道题应该不陌生吧,这是一道很经典的搜索题。

  总的意思就是说在一个n*n的棋盘上放n个皇后,要求它们互不攻击,求解有多少种情况,并输出前三种。

  那么开始分析:这毕竟是一道搜索题,搜索最大的弊端是什么,当然是时间复杂度极高,虽然这道题可能不会那么卡,我们完全可以开一个二维数组,然后不停标记不能放的位置。但是你是否想过,一维数组+极少的时间复杂度就可以解决问题。

  那么具体说一下该怎么放棋子,我们不需要全局的考虑,因为深搜最大的好处是可以简化繁琐的过程,因此我们先考虑只摆一枚棋子,首先假设已经摆好了,那么要进行怎样的操作。

  

  如图,比方说现在在第二行第二列的位置上放了一个皇后,那么有哪些点永远不能放棋子呢?

  

如图,所有红色的格子(包括这个皇后所在的格子)都不能放置皇后了,乍一看,也看不出来什么规律,别着急,把整个图都以二维数组下标的形式标上序号就一目了然了。

  

  按照国际象棋的规则,皇后所能控制的是它所在的行,列,左上到右下的对角线,右上到左下的对角线。那么我们分开看:

  1)行:如果你够细心,就会发现一行的左边的下标的值都相等,那么我们是不是就可以定义一个一维数组hang(用拼音更好区分),用来存储每行是否被哪一个皇后所霸占,初始赋成0,如果被霸占后,就赋为1,比如说我们要判断(2,4)是否可以放棋子,调用这个数组hang[2]即可知道这一行已经被霸占,所以不能放置。

  2)列:同上,我们仍然可以定义一个数组用来存储是否被霸占,只需注意所有数是纵坐标相同,和行稍有不同。

  3)左上到右下的对角线:这当然是一大难点,我们可以通过坐标发现规律,(1,1),(2,2),(3,3),(4,4)都是图上皇后左上到右下所能控制的点,有没有发现这一列的点的横纵坐标差值相同,简单说就是1-1=2-2=3-3=4-4,(不一定非等于零,随着这个皇后位置的改变,差值是会改变的),所以和上文一样,我们定义一个数组duijiaoxian2,如果要判断(i,j)是否能摆放皇后,只需判断duijiaoxian2[i-j]是否等于1即可。

  4)右上到左下的对角线:同上,只不过是横纵坐标的和相同需要注意就可以了。

  上文是摆棋时的判断,在摆完每一颗棋后要记得把四个数组相应数值改为1即可。

  这样,代码就出来了:

 1 #include<iostream>
 2 using namespace std;
 3 int hang[1000],lie[1000],duijiaoxian1[1000],duijiaoxian2[1000],n,lujin[1000],ans,cnt;
 4 void dfs(int x)
 5 {
 6     if(x>n)
 7     {
 8         ans++;
 9         if(ans<=3)
10         {
11             for(int i=1;i<=n;i++)
12             cout<<lujin[i]<<" ";
13             cout<<endl;
14         }
15         return;
16     }
17     for(int i=1;i<=n;i++)
18     {
19         if(lie[i]==0&&duijiaoxian1[i+x]==0&&duijiaoxian2[i-x]==0)
20         {
21             lie[i]=1;duijiaoxian1[i+x]=1;duijiaoxian2[i-x]=1;
22             cnt++;lujin[cnt]=i;
23             dfs(x+1);
24             cnt--;
25             lie[i]=0;duijiaoxian1[i+x]=0;duijiaoxian2[i-x]=0;//要记得回溯
26         }
27     }
28 }
29 int main()
30 {
31     cin>>n;
32     dfs(1);
33     cout<<ans;
34     return 0;
35 }

  小编的数组起名都是按拼音起的,便于理解,就不在过多解释了。

原文地址:https://www.cnblogs.com/TFLS-gzr/p/10657167.html

时间: 2024-10-19 09:19:39

【搜索】八皇后的相关文章

第五第六课------递推+记忆话搜索+搜索八皇后(思想是做梦)+各种剪枝思想

搜索是一个漫长的过程贯彻整个oi: 八皇后------- #include <bits/stdc++.h>#define inf 0x7fusing namespace std;int n,ans,a[inf],b[inf],c[inf],d[inf];void print(){ ++ans; if(ans<=3){ for(int i=1;i<=n;i++) cout<<d[i]<<" "; cout<<endl; }} v

深度优先搜索——八皇后问题

代码:(控制台打印不了92种情况,只打印前10种) 1 #include<iostream> 2 #include<string> 3 #include<windows.h> 4 #define ok 1 5 #define error 0 6 using namespace std; 7 8 9 int a[9][9]={0}; 10 int num=0; 11 12 int Ifblock(int x,int y) //判断有没有产生冲突 13 { 14 int i

每日一题17:八皇后问题

八皇后问题是由国际西洋棋棋手马克斯·贝瑟尔于1848年提出的:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行.同一列或同一斜线上,问有多少种摆法. 高斯认为有76种方案.1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果.解题的思路如下:从棋盘的第一行起,先选择第一个格子作为第一个皇后的位置,然后在第二行中从第一个格子开始试探一个合适的位置放置第二个皇后,接下来在第三行从第一个格子开始试探一个合适的位置放置第三个皇

kb-01-a&lt;简单搜索--dfs八皇后问题变种&gt;

题目描述: 在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别.要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案C. Input 输入含有多组测试数据. 每组数据的第一行是两个正整数,n k,用一个空格隔开,表示了将在一个n*n的矩阵内描述棋盘,以及摆放棋子的数目. n <= 8 , k <= n 当为-1 -1时表示输入结束. 随后的n行描述了棋盘的形状:每行有n个字符,其中 # 表示棋盘区域,

搜索6--noi1700:八皇后问题

搜索6--noi1700:八皇后问题 一.心得 二.题目 1756:八皇后 查看 提交 统计 提问 总时间限制:  1000ms 内存限制:  65536kB 描述 会下国际象棋的人都很清楚:皇后可以在横.竖.斜线上不限步数地吃掉其他棋子.如何将8个皇后放在棋盘上(有8 * 8个方格),使它们谁也不能被吃掉!这就是著名的八皇后问题. 对于某个满足要求的8皇后的摆放方法,定义一个皇后串a与之对应,即a=b1b2...b8,其中bi为相应摆法中第i行皇后所处的列数.已经知道8皇后问题一共有92组解(

搜索5--noi1700:八皇后问题

搜索5--noi1700:八皇后问题 一.心得 二.题目 1700:八皇后问题 查看 提交 统计 提问 总时间限制:  10000ms 内存限制:  65536kB 描述 在国际象棋棋盘上放置八个皇后,要求每两个皇后之间不能直接吃掉对方. 输入 无输入. 输出 按给定顺序和格式输出所有八皇后问题的解(见Sample Output). 样例输入 样例输出 No. 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0

洛谷 P1219 八皇后【经典DFS,温习搜索】

P1219 八皇后 题目描述 检查一个如下的6 x 6的跳棋棋盘,有六个棋子被放置在棋盘上,使得每行.每列有且只有一个,每条对角线(包括两条主对角线的所有平行线)上至多有一个棋子. 上面的布局可以用序列2 4 6 1 3 5来描述,第i个数字表示在第i行的相应位置有一个棋子,如下: 行号 1 2 3 4 5 6 列号 2 4 6 1 3 5 这只是跳棋放置的一个解.请编一个程序找出所有跳棋放置的解.并把它们以上面的序列方法输出.解按字典顺序排列.请输出前3个解.最后一行是解的总个数. //以下的

深度搜索(dfs)+典型例题(八皇后)

深度优先搜索简称深搜,从起点出发,走过的点要做标记,发现有没走过的点,就随意挑一个往前走,走不了就回退,此种路径搜索策略就称为“深度优先搜索”,简称“深搜”. 如上面的图所示:加入我们要找一个从V0到V6的一条最短的路径.我们可以看到有许多的路我们可以走. V0——V3——V5——V6: V0——V3——V1——V4: V0——V3——V1——V2——V6: V0——V1——V4: V0——V1——V3——V5——V6: V0——V1——V2——V6: V0——V2——V6: 前两组,是从节点V

搜索入门练习题5 八皇后问题 题解

题目来源:<信息学奥赛一本通>例5.4 题目描述 要在国际象棋棋盘(\(8 \times 8\) 的棋盘)中放 \(8\) 个皇后,使任意两个皇后都不能互相吃.(提示:皇后能吃同一行.同一列.同一对角线的任意棋子.) 输出格式 输出一个整数,用于表示八皇后问题的放置方案. 题目分析 首先我们用 \((x,y)\) 来表示棋盘上第 \(x\) 行第 \(y\) 列的格子的坐标. 那么,两个皇后 \((x_1,y_1)\) 和 \((x_2,y_2)\) 会互相攻击当且仅当满足如下条件之一: 在同

poj1321--棋盘问题(搜索练习2,变形的八皇后问题)

棋盘问题 Time Limit:1000MS     Memory Limit:10000KB     64bit IO Format:%I64d & %I64u Submit Status Appoint description:  System Crawler  (2013-07-31) Description 在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别.要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有