链接: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 n×m×h hanging on the wall.
Gromah soon finds a list beside the cube, there are q _{}q q instructions in the list and each instruction is in one of the following two formats:
- ( 1 , x , y , z ) _{}(1,x,y,z) (1,x,y,z), meaning to add a tag on position ( x , y , z ) _{}(x,y,z) (x,y,z) in the cube
- ( 2 , x , y , z ) _{}(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) (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) (x1,y1,z1),(x2,y2,z2) 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| ∣x1−x2∣+∣y1−y2∣+∣z1−z2∣.
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 n,m,h,q, denoting the sizes in three dimensions of the cube and the number of instructions.
Following
q
_{}q
q lines each contains four positive integers
o
p
,
x
,
y
,
z
_{}op,x,y,z
op,x,y,z, where
o
p
=
1
_{}op=1
op=1 means to add a tag on
(
x
,
y
,
z
)
_{}(x,y,z)
(x,y,z) while
o
p
=
2
_{}op=2
op=2 means to make a query on
(
x
,
y
,
z
)
_{}(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
1≤n×m×h,q≤105,1≤x≤n,1≤y≤m,1≤z≤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)
(1,1,1) currently, so the answer is
∣
1
−
2
∣
+
∣
1
−
3
∣
+
∣
1
−
3
∣
=
5
_{}∣1−2∣+∣1−3∣+∣1−3∣=5
∣1−2∣+∣1−3∣+∣1−3∣=5.
For the second query,
(
3
,
1
,
1
)
_{}(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
∣3−3∣+∣1−3∣+∣1−2∣=3.
题意:
给定一个长宽高分别为n,m,h的三维空间
有两种操作,一种是往空间中放一个点,第二种是询问一个点,问空间中与这个点距离最近的点的距离。
题解:
n
×
m
×
h
<
=
1
0
5
n\times m\times h <= 10^5
n×m×h<=105这是个好事
假设我们的所有询问都在放置之后,那么我们可以放完之后做一次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;
}