八皇后问题

八皇后问题

流过昼夜 提交于 2020-03-26 02:23:55
八皇后问题 8 x 8的棋盘上保证每一行、每一列和两个斜列上只有一个皇后。 递归分析 程序结构: 初始化 循环八次: 放置一个皇后 若满足防止条件则放置皇后 若不满足则回退,增加一步再放置 直到放置到最后一个皇后 自相似的关系提取 过程: 找到N个皇后的适合位置 划分: 找到第N-1个皇后合适的位置 找到第N个皇后的位置 递归终止条件 找到最后一个皇后的位置 算法流程 Step1: 数据初始化 Step2: 从col列开始摆放第n个皇后,挨个测试列是否可行,需要先测试当前位置是否安全: 若安全,摆放第n个皇后,并且宣布占领(横竖撇捺都要占领) 若未测试完所有的的行 递归测试下一行 n = N-1 时打印结果 如果当n >= N-1时说明无法摆放或摆放完毕时需要回溯 Step3: 输出结果 数据结构 place:int数组【0....7】 第n行皇后所占位置的列号 主要用于输出结果 flag:bool数组【0....7】 表示col列上能放置皇后 d1:bool数组【0....14】 (n,col)所在上对角线上是否可以放置皇后 (n-col+7)(保证为正) d2:bool数组【0....14】 (n,col)所在下对角线上是否可以放置皇后(n+col) 程序思路 是否能放置 flag[col] and d1[n-col+1] and d2[n+col] 放置皇后 place[n]

利用回溯法解决八皇后问题(循环)

独自空忆成欢 提交于 2020-03-17 08:02:45
利用回溯法解决八皇后问题(循环) 2.用循环解决 # include <stdio.h> # include <stdlib.h> int a [ 20 ] , n , sum ; void output ( ) //输出 { int i , j ; for ( i = 1 ; i <= n ; i ++ ) { for ( j = 1 ; j <= n ; j ++ ) { if ( a [ i ] == j ) printf ( " Q" ) ; else printf ( " *" ) ; } printf ( "\n" ) ; } printf ( "\n" ) ; } int check ( int k ) //检查当前位置是否可放 { int i ; for ( i = 1 ; i <= k - 1 ; i ++ ) //abs(a[i] - a[k])==abs(i - k))用于判断当前位置是否在前面任一皇后的左下斜线或右下斜线方向 //(a[i]==a[k])用于判断当前位置是否在前面任一皇后的正下方 if ( ( abs ( a [ i ] - a [ k ] ) == abs ( i - k ) ) || ( a [ i ] == a [ k ] ) ) return 0 ; //不可以放 return 1 ; //可以放 } void backdate (

八皇后问题(dfs)

与世无争的帅哥 提交于 2020-03-08 02:43:25
八皇后问题,是一个古老而著名的问题,是搜索算法的经典案例。该问题是国际西洋棋棋手马克思贝瑟尔于1848年提出:在8*8格的国际象棋上摆放八个皇后。使其不能相互攻击,即任意两个皇后都不能处于同一行、同一列或者同一斜线,问有多少中摆法。 分析:用dfs一行一行得进行摆放,用for循环来确定每一列,由于是一行一行得摆放所以不可能同行,我们只需要标记同列,同对角线,就行,会发现主对角线一条对角线上的行列和等于同一个常数,副对角线一条对角线行列差等于一个常数,只不过会是负数,防止下标是负数我们可以进行+8,保证是一个正数,利用这个性质来确定有没有同行同列 # include <iostream> using namespace std ; bool v [ 10 ] , tx [ 20 ] , ty [ 20 ] ; //表示这一列,主对角线,负对角线有没有皇后 int cnt = 0 ; bool check ( int x , int y ) { return ! v [ y ] && ! tx [ x + y ] && ! ty [ x - y + 8 ] ; //+8防止产生负数 void dfs ( int x ) { if ( x == 8 ) { //找到了一种摆法 cnt ++ ; return ; } for ( int i = 0 ; i < 8 ; i ++ ) {

八皇后问题 java

