一天课下,张老板研究起了国际象棋,渴望完美的他更改了棋盘的大小,在N*N的方格棋盘放置了N个皇后,希望它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上) 
张老板把这个艰巨的任务交给了你,对于给定的N,求出有多少种合法的放置方法。

Input共有若干行,每行一个正整数N≤10,表示棋盘和皇后的数量;如果N=0,表示结束。Output共有若干行,每行一个正整数,表示对应输入行的皇后的不同放置数量。Sample Input

1
8
5
0

Sample Output

1
92
10

第一次看到这个题感觉很难,后来通过看视频学会了一种递归算法来解这道问题,想明白后还是很有意思的,不过递归是一种很低效的算法,提交的时候TEL了,正确的解法应该是用回溯算法,以后有时间再理解

递归算法(低效)

#include<stdio.h>
#include<string.h> int count = ;
int t; int notDanger(int row, int j, int (*arr)[])
{
int flag1, flag2, flag3, flag4, flag5;
int i, k; flag1 = flag2 = flag3 = flag4 = flag5 = ; //判断列是不是危险
for( i = ; i < t; i++ )
{
if(arr[i][j] == )
{
flag1 = ;
break;
}
} //判断左上方
for( i = row, k = j; i >= && k >= ; i--, k-- )
{
if(arr[i][k] == )
{
flag2 = ;
break;
}
} //判断左下方
for( i = row, k = j; i < t && k >= ; i++, k-- )
{
if(arr[i][k] == )
{
flag3 = ;
break;
}
} //判断右上方
for( i = row, k = j; i >= && k < t; i--, k++ )
{
if(arr[i][k] == )
{
flag4 = ;
break;
}
} //判断右下方
for( i = row, k = j; i < t && k < t; i++, k++ )
{
if(arr[i][k] == )
{
flag5 = ;
break;
}
} if(flag1 == || flag2 == || flag3 == || flag4 == || flag5 == )
return ; else
return ;
} void nQueen(int row, int n, int (*arr)[])
{
int arr2[][], i, j; for( i = ; i < n; i++ )
{
for( j = ; j < n; j++ )
{
arr2[i][j] = arr[i][j];
}
} if(row == n)
count++; else
{
//该位置没有危险
for( j = ; j < n; j++ ) //这一部分代码其实往下会产生很大的容量
{ //有时候自己会在这部分,搞混。
if(notDanger(row, j, arr))
{
for( i = ; i < n; i++ )
{
arr2[row][i] = ;
} arr2[row][j] = ; nQueen(row+, n, arr2);
}
}
}
} int main()
{
int arr[][], i, j; while(scanf("%d", &t) != EOF && t)
{
count = ; for( i = ; i < t; i++ )
{
for( j = ; j < t; j++ )
{
arr[i][j] = ;
}
} nQueen(, t, arr);
if(count == )
printf("None\n");
else
printf("%d\n", count);
} return ;
}

回溯算法

#include<stdio.h>
#include<string.h> int n,tmp;
int map[]; void DFS(int k)
{
int i,j,flag;
if(k==n+)
{
tmp++;
return;
}
else
{
for(i=;i<=n;++i)
{
map[k]=i;
flag=;
for(j=;j<k;++j)
{
if(map[j]==i||i-k==map[j]-j||i+k==map[j]+j) // 注:1、i=map[k] 2、不在同一条斜线的两点的含义是行标到对角线的的距离不相等
{
flag=;
break;
}
}
if(flag)
DFS(k+);
}
}
} int main()
{
int i,m;
int ans[];
for(n=;n<=;++n)
{
tmp=;
DFS();
ans[n]=tmp;
}
while(scanf("%d",&m),m)
{
printf("%d\n",ans[m]);
}
return ;
}

