三维差分+前缀和
Recently, Zayin became obsessed with a tower defense game called Arknights. The most special level is the 5th level of chapter 4: Don’t panic. The most special thing about this level is that an enemy will continue taking radioactive damage after passing through the Active Originiums. As the most handsome man in the world, he tried to put obstacles in various positions, making all the enemies to be killed before reaching the end. After many attempts, he finally won the three stars clearance award.
Interestingly, that night Zayin dreamt that he had become the King Slayer (the leader of enemies). In the dream, the map of the tower defense game becomes a cube with edge length n. Zayin can take a step forward, backward, up, down, left or right from his current position every second, but can't get out of the map or walk through a grid of obstacles.
As in the original game, the player, who wants to kill all the enemies, can put obstacles many times. In particular, in the dream, every time players can place obstacles at all the coordinates (x,y,z) which satisfies a≤x≤d, b≤y≤e, c≤z≤f, and has no obstacles yet.
Now, Zayin knows that the player will place obstacles mm times and the locations of each time. In order to avoid dying on the way, Zayin wants to go to the end as fast as possible. But unfortunately, Zayin got lost for so long that all the obstacles were placed. Now, Zayin asks you for help. Can you help him get out of the map as quickly as possible?
Input
The first line of input contains an integer TT(1≤T≤5), denoting the number of test cases.
Each test case starts with two integers nn and mm in a line, where nn is the size of the map and mm is the number of times the player puts obstacles. (1≤n≤100, 1≤m≤1000)
The next mm lines contain six integers a,b,c,d,e,fa,b,c,d,e,f in each line, denoting the range of obstacles the player puts. (1≤a≤d≤n, 1≤b≤e≤n, 1≤c≤f≤n)
Then there are six integers x1,y1,z1, x2,y2,z2. The first three integers represent where Zayin is now, and the last three integers represent where the end point is.
Output
For each testcase, output an integer in a line, denoting how many seconds at least Zayin need to go to the end. If Zayin can't go to the end, output -1.
Samples
3 3 0 1 1 1 3 3 3 3 1 2 1 1 2 3 3 1 1 1 3 3 3 3 3 2 1 1 2 2 3 1 1 2 2 3 2 1 2 2 3 3 2 1 1 1 1 1 3
6 -1 14
题解
这个题的意思就是说给你一个三维的坐标系,然后起点是(x1,y1,z1)终点是(x2,y2,z2).
然后给了你m个限制,每个限制就是一个a,b,c,d,e,f,g,其中每一个的a≤x≤d, b≤y≤e, c≤z≤f,都是不能过的
然后问你从起点到终点最短路
这个题首先一眼看出是一个bfs的题,然后最主要的这个题就是怎么弄那些不能走的区域,这个就相当于一维里面的[l,r]不能走一样这个用一维差分+前缀和,然后这个题就是三维差分+前缀和
#include<iostream> #include<algorithm> #include<queue> #include<cstring> using namespace std; const int maxn=110; int s[maxn][maxn][maxn]; int sum[maxn][maxn][maxn]; int dx[]={0,0,0,0,1,-1}; int dy[]={0,0,1,-1,0,0}; int dz[]={1,-1,0,0,0,0}; int n,m; int xx1,yy1,zz1,xx2,yy2,zz2; struct node{ int x,y,z; int st; }; int bfs(int x,int y,int z){ queue<node>q; q.push({x,y,z,0}); if(sum[x][y][z]){ return -1; } sum[x][y][z]=1; while(!q.empty()){ node top=q.front(); q.pop(); for(int i=0;i<6;i++){ int xx=top.x+dx[i],yy=top.y+dy[i],zz=top.z+dz[i]; if(xx>=1&&xx<=n&&yy>=1&&yy<=n&&zz>=1&&zz<=n&&!sum[xx][yy][zz]){ // cout<<xx<<" "<<yy<<" "<<zz<<endl; if(xx==xx2&&yy==yy2&&zz==zz2){ return top.st+1; } sum[xx][yy][zz]=1; q.push({xx,yy,zz,top.st+1}); } } } return -1; } int main(){ int t; cin>>t; while(t--){ memset(s,0,sizeof(s)); memset(sum,0,sizeof(sum)); cin>>n>>m; for(int i=1;i<=m;i++){ int a,b,c,d,e,f; scanf("%d%d%d%d%d%d",&a,&b,&c,&d,&e,&f); s[a][b][c]--; s[a][b][f+1]++; s[a][e+1][c]++; s[a][e+1][f+1]--; s[d+1][b][c]++; s[d+1][b][f+1]--; s[d+1][e+1][c]--; s[d+1][e+1][f+1]++; } cin>>xx1>>yy1>>zz1>>xx2>>yy2>>zz2; for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ for(int k=1;k<=n;k++){ sum[i][j][k]=(sum[i-1][j][k]+sum[i][j-1][k]+sum[i][j][k-1])-(sum[i-1][j-1][k]+sum[i-1][j][k-1]+sum[i][j-1][k-1])+sum[i-1][j-1][k-1]+s[i][j][k]; } } } int ans=bfs(xx1,yy1,zz1); cout<<ans<<endl; } }