zoukankan      html  css  js  c++  java
  • 马的遍历

    题目链接

    首先,这是一道水题。(虽然我提交了四次才A掉)

    思路是很简单的。马的遍历,经典中的经典,一想就是搜索。但流传较广的是DFS,第一直觉也是DFS。可是,一看题,求马到各点的最短路,是求最优解,且是各个点,自然想到了BFS。

    BFS的简单思路,将矩阵每个点赋值为-1,先定义一个队列,用两个数组表示,h(行),l(列)。

    下面从马的坐标开始向外跳,判断是否超出边界,且是否已跳到过(相当于>-1),若大于-1,根据BFS越先越优的性质,跳过搜索下一个。最后,定义指针head,tail指向队头队尾。

    见代码:

    #include<iostream>
    #include<cstring> 
    using namespace std;
    void bfs();
    int head,tail=1,b,c,m,n,a[401][401];
    int p[9]={0,-2,-2,-1,-1,1,1,2,2};
    int y[9]={0,-1,1,-2,2,-2,2,-1,1};
    int h[160001],l[160001];
    int main()
    {
        cin>>m>>n>>b>>c;
        memset(a,-1,sizeof(a));
        a[b][c]=0;
        h[1]=b;
        l[1]=c;
        bfs();
        for(int i=1;i<=m;i++)
            {
                for(int j=1;j<=n;j++)
                cout<<a[i][j]<<" ";
                cout<<endl;
            }
        return 0;
    } 
    void bfs()
    {
        while(head!=tail)
        {
            head++;
            for(int i=1;i<=8;i++)
            {
                if(h[head]+p[i]>0&&h[head]+p[i]<1+m&&l[head]+y[i]>0&&y[i]+l[head]<1+n&&a[h[head]+p[i]][l[head]+y[i]]==-1)
                {
                    
                    a[h[head]+p[i]][l[head]+y[i]]=a[h[head]][l[head]]+1;
                    tail++;
                    h[tail]=h[head]+p[i];
                    l[tail]=l[head]+y[i];
                }
            }
        }
    }

    然后……华丽丽地挂掉啦!!!

    原因是未设域宽。

    于是,见代码*2:

    #include<iostream>
    #include<cstring> 
    #include<iomanip>
    using namespace std;
    void bfs();
    int head,tail=1,b,c,m,n,a[401][401];
    int p[9]={0,-2,-2,-1,-1,1,1,2,2};
    int y[9]={0,-1,1,-2,2,-2,2,-1,1};
    int h[160001],l[160001];
    int main()
    {
        cin>>m>>n>>b>>c;
        memset(a,-1,sizeof(a));
        a[b][c]=0;
        h[1]=b;
        l[1]=c;
        bfs();
        for(int i=1;i<=m;i++)
            {
                for(int j=1;j<=n;j++)
                if(j>1)
                cout<<setw(5)<<a[i][j];
                else
                cout<<a[i][j];
                cout<<endl;
            }
        return 0;
    } 
    void bfs()
    {
        while(head!=tail)
        {
            head++;
            for(int i=1;i<=8;i++)
            {
                if(h[head]+p[i]>0&&h[head]+p[i]<1+m&&l[head]+y[i]>0&&y[i]+l[head]<1+n&&a[h[head]+p[i]][l[head]+y[i]]==-1)
                {
                    
                    a[h[head]+p[i]][l[head]+y[i]]=a[h[head]][l[head]]+1;
                    tail++;
                    h[tail]=h[head]+p[i];
                    l[tail]=l[head]+y[i];
                }
            }
        }
    }

    又挂啦!左对齐!

    于是学到了一个神器——std::left——自动左对齐。(当然可为std::right,自动右对齐)调用<iomanip>库,在setw前输入即可。

    见代码*3:

    #include<iostream>
    #include<cstring> 
    #include<iomanip>
    using namespace std;
    void bfs();
    int head,tail=1,b,c,m,n,a[401][401];
    int p[9]={0,-2,-2,-1,-1,1,1,2,2};
    int y[9]={0,-1,1,-2,2,-2,2,-1,1};
    int h[160001],l[160001];
    int main()
    {
        cin>>m>>n>>b>>c;
        memset(a,-1,sizeof(a));
        a[b][c]=0;
        h[1]=b;
        l[1]=c;
        bfs();
        for(int i=1;i<=m;i++)
            {
                for(int j=1;j<=n;j++)
                {
                    if(j>1)
                    cout<<std::left<<setw(5)<<a[i][j];
                    else
                    cout<<std::left<<setw(5)<<a[i][j];
                }
                cout<<endl;
            }
        return 0;
    } 
    void bfs()
    {
        while(head!=tail)
        {
            head++;
            for(int i=1;i<=8;i++)
            {
                if(h[head]+p[i]>0&&h[head]+p[i]<1+m&&l[head]+y[i]>0&&y[i]+l[head]<1+n&&a[h[head]+p[i]][l[head]+y[i]]==-1)
                {
                    
                    a[h[head]+p[i]][l[head]+y[i]]=a[h[head]][l[head]]+1;
                    tail++;
                    h[tail]=h[head]+p[i];
                    l[tail]=l[head]+y[i];
                }
            }
        }
    }

    满分啦!好开心!!!


    例行总结:联系了BFS,学到了新神器,还明白了要注意域宽。

    好题哉!!!!! 

  • 相关阅读:
    主键索引就是聚集索引吗?
    聚集索引以及非聚集索引
    IO阻塞模型、IO非阻塞模型、多路复用IO模型
    Log4j的使用说明
    前置机是什么
    转:图文理解区块链
    DQL、DML、DDL、DCL全名是啥?
    OLAP和OLTP的区别
    JAVA之运算符优先级
    JAVA之异常处理(一)
  • 原文地址:https://www.cnblogs.com/qing1/p/11066106.html
Copyright © 2011-2022 走看看