回溯就是算法是搜索算法中一种控制策略,是一个逐个试探的过程。在试探的过程中,如果遇到错误的选择,就会回到上一步继续选择下一种走法,一步一步的进行直到找到解或者证明无解为止。

如下是一个经典回溯问题n皇后的解答树:

下面就从n皇后说起:


【问题描述】

在n×n的国际象棋盘上,放置n个皇后,使任何一个皇后都不能吃掉另一个,需满足的条件是:同一行、同一列、同一对角线上只能有一个皇后。求所有满足要求的放置方案。4皇后的放置方案如下:

【输入】一个正整数n。

【输出】每行代表一种放置方案:第i行的第一个数是i,表示第i种方案,后面一个冒号,然后是用空格隔开的n个数,其中第i个数x[i]表示第i行上的皇后放在第x[i]列;最后一行:一个整数,表示方案总数。

【样例输入】

4

【样例输出】

1:2 4 1 3

2:3 1 4 2

2

这个题目简直是太经典了,一提到回溯第一个想到的就是它。这个题非常的通俗易懂,就是在一个n*n的棋盘上满足条件地放置n个皇后,每种组合搜一遍就好了。在搜的过程中判断下一步的某种方向是否可以走,如果可以的话就进入下一层,如果不符合要求就搜下一个方向,搜完这一层的所有方向以后就回到上一层,继续搜上一层的下一个方向。

不知道大家看懂了没有,如果没看懂,看代码就懂了。。

上代码:

#include<iostream>
#include<cstdio> using namespace std; int n;
int sum=0;//解法存放个数
int a[100000];//存放皇后位置数据
bool b[1000000]={0},c[1000000]={0},d[10000000]={0};//b存储y方向,c、d存储对角线 void print()
{
sum++;
cout<<sum<<':';
for(int i=1;i<=n;i++)
{
cout<<a[i]<<' ';
}
cout<<endl;
} int search(int x)
{
for(int j=1;j<=n;j++)//遍历本层中每种方向
{
if((!b[j])&&(!c[x+j])&&(!d[x-j+n-1]))//如果满足条件
{
a[x]=j;//存入皇后数据
b[j]=1;//占领y轴
c[x+j]=1;//占领对角线
d[x-j+n-1]=1;//占领对角线
if(x==n)
{
print();//如果有完整解,输出
}
else
{
search(x+1);//如果没有继续找下一行
}
b[j]=0;//找完之后取消占领
c[x+j]=0;
d[x-j+n-1]=0;
}
}
} int main()
{
cin>>n;
search(1);//从第一个开始找
cout<<sum;
}

  把思想带到代码里应该就看懂了吧。

回溯就是这样一层一层的找,找完本层返回上一层继续找,直到找到正确解为止。

继续再看一道题:

3、素数链

设计程序将1。。。n排成一排,使任意两个相邻的数的和为素数。第1个和最后一个的和也为素数.输出一种方案即可。

输入:

n (n<=100)

输出:

1到n的一个序列,中间用一个空格隔开。第一个数为1。

如果无解输出-1。

样例输入:

10

样例输出:

1  2  3  4  7  6  5  8  9  10

这道题和刚才那道n皇后的思路是一样的,遍历所有可能,在遍历的过程中判断,如果可以就继续搜下一层。

代码如下:

#include<cstdio>
#include<iostream> const int maxx=1000; using namespace std; int n;
int numguo[maxx]={0};
bool guo[maxx]={0},pguo=0;
int c=0; int sushu(int x)//验证素数的函数
{
//关于判断素数的题很早就做过,这里我就不解释了
int i=2;
while(i<x)
{
if(x%i==0)
return 0;//如果不是直接跳出返回0
i++;
}
return 1;//如果是的话返回1
} int panduan()
{
int t;
for(int i=1;i<n;i++)//判断是否达到要求
{
if(!sushu(numguo[i]+numguo[i+1]))//这里我直接放到函数里去验证
{
return 0;//如果不是素数就直接跳出返回0
}
}
if(!sushu(numguo[n]+numguo[1])) return 0;//注意别忘了最后一个和第一个数字的和是否为素数
return 1;//正确的话返回1
} int print()
{
c++;//可能方法+1
for(int i=1;i<=n;i++){
cout<<numguo[i]<<' ';
}
cout<<endl;
} int search(int x)
{
for(int i=1;i<=n;i++)//搜索本层中每种可能
{
if(!guo[i])
{
guo[i]=1;//占领
numguo[x]=i;//标记
if(x==n)//如果达到数量要求
{ if(panduan())//如果符合要求
{
if(!pguo)//如果没输出过
{
pguo=1;//输出过
print();//输出
return 0;//搜到就直接跳出
}
}
}
else search(x+1);
guo[i]=0;
numguo[x]=0;
}
}
} int main()
{
cin>>n;
search(1);//从第一个开始找
if(!c) cout<<"-1";//如果没可能就输出“-1”
return 0;
}

  这些代码中我用了很多的函数,这样节约了代码长度,也更加方便(个人觉得)。

回溯就是这个中心思想,一步步往下搜,一层层的搜,直到搜完或找到结果为止。

