[2019牛客多校训练第8场]Distance

链接:https://ac.nowcoder.com/acm/contest/888/D
来源:牛客网

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 524288K,其他语言1048576K

64bit IO Format: %lld

分数:2500 前期题但是貌似没想到

题目描述

Gromah and LZR have entered the fourth level. There is a blank cube with size n × m × h n\times m\times h hanging on the wall.

Gromah soon finds a list beside the cube, there are q _{}q​ instructions in the list and each instruction is in one of the following two formats:

  1. ( 1 , x , y , z ) _{}(1,x,y,z) ​, meaning to add a tag on position ( x , y , z ) _{}(x,y,z) ​ in the cube
  2. ( 2 , x , y , z ) _{}(2,x,y,z) ​, meaning to determine the minimum Manhattan Distance to the given position ( x , y , z ) _{}(x,y,z) ​ among all tagged positions

Manhattan Distance between two positions ( x 1 , y 1 , z 1 ) , ( x 2 , y 2 , z 2 ) (x_1, y_1, z_1), (x_2, y_2, z_2) is defined as x 1 x 2 + y 1 y 2 + z 1 z 2 |x_1 - x_2| + |y_1 - y_2| + |z_1 - z_2| .

LZR also finds a note board saying that the password of this level is the sequence made up of all results of the instructions in format 2.

Please help them get all results of the instructions in format 2.
输入描述:

The first line contains four positive integers n , m , h , q _{}n,m,h,q ​, denoting the sizes in three dimensions of the cube and the number of instructions.

Following q _{}q ​ lines each contains four positive integers o p , x , y , z _{}op,x,y,z​ , where o p = 1 _{}op=1 ​ means to add a tag on ( x , y , z ) _{}(x,y,z) ​ while o p = 2 _{}op=2 ​ means to make a query on ( x , y , z ) _{}(x,y,z) ​.
1 n × m × h , q 1 0 5 , 1 x n , 1 y m , 1 z h 1 \le n\times m\times h, q\le 10^5, 1 \le x \le n, 1 \le y \le m, 1 \le z \le h

It is guaranteed that the first instruction is in format 1 and that no position will be tagged more than once.

输出描述:

For each instruction in format 2, output the answer in one line.

示例1
输入

3 3 3 4
1 1 1 1
2 2 3 3
1 3 1 1
2 3 3 2

输出

5
3

For the first query, there is only one tagged position ( 1 , 1 , 1 ) _{}(1,1,1) ​ currently, so the answer is 1 2 + 1 3 + 1 3 = 5 _{}∣1−2∣+∣1−3∣+∣1−3∣=5 ​.
For the second query, ( 3 , 1 , 1 ) _{}(3,1,1) ​ is the nearest tagged position, so the answer is 3 3 + 1 3 + 1 2 = 3 _{}∣3−3∣+∣1−3∣+∣1−2∣=3​ .

题意:
给定一个长宽高分别为n,m,h的三维空间
有两种操作,一种是往空间中放一个点,第二种是询问一个点,问空间中与这个点距离最近的点的距离。
题解:
n × m × h < = 1 0 5 n\times m\times h <= 10^5 这是个好事
假设我们的所有询问都在放置之后,那么我们可以放完之后做一次bfs来更新所有点的答案,但是现在查询和更新是混淆的。那么我们每次插入一个点的时候,就直接从这个点开始bfs更新能够更新的距离(跟最短路很像),然后查询的时候直接O(1)查询答案即可。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
int dx[8]={1,-1,0,0,0,0},
    dy[8]={0,0,1,-1,0,0},
    dz[8]={0,0,0,0,1,-1};
struct point{
    int x,y,z;
    point(){}
    point(int _x,int _y,int _z){
        x=_x;
        y=_y;
        z=_z;
    }
};
vector<vector<vector<int> > >dis;
queue<point>q;
int n,m,h,Q;
int ans[100004];

void bfs(){
    while(!q.empty()){
        point now=q.front();q.pop();
        int nd=dis[now.x][now.y][now.z];
        for(int i=0;i<6;i++){
            point np=now;
            np.x+=dx[i];np.y+=dy[i];np.z+=dz[i];
            if(np.x<0||np.x>=n||np.y<0||np.y>=m||np.z<0||np.z>=h){
                continue;
            }
            if(dis[np.x][np.y][np.z]==-1||dis[np.x][np.y][np.z]>nd+1){
                dis[np.x][np.y][np.z]=nd+1;
                q.push(np);
            }
        }
    }
}
int main(){
    scanf("%d%d%d%d",&n,&m,&h,&Q);
    for(int i=1;i<=n;i++){
        vector<vector<int> >cc;
        for(int j=1;j<=m;j++){
            vector<int>pp;
            for(int k=1;k<=h;k++){
                pp.push_back(-1);
            }
            cc.push_back(pp);
        }
        dis.push_back(cc);
    }
    int cnt=0;
    for(int i=1;i<=Q;i++){
        int t,x,y,z;
        scanf("%d%d%d%d",&t,&x,&y,&z);
        x--;y--;z--;
        if(t==1){
            q.push(point(x,y,z));
            dis[x][y][z]=0;
            bfs();
        }
        else{
            printf("%d\n",dis[x][y][z]);
        }
    }
    return 0;
}
发布了302 篇原创文章 · 获赞 19 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/dxyinme/article/details/99412499