N皇后问题—初级回溯

N皇后问题,最基础的回溯问题之一,题意简单N*N的正方形格子上放置N个皇后,任意两个皇后不能出现在同一条直线或者斜线上,求不同N对应的解。

提要:N>13时,数量庞大,初级回溯只能保证在N<=13的情况下快速得出答案,重点是数组cur[],表示的是第几行上放的皇后在第几列上,比如cur[1]=2;

表示第一行中的皇后已经放置,且在第一行的第二列上、然后用两个函数判断是否共线、下面是代码...

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cstring>
using namespace std;
int cur[16];
int real(int i,int j)//求i-j的绝对值
{
    if (i>j) return i-j;
    else return j-i;
}
int buzaitongyiahang(int i,int j) // 判断不在同一行
{
    for (int k=1; k<i; k++)
        if (cur[k]==j) return 0;
    return 1;
}
int notxie(int i,int j)    //判断不在一条斜线上
{
    for (int k=1; k<i; k++)
        if (real(i,k)==real(j,cur[k])) return 0;
    return 1;
}
int putque(int n,int i)
{
    int ans=0;
    int j;
    if (i==1)
    {
        for (j=1; j<=n; j++)
        {
            cur[i]=j;
            ans+=putque(n,2);
            cur[i]=-1;
        }
    }
    else if (i==n)
    {
        for (j=1; j<=n; j++)
            if (putque(i,j)&&notxie(i,j))
            {
                cur[i]=j;
                return 1;
            }
    }
    else
    {
        for (j=1; j<=n; j++)
            if (buzaitongyiahang(i,j)&&notxie(i,j))
            {
                cur[i]=j;
                ans+=putque(n,i+1);
                cur[i]=3276;
            }
    }
    return ans;
}

void work(int n)
{
    for (int k=1;k<=15;k++) cur[k]=-1;
    printf("%d\n",putque(n,1));
}
int main()
{
    int T,N;
    scanf("%d",&T);
    while (T--)
    {
        scanf("%d",&N);
        if (N==1) printf("1\n");
        else  work(N);
    }
    return 0;
}

时间: 2024-11-06 12:59:04

N皇后问题—初级回溯的相关文章

HDU 2553 N皇后问题 --- 经典回溯

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2553 DFS+回溯 /* HDU 2553 N皇后问题 --- 经典回溯 */ #include <cstdio> #include <cstring> const int maxn = 15; int cnt, n; bool visit[3][maxn*2];//3个数组分别标记列,y+x斜线,y-x斜线是否冲突 注意要*2 /* 从第r行开始满足条件地放置皇后 r表示行(从0开

八皇后问题(回溯法&amp;枚举法)

作者 : 卿笃军 本文讨论了八皇后问题的三种解决方案: 一.枚举法 二.回溯法(递归版) 三.回溯法(非递归版) 本来这些代码是以前编写好的,没有发表,由于最近又学习到了八皇后问题,自己整理了一下发表了出来! 首先.说明一下何为八皇后问题,我也不去谷歌了,直接简单的说明一下: 八皇后问题,就是在一个8*8的平面棋盘上,要求你摆放8个棋子,要求:这8个棋子不能有2个在同一行,也不能有2个在同一列,同时一条斜线上面也不能有2个~~~~ 比如:4*4的棋盘,你可以这样摆放(4皇后问题): 以上图为参照

八皇后问题的回溯和递归方法

1.回溯法 用一维数组记录皇后的位置.数组的下标代表皇后所处的行,下标对应的值代表皇后所处的列.用count记录皇后的个数,当count小于queen数时,在循环体中寻找合适位置的queen.寻找queen:从列1依次寻找,满足条件则count+1,继续从列1处寻找下一个queen.如全部找完没找到合适的位置,则count-1,从第count个皇后所在列的下一位置开始继续循环. public class Queen { public void queenInstance(int num ) {

八皇后问题——递归+回溯法

八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例.该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行.同一列或同一斜线上,问有多少种摆法. 高斯认为有76种方案.1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果. 求解过程: 采用遍历的办法,就是采用将每种情况都验证的办法最终找出问题的解,但是蛮力遍历的话,需要遍历的数据量太大,计算时间花费太大,所以在遍历

【八皇后问题】 回溯算法

回溯算法:回溯算法实际上是一个类似枚举的搜索尝试方法,它的思想是在搜索尝试中寻找问题的解,当发现不满足求解条件时,就“回溯”返回,尝试别的路径.之前介绍的基础算法中的贪婪算法,动态规划等都具有“无后效性”,也就是在分段处理问题时,某状态一旦确定,将不再改变.而多数问题很难找到"无后效性”的阶段划分和相应决策,而是通过深入搜索尝试和回溯操作完成的. 八皇后问题:8*8的国际象棋棋盘中放八个皇后,是任意两个皇后不能互相吃掉.规则:皇后能吃掉同一行,同一列,同一对角线的任意棋子. 模型建立:不妨设八个

蓝桥杯 算法提高 8皇后&#183;改 -- DFS 回溯

  算法提高 8皇后·改   时间限制:1.0s   内存限制:256.0MB 问题描述 规则同8皇后问题,但是棋盘上每格都有一个数字,要求八皇后所在格子数字之和最大. 输入格式 一个8*8的棋盘. 输出格式 所能得到的最大数字和 样例输入 1 2 3 4 5 6 7 89 10 11 12 13 14 15 1617 18 19 20 21 22 23 2425 26 27 28 29 30 31 3233 34 35 36 37 38 39 4041 42 43 44 45 46 47 48

数据结构应用案例——栈结构用于8皇后问题的回溯求解

[说明]本文来自由周世平老师主编的<C语言程序设计>教材.我作为参编人员执笔了第7.8章."第8章 问题求解与算法"中"8.6.1 回溯法"以8皇后问题的求解为例,介绍了回溯法的解题过程.这个解决方案中用到了"栈",引用至此,作为栈应用的例子.需要说明的是,教材面向程序设计初学者,并全文中并未提出过任何关于"栈"的描述.这样做,隐藏了术语,减少初学者的认知难度.对于数据结构的学习者而言,由于知识面的扩大,却用不着回

八皇后问题(回溯)

public class Queen {          int QUEEN_COUNT = 8;    //随便你定义几个皇后了,你可以循环产生a个到b个皇后的解     static final int EMPTY = 0;  //如果count[x][y] == EMPTY ,则可以放置皇后:反之,其正上方或斜上方必己放置皇后     int[][] count = new int[QUEEN_COUNT][QUEEN_COUNT]; //     int[] QueenIndex = 

N皇后问题--递归回溯

著名的N皇后问题,就是先按照行一行一行的找,先找第一行,第一行找到一列能满足条件,继续找下一行,如果下一行也找到一列能满足条件,继续找下一行,一次类推,最终找到解, 但是,如果找不到的话, 就说明上一行放的位置错误, 所以回溯到上一行中,继续找下一列,如果找不到,继续回溯,大体就是这么执行找到解的. 下面是代码: 1 #include <stdio.h> 2 3 const int MAX = 30; 4 int n; 5 int a[MAX];//保存当前列值 6 int vis1[MAX]