2019牛客暑期多校训练(第八场)D-Distance

2019牛客暑期多校训练(第八场)D-Distance


膜拜UESTC_Trimen的大佬们~


原题

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


题意

给定一个n* m* h的空间立方体,进行q次操作。
第1种操作,向空间体中加入一个点(x,y,z)。
第2种操作,找到与(x,y,z)曼哈顿距离最小的点,输出两点间的曼哈顿距离。

思路

BFS。先将n,m,h的中间值换到高的位置,保证h的值小于500,然后将剩下两维压缩处理(不然数组开不下),并且把每层分离出来单独BFS。每加一个点,BFS更新当前平面每个点的最近的点的曼哈顿距离。当查询一个点的时候,遍历所有的高度h,找到三维曼哈顿距离的最小值输出即可。

坑点

要记得把高换为长宽高的中间值,高小了,BFS的平面太大,高大了,遍历的复杂度过高。
(实际上把高换为最小值也能过,时间上也没啥区别。。。)


代码

#include <bits/stdc++.h>

using namespace std;

const int N=100007;
const int INF=1000000007;
const int dx[4]= {0,0,-1,1};
const int dy[4]= {-1,1,0,0};

int n,m,h,q,o;

void trans(int &x, int &y, int &z)
{
    if(o==1)
        swap(x,z);
    if(o==2)
        swap(y,z);
}

int main()
{
    scanf("%d%d%d%d",&n,&m,&h,&q);

    ///将h换到中间值,保证h小于500
    int a[]={n,m,h};
    sort(a,a+3);
    if(n==a[1])
        o=1;
    else if(m==a[1])
        o=2;
    trans(n,m,h);

    int d[500][a[0]*a[2]+1];

    ///初始化
    for(int i=1; i<=h; i++)
        for(int j=0; j<n; j++)
            for(int k=0; k<m; k++)
                d[i][j*m+k]=INF;

    for(int i=1,t,x,y,z; i<=q; i++)
    {
        scanf("%d%d%d%d",&t,&x,&y,&z);

        ///因为前面长宽高顺序换过了,所以这里的长宽高顺序也要换掉
        trans(x, y, z);
        x--;
        y--;

        if (t == 1)
        {
            queue<int> q;
            int s=x*m+y;
            d[z][s]=0;
            q.push(s);
            while(!q.empty())
            {
                int cur=q.front();
                q.pop();
                ///分离出x0和y0
                int x0=cur/m,y0=cur%m;
                for(int j=0; j<4; ++j)
                {
                    int x1=x0+dx[j],y1=y0+dy[j];
                    if(x1>=0&&x1<n&&y1>=0&&y1<m)
                    {
                        int nxt=x1*m+y1;
                        ///判断是否需要更新点并且继续找下一个点
                        if(d[z][cur]+1<d[z][nxt])
                        {
                            d[z][nxt]=d[z][cur]+1;
                            q.push(nxt);
                        }
                    }
                }
            }
        }
        else
        {
            int ans=INF;
            for(int i=1; i<=h; i++)
                ans=min(ans,d[i][x*m+y]+abs(z-i));
            printf("%d\n",ans);
        }
    }
    return 0;
}

发布了42 篇原创文章 · 获赞 6 · 访问量 4028

猜你喜欢

转载自blog.csdn.net/qq_43383246/article/details/99434210