#P2108. 第4题-小美玩地雷
-
1000ms
Tried: 165
Accepted: 28
Difficulty: 7
所属公司 :
美团
时间 :2024年9月21日
-
算法标签>DFS
第4题-小美玩地雷
思路
首先将地雷按照爆炸时间排序,然后用二重循环检查每个地理都能引爆哪些地雷,然后依次按照时间引爆,引爆的时候使用dfs递归进行引爆,引爆过的地理就再f中标记为false,累加实际爆炸的地雷数,超过m就输出当前地雷爆炸时间就可以了
代码
python
def main():
t = int(input())
for _ in range(t):
n, m = map(int, input().split())
a = [list(map(int, input().split())) for _ in range(n)]
a.sort(key=lambda x: x[2])
g = [[] for _ in range(n)]
vis = [True] * n
for i in range(n):
for j in range(n):
if abs(a[i][0] - a[j][0]) + abs(a[i][1] - a[j][1]) <= a[i][-1]:
g[i].append(j)
def dfs(u):
if not vis[u]:
return 0
vis[u] = False
return 1 + sum(dfs(v) for v in g[u])
total = 0
for i in range(n):
total += dfs(i)
if total >= m:
print(a[i][2])
break
main()
java
import java.util.*;
public class Main {
static final int MAX_N = 2005;
static boolean[] vis = new boolean[MAX_N];
static List<Integer>[] g = new ArrayList[MAX_N];
static {
for (int i = 0; i < MAX_N; i++) {
g[i] = new ArrayList<>();
}
}
static int dfs(int u) {
if (!vis[u]) return 0;
vis[u] = false;
int total = 1;
for (int v : g[u]) {
total += dfs(v);
}
return total;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int t = scanner.nextInt();
while (t-- > 0) {
int n = scanner.nextInt();
int m = scanner.nextInt();
int[][] a = new int[n][4];
for (int i = 0; i < n; i++) {
a[i][0] = scanner.nextInt();
a[i][1] = scanner.nextInt();
a[i][2] = scanner.nextInt();
a[i][3] = scanner.nextInt();
}
Arrays.sort(a, Comparator.comparingInt(o -> o[2]));
for (int i = 0; i < n; i++) {
g[i].clear();
vis[i] = true;
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if ((long) Math.abs(a[i][0] - a[j][0]) + (long) Math.abs(a[i][1] - a[j][1]) <= (long) a[i][3]) {
g[i].add(j);
}
}
}
int total = 0;
for (int i = 0; i < n; i++) {
total += dfs(i);
if (total >= m) {
System.out.println(a[i][2]);
break;
}
}
}
scanner.close();
}
}
c++
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;
const int MAX_N = 2005;
bool vis[MAX_N];
vector<int> g[MAX_N];
int dfs(int u) {
if (!vis[u]) return 0;
vis[u] = false;
int total = 1;
for (int v : g[u]) {
total += dfs(v);
}
return total;
}
int main() {
int t;
cin >> t;
while (t--) {
int n, m;
cin >> n >> m;
vector<vector<int>> a(n, vector<int>(4));
for (int i = 0; i < n; ++i) {
cin >> a[i][0] >> a[i][1] >> a[i][2] >> a[i][3];
}
sort(a.begin(), a.end(), [](const vector<int>& x, const vector<int>& y) {
return x[2] < y[2];
});
for (int i = 0; i < n; ++i) {
g[i].clear();
vis[i] = true;
}
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
if (1ll*abs(a[i][0] - a[j][0]) + 1ll*abs(a[i][1] - a[j][1]) <= 1ll*a[i][3]) {
g[i].push_back(j);
}
}
}
int total = 0;
for (int i = 0; i < n; ++i) {
total += dfs(i);
if (total >= m) {
cout << a[i][2] << endl;
break;
}
}
}
return 0;
}
题目内容
小美来到了一个无限大的二维平面上,平面中有n个地雷,其中第i个地雷的坐标为(xi,yi),且第ti秒它就会爆炸,它的爆炸冲击会引爆和它曼哈顿距离在ki以内的所有其它地雷。小美现在想知道,至少需要多长时间,才能使得至少m个地雷爆炸。 (x1,y1) 和(x2,y2)的曼哈顿距离定义为:dist=∣x1−x2∣+∣y1−y2∣。
输入描述
每个测试文件均包含多组测试数据。第一行输入一个整数T(1≤T≤100)代表数据组数,每组测试数据描述如下: 第一行输入两个整数n,m(1≤m≤n≤2000),表示平面中地雷的个数和至少需要m个地雷爆炸。 此后n行,第i行输入四个整数 xi,Yi,ti,ki(−109≤x,y≤109,0≤ti≤109,0≤ki≤2x109),描述第i个地雷。 除此之外,保证所有的n之和不超过3000。
输出描述
在一行上输出一个整数,代表最少的等待时间
样例1
输入
1
3 3
0 0 0 1
1 0 1 1
2 2 3 10
输出
3