盲目搜索:跳马

题目:

有一m*n的棋盘,把马放在任意位置,马按照中国象棋法起跳,求能返回原位置的所有路线。

回溯法求解此题(其实也就是最基本的深搜):

从起点开始,向可以扩展的位置扩展(由题意可知,一共有八种扩展方法);

到了新的位置,先判断是不是到达原位置,如果是,则输出该路线,并会退到上一个位置,继续下一个位置的扩展;

如果不是,再判断是否超出棋盘,或者产生回路,如果是,则回退到上一个位置;

如果以上都不成立,那么就从这一新位置继续向下扩展;

每当一个位置的八种情况都扩展完了,就回退到上一位置;

以上为此题的思路。


也就是一个回溯思想的应用,DFS在我看来,就是对回溯的应用(如果过于绝对,请指正)。


代码可以用递归,也可以非递归。。一直都是写的递归,这次尝试了一下非递归,果然各种错啊。。。。

最让人郁闷的是二维数组的赋初值竟然弄错了。。。这个问题一直没发现,让我找错找了好久。。。


代码:


#include<iostream>
using namespace std;
#define maxn 5
int choose[8][2]={{1,2},{2,1},{2,-1},{1,-2},{-1,-2},{-2,-1},{-2,1},{-1,2}};
struct node{
       int x;
       int y;
       int p;
       };

int flag[10][10];
bool istrue(int x1,int y1){
     if(flag[x1][y1])
         return false;
     if(x1<=0||x1>4||y1<=0||y1>3)
         return false;
     return true;
}
int main(){
    int start,end;
    while(cin>>start>>end){
        node a[100];
        node b[100][100];
        memset(flag,0,sizeof(flag));
        int times=0;
        int time=0;
        node temp;
        temp.x=start;
        temp.y=end;
        temp.p=0;
        a[times++]=temp;
        flag[start][end]=1;
        while(times>0){
            node temp1=a[times-1];
            node temp2;
            int i;
            for(i=temp1.p;i<8;i++){
                    temp2.x=temp1.x+choose[i][0];
                    temp2.y=temp1.y+choose[i][1];
                    temp2.p=0;
                    if(temp2.x==start&&temp2.y==end){
                          for(int j=0;j<times;j++){
                                  b[time][j]=a[j];    
                                  }
                          time++;
                          continue;
                          }
                    if(istrue(temp2.x,temp2.y)){
                          
                          a[times-1].p=i+1;
                          a[times++]=temp2;
                          flag[temp2.x][temp2.y]=1;
                          break;
                          }
                          }
            if(i>=8){
                times--;
                flag[a[times].x][a[times].y]=0;
                }
                }
         for(int k=0;k<time;k++){
                 int temp3=b[k][0].x;
                 int temp4=b[k][0].y;
                 int temp5=0;
                 while(temp3!=0||temp4!=0){
                     cout<<temp3<<" "<<temp4<<endl;
                     temp5++;
                     temp3=b[k][temp5].x;
                     temp4=b[k][temp5].y;
                     }
                 cout<<endl;
                 }
                 }
        return 0;
}        



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值