╄→гoц情女王★ 提交于 2020-03-01 21:17:06
在棋盘上放置8个皇后,使他们互不攻击,此时每个皇后的 攻击范围为 同行 同列 同对角线 要求找出所有解 恰好每行每列放置一个皇后 如果用C[x]表示第x行皇后的列号,就成为了一个全排列问题 static int ans ; static int n ; static int [ ] C ; public static void main ( String [ ] args ) { Scanner sc = new Scanner ( System . in ) ; n = sc . nextInt ( ) ; C = new int [ n ] ; f ( 0 ) ; System . out . println ( ans ) ; } static void f ( int cur ) { if ( cur == n ) ans ++ ; else for ( int i = 0 ; i < n ; i ++ ) { int ok = 1 ; C [ cur ] = i ; for ( int j = 0 ; j < cur ; j ++ ) { //检查是否和前面的皇后冲突 //判断是否跟前面的皇后在同一列或者对角线 // 因为数组下标就是行号,所以不会在同一行 if ( C [ cur ] == C [ j ] || cur + C [ cur ] == j + C [ j

八皇后

允我心安 提交于 2020-03-01 11:48:54
描述 会下国际象棋的人都很清楚:皇后可以在横、竖、斜线上不限步数地吃掉其他棋子。如何将8个皇后放在棋盘上(有8 × 8个方格),使它们谁也不能被吃掉!这就是著名的八皇后问题。 对于某个满足要求的8皇后的摆放方法,定义一个皇后串a与之对应,即a=b1b2...b8,其中bi为相应摆法中第i行皇后所处的列数。已经知道8皇后问题一共有92组解(即92个不同的皇后串)。 给出一个数b,要求输出第b个串。串的比较是这样的:皇后串x置于皇后串y之前,当且仅当将x视为整数时比y小。 格式 输入格式 第1行是测试数据的组数n,后面跟着n行输入。每组测试数据占1行,包括一个正整数b(1≤b≤92)。 输出格式 输出有n行,每行输出对应一个输入。输出应是一个正整数,是对应于b的皇后串。 样例 输入样例 2 1 92 输出样例 15863724 84136275 利用深搜的思路写 #include <iostream> #include <stdio.h> #include <string.h> #include <stdio.h> #include <algorithm> using namespace std; int map[9][9]; int ans[1000][9]; int cnt; void initMap(){ for(int i=1; i<=8; ++i){ for(int j=1;

八皇后问题递归Java实现

冷暖自知 提交于 2020-02-27 18:41:07
八皇后问题递归java实现 八皇后问题是指将八个皇后放置在8*8的国际棋盘上,使其两两之间不处于同一行同一列和同一斜线上。 递归解体思路为: 首先n=0,i=0,代表初始在第0行第0列放置第1个皇后 如果n=8,则八个皇后已经放完,输出当前的结果,并返回 在第 n 行第 i 列放置第 n+1 个皇后(同一个n) 判断该皇后是否与之前的所有皇后冲突,若冲突则列数 i + 1 重复进行第4步,若不冲突则n+1,重复进行第二步 存在问题:使用递归,算法效率低 具体实现代码如下: public class EightQueens { /* * arr[n]=i 表示第i个皇后放在棋盘的第n行,第i列 * max代表皇后的个数8 * times记录解法个数 * */ static int [ ] arr = new int [ 8 ] ; static int max = 8 ; static int times = 0 ; public static void main ( String [ ] args ) { check ( 0 ) ; } /* * check递归进行皇后的放置参数n代表放置第n个皇后 */ private static void check ( int n ) { //因为索引从0开始,所以n==max时表示八个皇后都放置完成,次数加一并打印当前的结果 if ( n

搜索练习题八皇后

不羁的心 提交于 2020-02-26 18:06:47
题目链接: http://ybt.ssoier.cn:8088/problem_show.php?pid=1214 题目描述: 会下国际象棋的人都很清楚:皇后可以在横、竖、斜线上不限步数地吃掉其他棋子。如何将8个皇后放在棋盘上(有8 × 8个方格),使它们谁也不能被吃掉!这就是著名的八皇后问题。 对于某个满足要求的8皇后的摆放方法,定义一个皇后串a与之对应,即 a = b 1 b 2 . . . b 8 a=b1b2...b8,其中bi为相应摆法中第i行皇后所处的列数。已经知道8皇后问题一共有92组解(即92个不同的皇后串)。 给出一个数b,要求输出第b个串。串的比较是这样的:皇后串x置于皇后串y之前,当且仅当将x视为整数时比y小。 【输入】 第1行是测试数据的组数n,后面跟着n行输入。每组测试数据占1行,包括一个正整数b(1≤b≤92)。 【输出】 输出有n行,每行输出对应一个输入。输出应是一个正整数,是对应于b的皇后串。 【输入样例】 2 1 92 【输出样例】 15863724 84136275 1 #include <bits/stdc++.h> 2 using namespace std; 3 int q[92][8],row[8],num=0; //92组皇后 4 void queen(int i){ 5 int j,k; 6 if(i==8){ //一组新的解产生了

算法与数据结构学习(18)-递归(3)八皇后问题

强颜欢笑 提交于 2020-02-25 20:24:37
八皇后问题介绍 八皇后问题是一个经典而又古老的问题,是回溯算法的经典案例。该问题是西洋棋手马克斯·贝斯尔于1848年提出,在8x8个格的国际象棋上摆放八个皇后,使其不能互相攻击,即:** 任意两个皇后都不能处于同一行或者同一条斜线上,问总共有多少种摆法? 八皇后问题算法思路分析 第一个皇后先放第一行第一列 第二个皇后放在第二行第一列、然后判断是否OK[即判断是冲突], 如果不OK,继续放在第二列、第三列、依次把所有列都放完,找到一个合适 继续第三个皇后,还是第一列、第二列……直到第8个皇后也能放在一个不冲突的位置,算是找到了一个正确解 当得到一个正确解时,在栈回退到上一个栈时,就会开始回溯,即将第一个皇后,放到第一列的所有正确解,全部得到. 然后回头继续第一个皇后放第二列,后面继续循环执行 1,2,3,4的步骤 说明:理论上应该创建一个二维数组来表示棋盘,但是实际上可以通过算法,用一个一维数组即可解决问题. arr[8] = {0 , 4, 7, 5, 2, 6, 1, 3} //对应arr 下标 表示第几行,即第几个皇后,arr[i] = val , val 表示第i+1个皇后,放在第i+1行的第val+1列 代码实现 package recursion ; public class Queue8 { //定义一个max表示有多少个皇后 int max = 8 ; /

八皇后问题概述

两盒软妹~` 提交于 2020-02-18 22:22:01
八皇后问题是数学史上具有重要地位的问题之一,可以与汉诺塔问题、马走日问题平起平坐。喜欢国际象棋的人一定知道,在8*8的棋盘里,皇后所在的行、列和斜线上不能放棋子,也就是说行、列和斜线是皇后的攻击范围。八皇后问题的主要内容是,在8*8的棋盘上摆放8个皇后,让他们不能相互吃掉。也就是说,每行、每列、每条斜线上至多有一个皇后棋子。实际上,每行、每列上都会有一个皇后棋子。 1.生成所有符合条件的情况。“1”代表皇后,“0”代表空位。(一本通题库1213) 在这里我只提供一个思路。设计出来的程序不知为何无法通过(所以不要妄想白嫖了),但是它的确形成了所有的可能情况。 看了大佬们的讲解,里面有各种取余、加减等运算,竟然都是在数组下表里完成,比如"a[y-x%10+1]=b[x+y-1]“这样很复杂的表达式。毕竟我的智商不够,只能像狗走直线拣骨头一样,用最简单的思路。 请读者们想想,人类解决这样的问题,最直接的方法是什么? 如果你的脑回路和常人差不多的话,回答大概是:“列出所有的可能情况,再一个个排除!”或者是“一行(或一列)摆一个,判断符不符合条件!” 于是,大体的思路出来了。用搜索枚举所有情况,遇到不可行的情况就跳过! 首先,先写出检验一个点(x,y)是否能放棋子的函数: bool a[100][100];//棋盘 int now=1;//当前方案 bool isOK(int x,int y

问题 D: 八皇后

旧街凉风 提交于 2020-02-15 23:55:41
#include <cstdio> #include <vector> #include <algorithm> using namespace std; const int N = 8; vector<long> s; bool flag[N] = {false}; int a[N]; void help(int index) { if (index == N + 1) { for (int j = 1; j <= N; ++j) { for (int i = j + 1; i <= N; ++i) { if (abs(i - j) == abs(a[i] - a[j])) return; } } long temp = 0; for (int i = 1; i <= N; ++i) { temp = temp * 10 + a[i]; } s.push_back(temp); } for (int i = 1; i <= N; ++i) { if (!flag[i]) { flag[i] = true; a[index] = i; help(index + 1); flag[i] = false; } } } int main() { help(1); sort(s.begin(), s.end()); int n; while (scanf(" %d", &n) != EOF