zoukankan      html  css  js  c++  java
  • 骑士问题【BFS】【DFS】【记搜】

    题目大意:
    一个8×8的棋盘上有n个点不可以走,求马(骑士)从(sx,sy)走到(ex,ey)的最少步数。
    Input

    10
    c1 d1 d5 c2 c3 c4 d2 d3 d4 c5
    a1 f1
    0
    
    c1 b3
    2
    b3 c2
    a1 b2
    -1
    

    Output

    Board 1: 7 moves
    Board 2: 1 moves
    Board 3: not reachable

    思路:

    BFS

    比较裸的广搜吧。。。

    n个点赋值为1,表示不可以走,到时候走过的点也赋值给1,最终回溯输出答案。

    当然这道题记搜和DFS也都可以,2003年的GDOI应该也是比较简单的一次了吧。时限都是2秒。


    代码:

    #include <cstdio>
    #include <iostream>
    #include <string>
    using namespace std;
    
    const int dx[]={0,-2,-1,1,2,-2,-1,1,2};
    const int dy[]={0,-1,-2,-2,-1,1,2,2,1};
    int n,state[100001][3],a[101][101],head,tail,sx,sy,ex,ey,father[100001],tot,sum;
    string s;
    
    void print(int x,int k)  //回溯输出
    {
        if (father[x]) print(father[x],k);
        sum++;
        return;
    }
    
    bool check(int x,int y)
    {
        return (x==ex&&y==ey);  //到达终点
    }
    
    void bfs()
    {
        father[1]=0;
        state[1][1]=sx;
        state[1][2]=sy;
        head=0;
        tail=1;  //初始化
        do
        {
            head++;
            for (int i=1;i<=8;i++)  //8个方向搜索
            { 
                tail++;  //入队
                int xx=state[head][1]+dx[i];
                int yy=state[head][2]+dy[i];
                if (xx<1||yy<1||xx>8||yy>8||a[xx][yy])   //不符合要求
                {
                    tail--;  //出队
                    continue;
                }
                a[xx][yy]=1;
                state[tail][1]=xx;
                state[tail][2]=yy;
                father[tail]=head;
                if (check(xx,yy))   //到达了终点
                {
                    sum=0;
                    print(tail,0);
                    printf("%d moves\n",sum-1);
                    return;
                }
            }
        }
        while (head<tail); 
        printf("not reachable\n");
        return;
    }
    
    int main()
    {
        while (++tot)
        {
            scanf("%d",&n);
            if (n==-1) break;
            for(int i=1;i<=100;i++)
             for (int j=1;j<=100;j++) a[i][j]=0;
            for (int i=1;i<=n;i++)
            {
                cin>>s;
                a[(int)s[0]-'a'+1][(int)s[1]-'0']=1;  //不能走
            }
            cin>>s;
            sx=s[0]-'a'+1;
            sy=s[1]-'0';
            cin>>s;
            ex=s[0]-'a'+1;
            ey=s[1]-'0';  //起点和终点
            a[sx][sy]=1;
            printf("Board %d: ",tot);
            bfs();
        }
        return 0;
    }
  • 相关阅读:
    使用Notepad++进行php开发所必需的插件
    jquery操作复选框(checkbox)的12个小技巧总结
    深入理解拆箱
    史上最全UML的详细解析
    我理解的invoke和begininvoke
    java中的冒泡排序算法
    java中的选择排序算法
    Java实现将json中的数值插入到mysql中
    Java实现对mysql中的数值进行读取、插入、更新、删除
    Java连接MySQL数据库
  • 原文地址:https://www.cnblogs.com/hello-tomorrow/p/9313041.html
Copyright © 2011-2022 走看看