一天课下,张老板研究起了国际象棋,渴望完美的他更改了棋盘的大小,在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. vsftpd设置被动模式

    完整配置 listen=yes listen_port= max_clients= max_per_ip= local_max_rate= anonymous_enable=no local_enab ...

  2. babel-preset-latest使用介绍

    本文介绍babel中的babel-preset-latest插件 简介 该插件的作用是包含了每年的js代码转换规则 默认包含es2015,es2016,es2017,默认对这些代码都会进行转码,从而方 ...

  3. Python Twisted系列教程13:使用Deferred新功能实现新客户端

    作者:dave@http://krondo.com/deferred-all-the-way-down/  译者:杨晓伟(采用意译) 你可以从这里从头阅读这个系列. 介绍 回忆下第10部分中的客户端5 ...

  4. JS播放声音 兼容所有浏览器

    JS播放声音 兼容所有浏览器 <!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.0//EN" "http ...

  5. IDE 文件查找快捷键被占

    快捷键 Ctrl+Shift+F 被搜狗输入法抢占了. 打开搜狗输入法里的快捷键设置,去掉,my ide is ok!

  6. 17-EasyNetQ:非泛型的发布&订阅扩展方法

    自从EasyNetQ第一个版本开始,它就可以发布/订阅特定类型的消息. bus.Subscribe<MyMessage>("subscriptionId", x =&g ...

  7. C++风格与C风格文件读写效率测试-vs2015,vs2017

    void test_write() { ; const char* c_plus_write_file = "H://c_plus_write_file.txt"; const c ...

  8. 值得一做》关于并查集的进化题目 BZOJ1015(BZOJ第一页计划)(normal-)

    这道题和以前做过的一道经典的洪水冲桥问题很像,主要做法是逆向思维.(BZOJ第10道非SB题纪念) 先给出题目 Description 很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治者 ...

  9. 2014蓝桥杯B组初赛试题《啤酒和饮料》

    题目描述: 啤酒每罐2.3元,饮料每罐1.9元.小明买了若干啤酒和饮料,一共花了82.3元.     我们还知道他买的啤酒比饮料的数量少,请你计算他买了几罐啤酒.     注意:答案是一个整数.请通过 ...

  10. js数值和字符串比较的规则

    1.数值和字符串比较时 a.若字符串为数字字符串,则将字符串转为数字,再比较 b.若字符串不为数字字符串,则直接返回false,因为这里把字符串转为了NaN, 数字与NaN比较,都返回false