回溯算法(1)

                搜索与回溯是计算机解题中常用的算法,很多问题无法根据某种确定的计算法则来求解,可以利用搜索与回溯的技术求解。回溯是搜索算法中的一种控制策略。它的基本思想是:为了求得问题的解,先选择某一种可能情况向前探索,在探索过程中,一旦发现原来的选择是错误的,就退回一步重新选择,继续向前探索,如此反复进行,直至得到解或证明无解。

              回溯算法通常用递归来实现,通常有下面两种算法框架(阅读回溯算法实现代码可以依照下面的框架来理解):

                算法框架一:

                procedure Try(k:integer);

                begin

                for i:=1 to 算符种类 Do

                if 满足条件 then

                begin

                保存结果

      if 到目的地 then 输出解

      else Try(k+1) 

                 恢复,保存结果之前的状态,回溯一步

      end;

                           end;    

             算法框架二:

                procedure Try(k:integer);

                begin

     if 到目的地 then 输出解

                else:

                for i:=1 to 算符种类 Do

                if 满足条件 then

                begin

                保存结果

     Try(k+1);

     end;

                          end;

         第二种算法框架更加简洁,很多人看别人的回溯算法代码实现都纳闷怎么没有发现代码中有回溯的操作,而觉得回溯算法代码有问题,其实这是由于代码是参照第二种框架来写,这种框架没有直接回溯操作。但是实际上本质上和第一种算法框架相同

    

下面运用第二种算法框架 实现n皇后问题

题目:

在n * n的国际象棋盘上放置n个皇后,使它们彼此互相不攻杀。皇后攻杀条件:处于同一行,或同一列,或同一斜线的皇后彼此攻杀。试给出全部方案

//编程实现n皇后问题 其中n由define规定

#include <stdio.h>
#include <math.h>
#define N  5


int col[N+1];
//输出结果
void Output()
{
    for(int i=1;i<=N;i++)
    {
        printf("(%d,%d)\n",i,col[i]);
    }
    printf("\n");
}
//求解函数  i之前的解已经确定的基础上 求其它
void Queen(int i,int n)
{
    if(i>n)    //当满足此条件 说明 到达目的地
        Output();
    else
    {
        for(int j=1;j<=n;++j)
        {
            int k=1;
            col[i]=j;
            while(k<i)  
            {
                if((col[k]-col[i])*(fabs(col[k]-col[i])-fabs(k-i))!=0)
                {  //满足此条件 说明col[k]当前放置的位置没有发生冲突
                    k++;        //保存结果
                    if(k==i)
                        Queen(i+1,n);//递归
                }
                else
                {
                    break;
                }
            }

        }
    }
}
int main()
{
     printf("the answer is:\n");
     for(int i=1;i<=N;i++)
     {
        col[1]=i;   //设置第一行的 列值 为i
        Queen(2,N);
    }
}
~                                                                                                                                                                                                            
~      

 

   

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值