其实上面两道题都是很水的基础,再往后还有回溯遍历图、树等等等等。。

ending。。。

回溯算法————n皇后、素数串的更多相关文章

  1. 回溯算法 - n 皇后问题

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

  2. 8皇后以及N皇后算法探究,回溯算法的JAVA实现,非递归,循环控制及其优化

    上两篇博客 8皇后以及N皇后算法探究,回溯算法的JAVA实现,递归方案 8皇后以及N皇后算法探究,回溯算法的JAVA实现,非递归,数据结构“栈”实现 研究了递归方法实现回溯,解决N皇后问题,下面我们来 ...

  3. 8皇后以及N皇后算法探究,回溯算法的JAVA实现,递归方案

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

  4. 回溯算法之n皇后问题

    今天在看深度优先算法的时候,联想到DFS本质不就是一个递归回溯算法问题,只不过它是应用在图论上的.OK,写下这篇博文也是为了回顾一下回溯算法设计吧. 学习回溯算法问题,最为经典的问题我想应该就是八皇后 ...

  5. 回溯算法-C#语言解决八皇后问题的写法与优化

    结合问题说方案,首先先说问题: 八皇后问题:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行.同一列或同一斜线上,问有多少种摆法. 嗯,这个问题已经被使用各种语言解 ...

  6. C语言回溯算法解决N皇后问题

    回溯算法的模型是 x++, not satisfy ? x-- : continue. 代码中x作列号,y[x]保存第x列上皇后放置的位置. #include<stdio.h> #incl ...

  7. 回溯算法 LEETCODE别人的小结 一八皇后问题

    回溯算法实际上是一个类似枚举的搜索尝试过程,主要是在搜索尝试中寻找问题的解,当发现已不满足求解条件时,就回溯返回,尝试别的路径. 回溯法是一种选优搜索法,按选优条件向前搜索,以达到目的.但是当探索到某 ...

  8. 回溯算法——解决n皇后问题

    所谓回溯(backtracking)是通过系统地搜索求解问题的方法.这种方法适用于类似于八皇后这样的问题:求得问题的一个解比较困难,但是检查一个棋局是否构成解很容易. 不多说,放上n皇后的回溯问题代码 ...

  9. JS算法之八皇后问题(回溯法)

    八皇后这个经典的算法网上有很多种思路,我学习了之后自己实现了一下,现在大概说说我的思路给大家参考一下,也算记录一下,以免以后自己忘了要重新想一遍. 八皇后问题 八皇后问题,是一个古老而著名的问题,是回 ...

随机推荐

  1. PHP.INI常用设置一览表(持续更新)

    在编程的过程中遇到或发现的问题,会持续的更新: 1. 打破var_dump的显示瓶颈 php开发环境里,安装了xdebug模块后,var_dump()输出的结果将比较易于查看,但默认情况下,var_d ...

  2. SpringMVC(一) —— 入门

    SpringMVC原理图: 步骤: 首先用户发送请求.——>DispatcherServlet,前端控制器收到请求后自己不进行处理,而是委托给其他的解析器进行处理,作为统一访问点,进行全局的流程 ...

  3. (转+原)android获取系统时间

    参考的网站如下: http://c.biancheng.net/cpp/html/144.html http://www.linuxidc.com/Linux/2012-03/55909.htm 代码 ...

  4. 容联手机接口封装到ThinkPHP3.2.菜鸟图文教学

    今天来说下短信发送技术. 使用的是 容联http://www.yuntongxun.com/ 用法很简单, 具体要知道的参数有 ACCOUNT SID   应用ID AUTH TOKEN 应用toke ...

  5. 使用Python脚本获取指定格式文件列表的方法

    在Python环境下获取指定后缀文件列表的方式. 来源stackoverflow 这里简单以*.txt的作为例子. 使用glob(推荐) import glob, os os.chdir(" ...

  6. win7 安装 redis +php扩展

    1:首先下载redis:redis-2.0.2.zip (32 bit),解压. 从下面地址下:http://code.google.com/p/servicestack/wiki/RedisWind ...

  7. VMware双网卡实现虚拟机连开发板和Internet

    前面已经介绍过关于VMware产生的虚拟交换机和虚拟网卡,当宿主机拥有两个网卡时,可以让虚拟系统同时实现上网和连接开发板的功能. 首先,在设置中虚拟出两块虚拟机网卡,一块连接VMnet0交换机一块连接 ...

  8. MediaInfo使用简介(新版本支持HEVC)

    MediaInfo 用来分析视频和音频文件的编码和内容信息,是一款是自由软件 (免费使用.免费获得源代码).他除了提供DLL之外,本身也提供GUI工具用于查看视频信息.我使用中发现,新版本的Media ...

  9. 直播视频插件--sewise player

    直播视频插件 -- sewise player 2017-1-9 因为公司要开发一个关于购车直播的新项目,需要在页面引入直播视频,项目组之前都没有做过关于直播类型的项目,所以可以说是真的从各种资源中筛 ...

  10. AJAX提交到Handler.ashx一般处理程序返回json数据 (字符串拼接方式)

    <%@ WebHandler Language="C#" Class="Handler" %> using System; using System ...