Problem L. 跑图---2018年第二届河北省大学生程序设计竞赛

Description

    跑图是RPG游戏中很烦躁的事情。玩具需要跑到距离他最近的传送点的位置。现在给你一张N×M的方格图,每个方格中数值0表示平地,数值1表示为转送点,你的任务是输出一张N×M的矩阵,Matrix(x,y)表示从(x,y)到距离它最近的传送点的距离。这里的距离是曼哈顿距离,(x1,y1)->(x2,y2)的距离为|x1-x2|+|y1-y2|。

Input

    第一行,有两个数n,m。接下来n行,每行m个数。

    数据保证至少有一个传送点。

    1<=n<=500, 1<=m<=500

Output

    n行,每行m个数,表示某个点到离它最近的传送点的距离。


---------------------------------------------------------------------------------------

Sample input

2 3

0 0 0

1 0 1

---------------------------------------------------------------------------------------

Sample output

1 2 1

0 1 0

---------------------------------------------------------------------------------------

n和m最大为500,若直接进行一个点一个点比较的话,绝逼超时,所以应该另想他法。


绝逼超时的代码:

#include <bits/stdc++.h>
#define maxn 999999
using namespace std;

struct sp
{
    int x;
    int y;
};

vector<sp> v;

int main()
{
    int px,py;
    //cin>>px>>py;
    scanf("%d%d",&px,&py);
    int m[px][py];
    memset(m,0,sizeof(py));
    int sendp;//sendplace
    sp mysp;
    for(int j=0;j<px;++j)
    {
        for(int k=0;k<py;++k)
        {
            //cin>>sendp;
            scanf("%d",&sendp);
            if(sendp==1)
            {
                m[j][k]=1;
                mysp.x=j;
                mysp.y=k;
                v.push_back(mysp);
            }
        }
    }
    vector<sp>::iterator i=v.begin();
    for(int j=0;j<px;++j)
    {
        int mind=maxn;
        if(m[j][0]==1)
        {
            printf("0");
           // cout<<0;
        }
        else
        {
            int tmind;
            for(i=v.begin();i!=v.end();++i)
            {
                tmind=abs(j-i->x)+abs(i->y);
                mind=min(mind,tmind);
            }
            //cout<<mind;
            printf("%d",mind);
        }
        for(int k=1;k<py;++k)
        {
            if(m[j][k]==1)
            {
                //cout<<" "<<0;
                printf(" 0");
            }
            else
            {
                mind=maxn;
                for(i=v.begin();i!=v.end();++i)
                {
                    int tmind=abs( j - (i->x))+abs( k - (i->y));
                    mind=min(mind,tmind);
                }
                //cout<<" "<<mind;
                printf(" %d",mind);
            }
        }
        i=v.begin();
        //cout<<endl;
        printf("\n");
        }
   return 0;
}

看了这么多,有用吗???




这才是正确的代码:(可能有更好的,这只是在赛场上想出来的)

解题思路:以1进行周围发散,把1周围的点置为2,完成后把2周围的(除1之外)置为3,直到计算出所有0的距离。

代码思路:两个vector数组循环使用,进行上下作用遍历后存储。

#include <bits/stdc++.h>
#define maxn 999999
using namespace std;
int mx[4]={0,1,0,-1};
int my[4]={1,0,-1,0};
int count_=0;
struct sp
{
    int x;
    int y;
};

vector<sp> v1;
vector<sp> v2;

int main()
{
    int px,py;
    cin>>px>>py;
    int a[px][py];
    for(int j=0;j<px;++j)
    {
        for(int k=0;k<py;++k)
        {
            cin>>a[j][k];
            if(a[j][k]==1)
            {
                ++count_;
                sp t;
                t.x=j;
                t.y=k;
                v1.push_back(t);
            }
            else a[j][k]=-1;
        }
    }
    while(count_!=px*py)
    {
        if(v2.empty())
        {
            vector<sp>::iterator i=v1.begin();
            for(;i!=v1.end();++i)
            {
                for(int p=0;p<4;++p)
                {
                    int tx=i->x+mx[p];
                    int ty=i->y+my[p];
                    if(tx<0||tx>=px||ty<0||ty>=py)
                    {
                        continue;
                    }
                    else
                    {
                        if(a[tx][ty]!=-1) continue;
                        a[tx][ty]=a[i->x][i->y]+1;
                        ++count_;
                        sp t;
                        t.x=tx;
                        t.y=ty;
                        v2.push_back(t);
                    }
                }
            }
            v1.clear();
        }
        else
        {
            vector<sp>::iterator i=v2.begin();
            for(;i!=v2.end();++i)
            {
                for(int p=0;p<4;++p)
                {
                    int tx=i->x+mx[p];
                    int ty=i->y+my[p];
                    if(tx<0||tx>=px||ty<0||ty>=py)
                    {
                        continue;
                    }
                    else
                    {
                        if(a[tx][ty]!=-1) continue;
                        a[tx][ty]=a[i->x][i->y]+1;
                        ++count_;
                        sp t;
                        t.x=tx;
                        t.y=ty;
                        v1.push_back(t);
                    }
                }
            }
            v2.clear();
        }
    }
    for(int j=0;j<px;++j)
    {
        for(int k=0;k<py;++k)
        {
        	
            if(k==0)
                cout<<a[j][k]-1;
            else cout<<" "<<a[j][k]-1;
        }
        cout<<endl;
    }
    return 0;
}


代码来自:东秦观光旅行团

猜你喜欢

转载自blog.csdn.net/jtjljy/article/details/80386501