八皇后问题

八皇后,回溯与递归(Python实现)

柔情痞子 提交于 2019-12-02 15:05:08
八皇后,回溯与递归(Python实现) 八皇后问题是十九世纪著名的数学家高斯1850年提出 。以下为python语言的八皇后代码,摘自《Python基础教程》,代码相对于其他语言,来得短小且一次性可以打印出92种结果。同时可以扩展为九皇后,十皇后问题。 问题:在一个 8*8 棋盘上,每一行放置一个皇后旗子,且它们不冲突。冲突定义:同一列不能有两个皇后,每一个对角线也不能有两个皇后。当然,三个皇后也是不行的,四个也是不行的,凭你的智商应该可以理解吧。 解决方案:回溯与递归。 介绍: 1.回溯法 回溯法是一种选优搜索法,按选优条件向前搜索,以达到目标。当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”。参见 百度百科 2.递归法 阶乘 n! = 1 x 2 x 3 x ... x n 用函数 fact(n) 表示,可以看出: fact(1) = 1 fact(n) = n! = 1 x 2 x 3 x ... x (n-1) x n = (n-1)! x n = fact(n-1) x n 于是, fact(n) 用递归的方式写出来就是: def fact(n): if n==1: return 1 return n * fact(n - 1) 如果计算 fact(5) ,结果如下: ==

dfs--八皇后问题

冷暖自知 提交于 2019-12-02 10:49:59
在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上。 你的任务是,对于给定的N,求出有多少种合法的放置方法。 每次把第k个皇后放在第k行,这样就不用考虑是否在同一行的可能,只需判断每个皇后是否在同一列,一个对角线即可。 最后输出时,多组数据,可能会有包含的情况,压缩时间。 1 #include<iostream> 2 #include<cstdio> 3 int Queen[20],n; 4 int dp[15]; 5 int dfs(int k) 6 { 7 if (k>n) 8 return 1; 9 int ans = 0; 10 for (int i = 1 ;i<= n ;i++) 11 { 12 int nx = k, ny = i;//把第k个皇后放在第k行 13 bool isOk = true; 14 for (int j = 1; j< k && isOk ;j++) 15 { 16 int prex = j, prey = Queen[j];//放过的皇后 17 if (prey == ny || prey-prex == ny-nx || prey + prex == ny + nx)//在同一列、一个对角线 不合法 18 isOk = false; 19 } 20 if

八皇后问题

