【转】POJ-2243-Knight Moves:DFS || BFS || Floyd 求最短路

DFS

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int knight[8][8];// 各点到起点的最短距离
int x[8]={-2, -1, 1, 2, -2, -1, 1, 2};
int y[8]={-1, -2, -2, -1, 1, 2, 2, 1};

void DFS(int i, int j, int dis)
{
        if(i<0||i>7||j<0||j>7||knight[i][j]<=dis)
            return;
        knight[i][j]=dis;
        for(int k=0; k<8; k++)
            DFS(i+x[k], j+y[k], dis+1);
}

int main()
{
        char S1[10], S2[10];
        while(cin>>S1>>S2)
        {
                memset(knight, 10, sizeof(knight));// 初始化距离较大 DFS时再更新

                DFS(S1[0]-‘a‘, S1[1]-‘1‘, 0);

                printf("To get from %s to %s takes %d knight moves.\n", S1, S2, knight[S2[0]-‘a‘][S2[1]-‘1‘]);
        }
        return 0;
}

BFS

#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;

int x[8]={-2, -1, 1, 2, -2, -1, 1, 2};
int y[8]={-1, -2, -2, -1, 1, 2, 2, 1};

struct point
{
        int x, y;
        int  dis;
};

int main()
{
        queue<point>que;
        char S1[10], S2[10];
        while(cin>>S1>>S2)
        {
                while(!que.empty())
                    que.pop();
                point p;
                p.x=S1[0]-‘a‘;
                p.y=S1[1]-‘1‘;
                p.dis=0;
                que.push(p);
                while(!que.empty())
                {
                        p = que.front();
                        que.pop();
                        if(p.x==S2[0]-‘a‘ && p.y==S2[1]-‘1‘)
                            break;

                        point tmp;
                        for(int i=0; i<8; i++)
                        {
                                tmp.x=p.x+x[i];
                                tmp.y=p.y+y[i];
                                tmp.dis=p.dis+1;
                                if(tmp.x<0 || tmp.x>7 || tmp.y<0 || tmp.y>7)
                                        continue;
                                que.push(tmp);
                        }
                }
                printf("To get from %s to %s takes %d knight moves.\n", S1, S2, p.dis);
        }
        return 0;
}

Floyd

算法详解请点这里

应用于改题的思路:由于棋盘很小,而输入数据可能很大,则可以想到先打表存储每点到各点的最短路径,这样对于所有输入查表输出即可。

当然前提是从每一点出发可以到达任一点(题中有提到)

相对于DFS和BFS来说 Floyd的时间复杂度最小

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
using namespace std;

void Floyd(int k[][64])
{
        int dx, dy;// 两点间相对距离
        for(int i=0; i<64; k[i][i]=0,i++)
            for(int j=0; j<64; j++){

                dx=abs(i/8-j/8);
                dy=abs(i%8-j%8);

                if(dx==1&&dy==2 || dx==2&&dy==1)//      骑士一步的距离
                    k[i][j]=k[j][i]=1;
            }

        for(int l=0; l<64; l++)
            for(int i=0; i<64; i++)
                for(int j=0; j<64; j++){

                        if(k[i][l]+k[l][j]<k[i][j])
                            k[i][j]=k[i][l]+k[l][j];
                }
}

int main()
{
        char S1[10], S2[10];
        int knight[64][64];// 棋盘中每点到其余给点的距离 以骑士的步长为单位
        memset(knight, 10, sizeof(knight));//初始化为无穷
        Floyd(knight);// 打表 存储

        while(cin>>S1>>S2)
        {
                int x=(S1[0]-‘a‘)*8+S1[1]-‘1‘;
                int y=(S2[0]-‘a‘)*8+S2[1]-‘1‘;
                // 直接查表 打印结果
                printf("To get from %s to %s takes %d knight moves.\n", S1, S2, knight[x][y]);
        }
        return 0;
}

总结:Floyd算法适合稠密图 即图小数据量大 而BFS适合稀疏图 即图大数据量小。

时间: 2024-10-19 15:30:36

【转】POJ-2243-Knight Moves:DFS || BFS || Floyd 求最短路的相关文章

poj 1915 Knight Moves (bfs搜索)

Knight Moves Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 21919   Accepted: 10223 Description Background Mr Somurolov, fabulous chess-gamer indeed, asserts that no one else but him can move knights from one position to another so fast

POJ 2243:Knight Moves(BFS)

可以理解为象棋中的马走“日”字形,从第一个位置到第二个位置所需的最短步数,简单的BFS 每走一步需判断一次是否到达目标点. 由于BFS写得不多,一直用DFS的思维理解,递归写一直溢出.超时~~ #include"cstdio" #include"iostream" #include"cstring" #include"queue" using namespace std; int dx[8]={-1,1,-2,2,-2,2,-

poj 2243 Knight Moves

Knight Moves Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11794   Accepted: 6646 Description A friend of you is doing research on the Traveling Knight Problem (TKP) where you are to find the shortest closed tour of knight moves that v

POJ 1915 Knight Moves(BFS+STL)

 Knight Moves Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 20913   Accepted: 9702 Description Background Mr Somurolov, fabulous chess-gamer indeed, asserts that no one else but him can move knights from one position to another so fa

poj2243&amp;&amp;hdu1372 Knight Moves(BFS)

转载请注明出处:http://blog.csdn.net/u012860063?viewmode=contents 题目链接: POJ:http://poj.org/problem?id=2243 HDU: http://acm.hdu.edu.cn/showproblem.php?pid=1372 Problem Description A friend of you is doing research on the Traveling Knight Problem (TKP) where y

POJ 1915 Knight Moves

Knight Moves Description Background Mr Somurolov, fabulous chess-gamer indeed, asserts that no one else but him can move knights from one position to another so fast. Can you beat him? The Problem Your task is to write a program to calculate the mini

Knight Moves(hdu1372 bfs模板题)

http://acm.hdu.edu.cn/showproblem.php?pid=1372 Knight Moves Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 6731    Accepted Submission(s): 4059 Problem Description A friend of you is doing res

dijkstra,SPFA,Floyd求最短路

Dijkstra: 裸的算法,O(n^2),使用邻接矩阵: 算法思想: 定义两个集合,一开始集合1只有一个源点,集合2有剩下的点. STEP1:在集合2中找一个到源点距离最近的顶点k:min{d[k]} STEP2:把顶点k加入集合1中,同时修改集合2中的剩余顶点j的d[j]是否经过k之后变短,若变短则修改d[j]; if d[k]+a[k,j]<d[j] then   d[j]=d[k]+a[k,j]; STEP3:重复STEP1,直到集合2为空为止. #include <iostream&

POJ 1915 Knight Moves [BFS]

Knight Moves Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 26844   Accepted: 12663 Description Background  Mr Somurolov, fabulous chess-gamer indeed, asserts that no one else but him can move knights from one position to another so fas