多种解法解决n皇后问题
多种解法解决n皇后问题
0x1 目的
 深入掌握栈应用的算法和设计
0x2 内容
 编写一个程序exp3-8.cpp求解n皇后问题。
0x3 问题描述
即在n×n的方格棋盘上,放置n个皇后,要求每个皇后不同行、不同列、不同左右对角线。
要求:(1)皇后的个数n由用户输入,其值不能超过20,输出所有的解。(2)采用类似于栈求解迷宫问题的方法。
0x4 递归解法
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <string.h>
#define maxsize 20+7
using namespace std;
int y_pos[maxsize];
int n;
int count=0;
bool judge(int num)
{
    for(int i=0;i<num;i++)
    {
        if(y_pos[i]==y_pos[num] || abs(y_pos[num]-y_pos[i])==num-i)
            return false;
    }
    return true;
}
void show()
{
    printf("\nThe %d number position:\n",count);
    for(int i=0;i<n;i++)
    {
        printf("\t(%d,%d)",i,y_pos[i]);
    }
}
void RecurBack(int num)
{
    if(num==n)
    {
        count++;
        show();
        return;
    }
    for(int i=0;i<n;i++)
    {
        y_pos[num]=i;
        if(judge(num))
        {
            RecurBack(num+1);
        }
    }
}
int main()
{
    printf("input n:\n");
    scanf("%d",&n);
    memset(y_pos,0,sizeof(y_pos));
    RecurBack(0);
    printf("\ncount:%d",count);
    return 0;
}
思路就是: 直接从不同行开始选取,然后判断是否满足条件。思路主要就是以皇后的个数作为行数,然后递归下去,递归出口就是回溯
0x5 全排列解法
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#define maxsize 20+7
using namespace std;
int queen[maxsize];
int n;
int count_=0;
int main()
{
    printf("input n:\n");
    scanf("%d",&n);
    for(int i=0;i<n;i++)
    {
        // Init array
        queen[i]=i;
    }
    do
    {
        /*
        for(int i=0;i<n;i++)
            printf("%d\t",queen[i]);
        printf("\n");
        */
        // generate the permutation of queen
        bool find=true;
        for(int i=0;i<n;i++)
        {
            for(int j=i+1;j<n;j++)
            {
                if(j-i==abs(queen[j]-queen[i]))
                {
                    //cout<< "false!!! " <<endl;
                    find=false;
                    break;
                }
                if(!find)
                    break;
            }
        }
        //printf("\n");
        if(find)
        {
            count_++;
        }
    }while(next_permutation(queen,queen+n));
    printf("count:%d",count_);
    return 0;
}
这个可以来说也很好,都是暴力解法,时间差别主要是在生成全排列的过程,但是这个解法可以利用STL,代码可以说是相当简洁的了。
0x6 用栈解决
 用栈来模拟递归过程,这个是我数据结构的一个作业。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <string.h>
#define MaxSize 100000+7
#define maxsize 20+7
using namespace std;
int path[maxsize][maxsize];
int n;
int y_pos[maxsize];
int count=0;
bool judge(int num)
{
    for(int i=0;i<num;i++)
    {
        if(y_pos[i]==y_pos[num] || abs(y_pos[num]-y_pos[i])==num-i)
            return false;
    }
    return true;
}
typedef struct
{
    int x;
    int y;
    int di;
}Box;
typedef struct
{
    Box data[MaxSize];
    int top;
}StType;
void InitStack(StType *&s)
{
    s=(StType *)malloc(sizeof(StType));
    s->top=-1;
}
void DestroyStack(StType *&s)
{
    free(s);
}
bool GetTop(StType *&s,Box &e)
{
    if(s->top==-1)
        return false;
    e=s->data[s->top];
    return true;
}
bool push(StType *&s,Box e)
{
    if(s->top==MaxSize-1)
        return false;
    s->top++;
    s->data[s->top]=e;
    return true;
}
bool pop(StType *&s,Box &e)
{
    if(s->top==-1)
        return false;
    e=s->data[s->top];
    s->top--;
    return true;
}
int GetLength(StType *s)
{
    return(s->top+1);
}
bool EmptyStack(StType *s)
{
    return(s->top==-1);
}
void SetPath(int ex,int ey,int k)
{
    int xi=ex;
    int yi=ey;
    for(int i=0;i<n;i++)
    {
        path[xi][i]+=k;
        path[i][yi]+=k;
    }
    int x1,x2,y1,y2;
    x1=x2=xi;
    y1=y2=yi;
    while(x1>0&&y1>0)
        path[--x1][--y1]+=k;
    while(x2<n&&y2<n)
        path[x2++][y2++]+=k;
    path[xi][yi]-=k*2;
}
void printSolution()
{
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<n;j++)
        {
            if(y_pos[i]==j)
                printf("q");
            else
                printf("*");
        }
        printf("\n");
    }
    printf("\n");
}
void Disp(StType *s)
{
    for(int i=0;i<s->top;i++)
        printf("\t(%d,%d)",s->data[i].x,s->data[i].y);
}
void SolveQ(int n)
{
    int x1,y1,di;
    StType *st;
    InitStack(st);
    Box e;
    e.x=0;
    e.y=-1;
    push(st,e);
    while(!EmptyStack(st))
    {
        GetTop(st,e);
        x1=e.x;
        y1=e.y;
        bool find=false;
        if(x1==n)
        {
            printSolution();
            Disp(st);
            printf("\n");
            count++;
        }
        while(y1<n-1 && !find)
        {
            y1++;
            y_pos[x1]=y1;
            st->data[st->top].y=y1;
            if(judge(x1))
            {
                find=true;
                e.x=x1+1;
                e.y=-1;
                push(st,e);
            }
        }
        if(!find)
        {
            pop(st,e);
        }
        //pop(st,e);
    }
}
int main()
{
    printf("please input n:\n");
    scanf("%d",&n);
    memset(path,0,sizeof(path));
    memset(y_pos,0,sizeof(y_pos));
    SolveQ(n);
    printf("\n count:%d \n",count);
    return 0;
}
多种解法解决n皇后问题的更多相关文章
- 回溯法解决N皇后问题(以四皇后为例)
		以4皇后为例,其他的N皇后问题以此类推.所谓4皇后问题就是求解如何在4×4的棋盘上无冲突的摆放4个皇后棋子.在国际象棋中,皇后的移动方式为横竖交叉的,因此在任意一个皇后所在位置的水平.竖直.以及45度 ... 
