题目描述 你现在正在参加一次军事模拟训练。训练的地图是一个网格图,包含n行和m列。每个网格要么是空的,要么是障碍物。空格可能包含一件武器。设(x,y)是第x行和第y列上的网格。如果你在网格(x,y)处,则你可以移动到网格(x′,y′),当且仅当1≤x′≤n,1≤y′≤m,|x−x′|+|y−y′|=1,并且(x′,y′)不是障碍。行动需要一秒钟。
你目前位于网格(px,py),敌人位于(bx,by)。除非你达到网格(bx,by),否则敌人永远不会移动。如果你达到网格(bx,by),那么你就会被敌人消灭,并且输掉这次训练。
你一开始没有武器,但k个武器被放置在地图中。每件武器都被放置在一个空格中,武器所在的格子两两不同,如果你到达一个有武器的各自,你就可以装备这件武器。第i-件武器的攻击距离为di,这意味着如果你目前在(x,y),并且装备了这件武器,他可以攻击任何网格(x′,y′) 当且仅当 √ (x−x′)2+(y−y′)2 ≤di。并且这会立即消灭网格(x′,y′)处的敌人。装备武器不需要时间,攻击也不需要时间。你可以装备任意数量的武器,随时使用。
请你计算你消灭敌人的最小时间,或者输出这是不可能的任务。
输入格式 输入包含多组数据。
第一行包含一个整数T,表示数据的组数。
对于每组数据,第一行包含三个整数n,m,k。
第二行包含四个整数px,py,bx,by,表示你和敌人的位置。保证px!=bx或py!=by。
接下来n行,每一行都包含一个长度为m的字符串。第i行上的第j个字符是“.”或“#”,表示第i行,第j列是空网格或障碍物。
接下来k行中的第i行包含三个整数xi,yi,di,表示武器i位于(xi,yi)并且具有攻击距离di。
输出格式 对每组数据输出一行,代表消灭敌人需要花费的最小时间,或者输出−1代表不可能。
输入样例1 2 4 4 2 1 1 4 4 ...# ..## .### ###. 1 1 3 1 3 5 3 3 1 3 3 1 1 .##
##.
3 3 1
输出样例1
2
-1
样例解释:
在(1,1)拿起攻击距离为3的武器,之后花费2的时间走到(2,2),就可以攻击(4,4) 对于第二组,不存在攻击的方法
数据范围 对于30%的数据,n,m≤20,T≤5;
对于60%的数据,n≤100,T≤5;
对于所有数据,1≤T≤10,1≤n,m≤400,保证∑nm≤1.6×105,保证所有坐标合法,武器攻击距离0≤di≤109,不会有两个武器在同一个格子,你初始位置和敌人的位置不会重合。
我的代码
#include"bits/stdc++.h"
using namespace std;
inline int read(){
int xr = 0, f = 1;
char cr;
while (cr = getchar(), cr < '0' or cr > '9')
{
if (cr == '-')
{
f = -1;
}
}
while (cr >= '0' and cr <= '9')
{
xr = (xr << 3) + (xr << 1) + (cr ^ 48);
cr = getchar();
}
return xr * f;
}
const int tx[4] = {0, 0, 1, -1};
const int ty[4] = {1, -1, 0, 0};
int T;
int n, m, k;
int px, py, bx, by;
char s[410][410];
int f[410][410];
int wq = 0;
int dfs(int x, int y, int sec){
int ans = INT_MAX;
if(s[x][y] == '#') return -1;
if(x == bx && y == by) return -1;
if(x < 1 || x > n || y < 1 || y > m) return -1;
int temp = wq;
wq = max(f[x][y], wq);
if(sqrt((x - bx) * (x - bx) + (y - by) * (y - by)) <= wq){
return sec;
}
s[x][y] = '#';
for(int i = 0; i < 4; i ++){
int nx = x + tx[i];
int ny = y + ty[i];
int lllll = dfs(nx, ny, sec + 1);
if(lllll) ans = min(lllll, ans);
}
s[x][y] = '.';
wq = temp;
return ans;
}
signed main(){
T = read();
while(T--){
n = read(); m = read(); k = read();
if(k == 0){
cout << -1 << endl;
continue;
}
px = read(); py = read();
bx = read(); by = read();
for(int i = 1; i <= n; i ++){
for(int j = 1; j <= m; j ++){
cin >> s[i][j];
}
}
int flag = 1;
for(int i = 1; i <= k; i ++){
int x, y;
x = read(); y = read();
f[x][y] = read();
if(s[x][y] != '#') flag = 0;
}
if(flag){
cout << -1 << endl;
continue;
}
cout << dfs(px, py, 0) << endl;
}
return 0;
}
求调玄一关QwQ (不会用Markdown, dalao轻喷)