风流意气都作罢 提交于 2019-12-02 06:44:52
简单的dfs,非最优解,胜在思路清晰 class Solution { int res = 0 ; public int totalNQueens ( int n ) { boolean [ ] [ ] grid = new boolean [ n ] [ n ] ; dfs ( grid , 0 ) ; return res ; } public void dfs ( boolean [ ] [ ] grid , int row ) { if ( row == grid . length ) { ++ res ; return ; } //遍历每一行 for ( int i = 0 ; i < grid . length ; i ++ ) { if ( isValid ( grid , row , i ) ) { grid [ row ] [ i ] = true ; //递归判断下一行 dfs ( grid , row + 1 ) ; grid [ row ] [ i ] = false ; } } } int [ ] [ ] dirs = { { 1 , 0 } , { 1 , 1 } , { 1 , - 1 } , { 0 , - 1 } , { 0 , 1 } , { - 1 , - 1 } , { - 1 , 0 } , { - 1 , 1 } } ; /

八皇后问题

青春壹個敷衍的年華 提交于 2019-12-02 00:48:20
Description 会下国际象棋的人都很清楚:皇后可以在横、竖、斜线上不限步数地吃掉其他棋子。如何将8个皇后放在棋盘上(有8 * 8个方格),使它们谁也不能被吃掉!这就是著名的八皇后问题。 对于某个满足要求的8皇后的摆放方法,定义一个皇后串a与之对应,即a=b1b2...b8,其中bi为相应摆法中第i行皇后所处的列数。已经知道8皇后问题一共有92组解(即92个不同的皇后串)。 给出一个数b,要求输出第b个串。串的比较是这样的:皇后串x置于皇后串y之前,当且仅当将x视为整数时比y小。 Input 第1行是测试数据的组数n,后面跟着n行输入。每组测试数据占1行,包括一个正整数b(1 <= b <= 92) Output 输出有n行,每行输出对应一个输入。输出应是一个正整数,是对应于b的皇后串。 Sample Input 3 6 4 25 Sample Output 25713864 17582463 36824175 1 #include <stdio.h> 2 #include <string.h> 3 #include <iostream> 4 #include <string> 5 #include <math.h> 6 #include <algorithm> 7 #include <vector> 8 #include <stack> 9 #include <queue>

八皇后问题java

不想你离开。 提交于 2019-11-30 09:27:40
八皇后问题java 问题描述 初始化一个8*8的棋盘,总共有8个棋子,都是皇后。 在棋盘上摆放棋子,满足规则: 1.同一行只能有一个棋子; 2.同一列只能有一个棋子; 3.同一条斜线上只能有一个棋子。 解题思路 定义size=8(可灵活更改),int[] (size)。 数组的下标可代表棋子在第几行棋盘上,对应的数组的值代表在第几列。 例如array[0] = 0表示在第一行第一列有一个棋子。 回溯:当第n+1棋子放在哪一列都不符合,则回溯到上一个棋子,改变位置,通过后继续递归下一个棋子。 从而可以得出一共有多少种摆法。 public class Queen8 { //初始化数组,定义一个8为的一维数组 int max = 9; int[] array = new int[max]; static int count = 0; static int judgeCount = 0; public static void main(String[] args) { new Queen8().check(0); System.out.println(count); System.out.println("一共判断了多少此次:"+judgeCount); } public void check(int n) { if (n==max) { print(); return; } for

搜索与回溯算法:八皇后问题

雨燕双飞 提交于 2019-11-29 18:22:22
1213:八皇后问题 时间限制: 1000 ms 内存限制: 65536 KB 提交数: 10320 通过数: 3609 【题目描述】 在国际象棋棋盘上放置八个皇后,要求每两个皇后之间不能直接吃掉对方。 【输入】 (无) 【输出】 按给定顺序和格式输出所有八皇后问题的解(见样例)。 【输入样例】 (无) 【输出样例】 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 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 No. 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 ...以下省略 【来源】 i表示行,a[j]=i,表示第i行的第j个数 #include<iostream> using namespace std; int a[10001],b[10001],w[10001],m[10001],tot = 0; int print() { tot++; cout << "No. " << tot <<

洛谷 P1219 八皇后

六月ゝ 毕业季﹏ 提交于 2019-11-28 19:32:32
这道题感觉没有必要用好几个数组甚至二维数组来做吧……把问题抽象一下,其实不需要显式地模拟棋盘的行列,这样代码也更简洁。 实际上,要满足“每行、每列有且只有一个,每条对角线(包括两条主对角线的所有平行线)上至多有一个棋子”的条件,只需要让 序列任意两个位置上的数字之差不等于其距离之差 。举个例子,假设当前要决定第pos行的棋子所在的列数i,即序列ans[]的第pos个位置的数字为i,那么只要让i与pos之前的每一个位置j上的数字ans[j]满足以下三个条件即可: i != ans[j] i != ans[j] + (pos - j) i != ans[j] - (pos - j) 在搜索函数dfs中,枚举当前pos位置上所有满足上述三个条件的数字i,每找到一个i,就加入ans[]序列中,然后pos增加1,继续向后递归。如果没有找到任何一个i,则回溯至上一个位置。pos的作用就是记录当前搜索到了序列的哪一个位置,即棋盘的哪一行。如果pos等于n了,就说明找到了一个解。 #include <iostream> using namespace std; int n, cnt; // n为棋盘大小,cnt记录解的个数 int ans[15]; // 保存序列的数组 void dfs(int pos) { if (pos > n) return; for (int i = 1; i <= n;

洛谷 P1219 ---- 八皇后

天涯浪子 提交于 2019-11-28 13:40:01
题目描述 检查一个如下的6 x 6的跳棋棋盘,有六个棋子被放置在棋盘上,使得每行、每列有且只有一个,每条对角线(包括两条主对角线的所有平行线)上至多有一个棋子。 上面的布局可以用序列2 4 6 1 3 5来描述,第i个数字表示在第i行的相应位置有一个棋子,如下: 行号 1 2 3 4 5 6 列号 2 4 6 1 3 5 这只是跳棋放置的一个解。请编一个程序找出所有跳棋放置的解。并把它们以上面的序列方法输出。解按字典顺序排列。请输出前3个解。最后一行是解的总个数。 //以下的话来自usaco官方,不代表洛谷观点 特别注意: 对于更大的N(棋盘大小N x N)你的程序应当改进得更有效。不要事先计算出所有解然后只输出(或是找到一个关于它的公式),这是作弊。如果你坚持作弊,那么你登陆USACO Training的帐号删除并且不能参加USACO的任何竞赛。我警告过你了! 输入输出格式 输入格式: 一个数字N (6 <= N <= 13) 表示棋盘是N x N大小的。 输出格式: 前三行为前三个解,每个解的两个数字之间用一个空格隔开。第四行只有一个数字,表示解的总数。 输入输出样例 输入样例#1: 6 输出样例#1: 2 4 6 1 3 5 3 6 2 5 1 4 4 1 5 2 6 3 4 说明 题目翻译来自NOCOW。 USACO Training Section 1.5 解析

R语言-八皇后问题

谁说胖子不能爱 提交于 2019-11-28 11:03:41
老师给我出了个暑期作业:用R语言解决八皇后问题。 八皇后问题:国际象棋棋盘(8×8)上放8个“后”,使8个“后”之间互相不能被进攻。(即:每个“后”所在行、列、两条斜线都没有其它子) 查看网上,大多用C++,没看到用R的。呵呵,看来是不能借鉴了。 第一感觉是,应该不能穷举,否则运行非常慢,在网上看了些介绍,打算用回溯法。 然而水平有限,搞了一天多竟然还没成功写好,总是有很奇怪的bug,唉,怪我对R不熟悉吧。 刚才生气了,干脆来个穷举,看看能运行多久,代码见下,看起来非常笨拙,结果运行2,3秒就完成了。。。还是不了解计算机、不了解R啊。。。 #穷举法 rm(list=ls()) cat(rep("\n", 50)) b1=array(numeric(64),dim=c(8,8)) i=0;j=1:8 for (d1 in j){ D2=setdiff(j,d1) for (d2 in D2){ D3=setdiff(D2,d2) for (d3 in D3){ D4=setdiff(D3,d3) for (d4 in D4){ D5=setdiff(D4,d4) for (d5 in D5){ D6=setdiff(D5,d5) for (d6 in D6){ D7=setdiff(D6,d6) for (d7 in D7){ D8=setdiff(D7,d7) for (d8 in

八皇后问题

孤街浪徒 提交于 2019-11-28 10:12:46
八皇后问题 ,是一个古老而著名的 问题 ,是回溯算法的典型案例。 该 问题 是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在 8 × 8 格的国际象棋上摆放 八 个 皇后 ,使其不能互相攻击,即任意两个 皇后 都不能处于同一行、同一列或同一斜线上,问有多少种摆法。 解法:回溯法 #include<iostream> #include<math.h> using namespace std; int n=8; int total=0; int *c=new int(n);//c[i]==j表示这个皇后处于第i行第j列 bool is_ok(int row){ for(int j=0;j!=row;j++){ //(c[row]-c[j])/(row-j)==1||(c[row]-c[j])/(row-j)==-1 //就是数学上的斜率k=(f(x)-f(x0))/(x-x0) if(c[row]==c[j] || row-c[row]==j-c[j] || row+c[row]==j+c[j])//同列、同副对角线、同主对角线 return false; } return true; } void queen(int row){//按行进行选择八皇后的位置 if(row==n){ total++; } else for(int col=0;col!=n;col++){ c[row]