- 巴塞尔问题(Basel problem)的多种解法
		巴塞尔问题(Basel problem)的多种解法——怎么计算\frac{1}{1^2}+\frac{1}{2^2}+\frac{1}{3^2}+\cdots112+122+132+⋯ ? (PS:本 ... 
- C语言解决八皇后问题
		#include <stdio.h> #include <stdlib.h> /* this code is used to cope with the problem of ... 
- 对八皇后的补充以及自己解决2n皇后问题代码
		有了上次的八皇后的基础.这次准备解决2n皇后的问题,: //问题描述// 给定一个n*n的棋盘,棋盘中有一些位置不能放皇后.现在要向棋盘中放入n个黑皇后和n个白皇后,使任意的两个黑皇后都不在同一行./ ... 
- 【BZOJ4555】求和(多种解法混合版本)
		[BZOJ4555]求和(多种解法混合版本) 题面 BZOJ 给定\(n\),求 \[f(n)=\sum_{i=0}^{n}\sum_{j=0}^{i}S(i,j)\times 2^j \times ... 
- CTF-练习平台-Misc之 多种方法解决
		五.多种方法解决 题目提示:在做题过程中你会得到一个二维码图片 下载文件后解压发现是一个exe文件,打开后报错:将文件后缀名改为txt打开后发现是base64编码 联系到提示说最后是一个二维码,将它转 ... 
- 回溯算法——解决n皇后问题
		所谓回溯(backtracking)是通过系统地搜索求解问题的方法.这种方法适用于类似于八皇后这样的问题:求得问题的一个解比较困难,但是检查一个棋局是否构成解很容易. 不多说,放上n皇后的回溯问题代码 ... 
- Python 解决八皇后问题
		问题介绍 八皇后问题是一个以国际象棋为背景的问题:如何能够在 \(8\times8\) 的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?为了达到此目的,任两个皇后都不能处于同一 ... 
- 使用穷举法结合numpy解决八皇后问题
		一般说到八皇后问题,最先想到的就是回溯思想,而回溯思想往往是需要递归来实现的. 计算机很善长做重复的事情,所以递归正和它的胃口,而我们人脑更喜观平铺直叙的思维方式.当 我们看到递归时,总想把递归平铺展 ... 
随机推荐
- winform 实现类似于TrackBar的自定义滑动条,功能更全
			功能很全,随便列几个 1.可以设置滑块的大小,边框颜色.背景色.形状等等吧 2.可以设置轨道的方向.边框颜色.背景色.阴影等等 ... 效果图: 下载链接https://download.csdn.n ... 
- H5直播避坑指南
			本文来自"小时光茶社(Tech Teahouse)"公众号 作者简介: 文赫,2015年加入腾讯,作为前端开发工程师参与过手Q游戏公会,游戏中心,企鹅电竞等项目,具有丰富的移动端开 ... 
- EL表达式 if 和 if else语句的写法
			JavaScript的if else大家都不会陌生,但可能很多小伙伴并不知道在jsp文件里,el表达式的if else是怎么写的,下面安利给各位小伙伴 el表达式 if 代码示例 <c:if t ... 
- [Abp vNext 源码分析] - 1. 框架启动流程分析
			一.简要说明 本篇文章主要剖析与讲解 Abp vNext 在 Web API 项目下的启动流程,让大家了解整个 Abp vNext 框架是如何运作的.总的来说 ,Abp vNext 比起 ABP 框架 ... 
- 为什么不要使用 async void?
			问题 在使用 Abp 框架的后台作业时,当后台作业抛出异常,会导致整个程序崩溃.在 Abp 框架的底层执行后台作业的时候,有 try/catch 语句块用来捕获后台任务执行时的异常,但是在这里没有生效 ... 
- ASP.NET Core中使用GraphQL - 第三章 依赖注入
			ASP.NET Core中使用GraphQL ASP.NET Core中使用GraphQL - 第一章 Hello World ASP.NET Core中使用GraphQL - 第二章 中间件 SOL ... 
- 【工利其器】必会工具之(一)Source Insight篇
			前言 “Source Insight(以下简称SI)是世界上最好的编辑器”,说这句话不知道会不会出门被打呢?-_- 中国古话说得好,“文无第一,武无第二”,所以不敢说SI是最好的,但是 ... 
- MaterialCalendarDialog【Material样式的日历对话框】
			版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 Material样式的日历对话框 前提条件:Activity界面必须继承FragmentActivity或者其子类(比如AppCom ... 
- mybatis在xml文件中处理转义字符
			第一种方法: 用了转义字符把>和<替换掉,然后就没有问题了. AND start_date <= CURRENT_DATE AND end_date >= CURRENT_DA ... 
- 一套代码小程序&Web&Native运行的探索05——snabbdom
			接上文:一套代码小程序&Web&Native运行的探索04——数据更新 对应Git代码地址请见:https://github.com/yexiaochai/wxdemo/tree/ma ... 