B - N皇后问题的更多相关文章

  1. 递归实现n(经典的8皇后问题)皇后的问题

    问题描述:八皇后问题是一个以国际象棋为背景的问题:如何能够在8×8的国际象棋棋盘上放置八个皇后, 使得任何一个皇后都无法直接吃掉其他的皇后?为了达到此目的,任两个皇后都不能处于同一条横行.纵行或斜线上 ...

  2. 八皇后算法的另一种实现(c#版本)

    八皇后: 八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例.该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于 ...

  3. [LeetCode] N-Queens II N皇后问题之二

    Follow up for N-Queens problem. Now, instead outputting board configurations, return the total numbe ...

  4. [LeetCode] N-Queens N皇后问题

    The n-queens puzzle is the problem of placing n queens on an n×n chessboard such that no two queens ...

  5. N皇后问题—初级回溯

    N皇后问题,最基础的回溯问题之一,题意简单N*N的正方形格子上放置N个皇后,任意两个皇后不能出现在同一条直线或者斜线上,求不同N对应的解. 提要:N>13时,数量庞大,初级回溯只能保证在N< ...

  6. 数据结构0103汉诺塔&八皇后

    主要是从汉诺塔及八皇后问题体会递归算法. 汉诺塔: #include <stdio.h> void move(int n, char x,char y, char z){ if(1==n) ...

  7. N皇后问题

    题目描述 在n×n格的棋盘上放置彼此不受攻击的n个皇后.按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子.n后问题等价于再n×n的棋盘上放置n个后,任何2个皇后不妨在同一行或同 ...

  8. LeetCode:N-Queens I II(n皇后问题)

    N-Queens The n-queens puzzle is the problem of placing n queens on an n×n chessboard such that no tw ...

  9. 八皇后问题_Qt_界面程序实现

    //核心代码如下 //Queen--放置皇后 #include "queue.h" queue::queue() { *; ; this->board = new bool[ ...

  10. 两个NOI题目的启迪8皇后和算24

    论出于什么原因和目的,学习C++已经有一个星期左右,从开始就在做NOI的题目,到现在也没有正式的看<Primer C++>,不过还是受益良多,毕竟C++是一种”低级的高级语言“,而且NOI ...

随机推荐

  1. mybatis 动态sql语句(2)

    什么是动态SQL MyBatis的一个强大特性之一通常是它的动态SQL能力.如果你有使用JDBC或其他相似框架的经验,你就明白条件串联SQL字符串在一起是多么地痛苦,确保不能忘了空格或者在列表的最后的 ...

  2. Oracle 11G的间隔(INTERVAL)分区

    -- Create table create table MS_BIGTABLE_LOG ( record_date DATE, col_1 VARCHAR2(), col_2 VARCHAR2() ...

  3. Py修行路 python基础 (二十一)logging日志模块 json序列化 正则表达式(re)

    一.日志模块 两种配置方式:1.config函数 2.logger #1.config函数 不能输出到屏幕 #2.logger对象 (获取别人的信息,需要两个数据流:文件流和屏幕流需要将数据从两个数据 ...

  4. 第九章 整合Mybatis(待续)

    ··········

  5. Vue 简单的总结一

    let 变量 1. 局部作用域 2. 不会存在变量提升 3. 变量不能重复声明 const 变量 1. 局部作用域 2. 不会存在变量提升 3. 变量不能重复声明 4. 只能声明常量,不可变得量 th ...

  6. delphi 在桌面屏幕上模拟鼠标单击

    delphi 在桌面屏幕上模拟鼠标单击 procedure TFrmUnicom.Button1Click(Sender: TObject); var oldPoint, newPoint: TPoi ...

  7. Coins and Queries(codeforce 1003D)

    Polycarp has nn coins, the value of the i-th coin is aiai . It is guaranteed that all the values are ...

  8. HashMap与ConcurrentHashMap的区别(转)

    从JDK1.2起,就有了HashMap,正如前一篇文章所说,HashMap不是线程安全的,因此多线程操作时需要格外小心. 在JDK1.5中,伟大的Doug Lea给我们带来了concurrent包,从 ...

  9. 分析比较多表查询中的IN与JOIN

    IN 是子查询的关键字,JOIN 是连接的关键字,项目开发中经常会使用到多表查询,而子查询与连接正是实现多表查询的重要途径.那两者是怎么运行的?IN与JOIN哪个更好?下面就来分析与比较. 现在有te ...

  10. 升级到Win10 周年更新版

    尝试过强制刷更新,但是没用,最近微软才跟我的机器推送周年更新,于是更新. 花费了些时间更新,之前网上有的那些诗句,亲眼看看还是蛮有意思的. 但是更新完了后,explorer 一直出错,有闪退(闪屏)一 ...