[CCPC 2019] 厦门 | Zayin and Obstacles | 三维差分前缀 + bfs

Description

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 m 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 T( 1 ≤ T ≤ 5 1≤T≤5 1T5), denoting the number of test cases.
Each test case starts with two integers n and m in a line, where n is the size of the map and m is the number of times the player puts obstacles. ( 1 ≤ n ≤ 100 , 1 ≤ m ≤ 1000 1≤n≤100, 1≤m≤1000 1n100,1m1000)
The next m lines contain six integers a,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 ) (1≤a≤d≤n, 1≤b≤e≤n, 1≤c≤f≤n) (1adn,1ben,1cfn)
Then there are six integers x 1 , y 1 , z 1 , x 2 , y 2 , z 2 x1,y1,z1, x2,y2,z2 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

Input Copy

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

Output

6
-1
14

Source

2019 CCPC xiamen onsite

根据容斥求出可以标记处三维空间中哪一块有障碍物,然后用三层for就可以枚举出

ll n,m,k;
int s[107][107][107],ss[107][107][107];
int stx,sty,stz,edx,edy,edz;
bool edge(int x,int y,int z){
	if(x < 1 || x > n) return false;
	if(y < 1 || y > n) return false;
	if(z < 1 || z > n) return false;
	return true;
}
struct node{
	int x,y,z;
};
int dx[6]={0,0,0,0,1,-1};
int dy[6]={0,0,1,-1,0,0};
int dz[6]={1,-1,0,0,0,0};
bool vis[107][107][107];
int dis[107][107][107];
void bfs(int x,int y,int z){
	queue<node> que;
	que.push({x,y,z});
	vis[x][y][z] = 1;
	dis[x][y][z] = 0;
	while(que.size()){
		node frt = que.front();
		que.pop();
		if(frt.x == edx && frt.y == edy && frt.z == edz) return ;
		for(int i=0;i<6;i++){
			int tx = frt.x + dx[i];
			int ty = frt.y + dy[i];
			int tz = frt.z + dz[i];
			if(ss[tx][ty][tz]) continue;
			if(!vis[tx][ty][tz] && edge(tx,ty,tz)) {
				que.push({tx,ty,tz});
				vis[tx][ty][tz] = 1;
				dis[tx][ty][tz] = dis[frt.x][frt.y][frt.z] + 1;
			}
		}
	}
	
}
int main() {
	int _ = read;
	while(_ --){
		memset(s,0,sizeof s);
		memset(ss,0,sizeof ss);
		memset(vis,0,sizeof vis);
		memset(dis,0,sizeof dis);
		n = read,m=read;
		for(int i=1;i<=m;i++){
			int a=read,b=read,c=read,d=read,e=read,f=read;
			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]++;
		}
		stx=read,sty=read,stz=read;
		edx=read,edy=read,edz=read;
		if(stx == edx && sty == edy && stz == edz) {
			puts("0");
			continue;
		}
		for(int i=1;i<=n;i++){
			for(int j=1;j<=n;j++){
				for(int k=1;k<=n;k++){
					ss[i][j][k]=(ss[i-1][j][k]+ss[i][j-1][k]+ss[i][j][k-1])-
					(ss[i-1][j-1][k]+ss[i-1][j][k-1]+ss[i][j-1][k-1])+ss[i-1][j-1][k-1]+s[i][j][k];
				}
			}
		}
		bfs(stx,sty,stz);
		if(dis[edx][edy][edz] >= 100000000 || dis[edx][edy][edz] == 0) {
			puts("-1");
		}else printf("%d\n",dis[edx][edy][edz]);
	}
	return 0;
}
/**
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
**/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值