[sicily]1153. 马的周游问题

来源:互联网 发布:手机淘宝我的分享 编辑:程序博客网 时间:2024/05/29 04:27

1153. 马的周游问题

Constraints

Time Limit: 1 secs, Memory Limit: 32 MB , Special Judge

Description

和题目C同样的任务,这里只是把棋盘扩大到标准的国际象棋。对这样一个8 * 8的棋盘用同样的方法编号如下:

1     2     3       4     5     6       7     8

9     10       11    12       13    14       15    16

17    18       19    20       21    22       23    24

25    26       27    28       29    30       31    32

33    34       35    36       37    38       39    40

41    42       43    44       45    46       47    48

49    50       51    52       53    54       55    56

57    58       59    60       61    62       63    64

Input

输入有若干行。每行一个整数N(1<=N<=64),表示马的起点。最后一行用-1表示结束,不用处理。

Output

对输入的每一个起点,求一条周游线路。对应地输出一行,有64个整数,从起点开始按顺序给出马每次经过的棋盘方格的编号。相邻的数字用一个空格分开。

Sample Input

4
-1

Sample Output

注意:如果起点和输入给定的不同,重复多次经过同一方格或者有的方格没有被经过,都会被认为是错误的。


深度优先搜索实现回溯,注意由于数据量比较大,需要进行剪枝。剪枝的方式很有意思,当前下一跳必须对八个方向进行判断,然后按照各个方向的再下一跳的次数从小到大进行排序,意思就是先搜索较少下一跳的方向。从状态空间树的形状来看,就是先搜索子树比较小的方向,从而避免在大量树路径中寻找一个的花销。具体代码如下:


#include <iostream>#include <cstring>#include <set>#include <algorithm>#include <queue> using namespace std;//board数组记录是否已经走过,走过标记为 1  int board[10][10];int movex[8] = {-2,-2,-1,-1,1,1,2,2};  int movey[8] = {-1,1,-2,2,-2,2,-1,1};int path[65]; //构造结构体点 struct Point{    int x,y;    int nextCount;}; //判断能否成为下一个扩展点 bool check(Point n){    return ( n.x>=1 && n.x<=8            &&n.y>=1 && n.y<=8            && board[n.x][n.y]==0);}//自定义比较函数用于比较下一个扩展点bool cmp(Point a,Point b){    return a.nextCount<b.nextCount;} //计算当前节点下一跳的个数 int calculate(Point cur){       Point next;    for(int i=0; i<8; i++)    {        next.x = cur.x + movex[i];        next.y = cur.y + movey[i];        next.nextCount = 0;        if(check(next))            cur.nextCount++;    }    return cur.nextCount;}//深度优先搜索,进行查找一条路径 bool dfs(Point p, int index){    board[p.x][p.y] = 1;    path[index] = (p.x-1)*8 + p.y;    if(index == 63)    {        for(int i=0; i<63; i++)            cout<<path[i]<<" ";        cout<<path[63]<<endl;        return true;    }        //将下一跳的压入vector,并排序     vector<struct Point> v;    for(int i=0; i<8; i++)    {        Point next;        next.x = p.x + movex[i];        next.y = p.y + movey[i];        next.nextCount = 0;        if(check(next))        {               next.nextCount = calculate(next);            v.push_back(next);        }    }    sort(v.begin(),v.end(), cmp);    //递归向下搜索            for(int i=0; i<v.size(); i++)    {        if(dfs(v[i],index+1))            return true;    }     board[p.x][p.y] = 0;    return false;   }int main(){       int n;    while(cin>>n && n!=-1)    {        struct Point tmp;        tmp.x = (n-1)/8+1;        tmp.y = (n-1)%8+1;        memset(board, 0,sizeof(board));         dfs(tmp,0);    }    //system("pause");    return 0;   }                                 

//注意:此代码 dfs 函数的实现和上一段代码不同,仅此而已。#include <iostream>#include <cstring>#include <set>#include <algorithm>#include <queue> using namespace std;//board数组记录是否已经走过,走过标记为 1  int board[10][10];int movex[8] = {-2,-2,-1,-1,1,1,2,2};  int movey[8] = {-1,1,-2,2,-2,2,-1,1};int path[65]; //构造结构体点 struct Point{    int x,y;    int nextCount;}; //判断能否成为下一个扩展点 bool check(Point n){    return ( n.x>=1 && n.x<=8            &&n.y>=1 && n.y<=8            && board[n.x][n.y]==0);}//自定义比较函数用于比较下一个扩展点bool cmp(Point a,Point b){    return a.nextCount<b.nextCount;} ////计算当前节点下一跳的个数 int calculate(Point cur){       Point next;    for(int i=0; i<8; i++)    {        next.x = cur.x + movex[i];        next.y = cur.y + movey[i];        next.nextCount = 0;        if(check(next))            cur.nextCount++;    }    return cur.nextCount;}//深度优先搜索,进行查找一条路径   int flag = 0;void dfs(Point p, int index){    if(flag==1)        return;    board[p.x][p.y] = 1;    path[index] = (p.x-1)*8+p.y;    if(index == 63)    {        for(int i=0; i<63; i++)            cout<<path[i]<<" ";        cout<<path[63]<<endl;         flag=1;        return;    }    //对八个方向计算可下一跳数,然后排序    struct Point next[8];    for(int i=0; i<8; i++)    {        next[i].x = p.x + movex[i];        next[i].y = p.y + movey[i];        next[i].nextCount = 0;        if(check(next[i]))            next[i].nextCount = calculate(next[i]);             }    sort(next,next+8,cmp);    for(int i=0; i<8; i++)    {   if(check(next[i]))            dfs(next[i], index+1);    }    board[p.x][p.y] = 0;    }int main(){       int n;    while(cin>>n && n!=-1)    {        struct Point tmp;        tmp.x = (n-1)/8+1;        tmp.y = (n-1)%8+1;        memset(board, 0,sizeof(board));         flag =0;        dfs(tmp,0);    }   // system("pause");    return 0;   }                                 




0 0
原创粉丝点击