zoj - 1091 - Knight Moves(广度优先地图记数法)

今天兴致再起,突发想法,用第三种方法,广度优遍历棋盘,每走一步,就在那个位记录下到达那个位置所需的步数,AC此题。微笑

#include <iostream>
#include <queue>
#include <string.h>

using namespace std;

typedef struct Tdata        //定义结点数据类型
{
    int x;
    int y;
}data;

data end;       //目标结点

int dx[] = {-2, -2, -1, 1, 2,  2,  1, -1};      //行偏移量
int dy[] = {-1,  1,  2, 2, 1, -1, -2, -2};      //列偏移量

int vis[10][10];        //步数数组,初始化为-1,既记录步数,又标记状态

void bfs(data n)        //广度优先遍历,记录走到各个位置的所需步数
{
    int i;
    queue<data> qu;     //广度优先中用来的队列
    qu.push(n);     //第一个结点入列
    vis[n.x][n.y] = 0;      //走过了,将此结点的步数标记为1

    data newnode;

    while(!qu.empty())
    {
        n = qu.front();
        qu.pop();
        for(i = 0; i < 8; i++)      //分别向8个方向进行遍历
        {
            newnode.x = n.x + dx[i];
            newnode.y = n.y + dy[i];

            if(vis[newnode.x][newnode.y] == -1 && newnode.x >= 0 && newnode.x < 8 && newnode.y >= 0 && newnode.y < 8)       //可走入的条件:没走过,不出界
            {
                qu.push(newnode);
                vis[newnode.x][newnode.y] = vis[n.x][n.y] + 1;      //记录走到这里的步数
            }
        }
    }
}

int main()
{
    string a, b;
    data begin;     //起始位置
    while(cin>>a>>b)
    {
        memset(vis, -1, sizeof(vis));        //令状态数组的初始值为0,即未访问过
        begin.x = a[0] - 'a';       //转换
        begin.y = a[1] - '0' - 1;
        end.x = b[0] - 'a';
        end.y = b[1] - '0' - 1;

        bfs(begin);

        cout<<"To get from "<<a<<" to "<<b<<" takes "<<vis[end.x][end.y]<<" knight moves."<<endl;
    }
    return 0;
}


posted @ 2012-11-14 10:43  xiaodanding  阅读(122)  评论(0编辑  收藏  举报