Unusual Minesweeper

题意

给定n颗炸弹,每颗炸弹有一个左边x,y以及一个爆炸时间,一个炸弹爆炸会牵引不超过k距离的其它炸弹爆炸(如下图k=2时),每秒可以点燃一个炸弹,问最少多少秒所有炸弹爆炸。
在这里插入图片描述

题解

假如没有牵连爆炸这个限制,这道题就变成一个简单的贪心问题,排序每次选择爆炸时间最长的一个点燃,当时间已经比下一个时间长时就是答案,那么有了牵连爆炸的限制后该怎么做呢?其实我们可以把会一起爆炸的炸弹看成一个炸弹,也就可以用并查集来维护,然后它们爆炸的时间就是集合中爆炸时间最短的那个。再之后就变成那个简单的贪心问题了。

#include <bits/stdc++.h>
using namespace std;
#define mp make_pair
#define fr first
#define sc second
#define ll long long 
const long long inf = 1e18;
long long n, d, nn, a[200069], dsu[200069], ex[200069];
pair<pair<long long, long long>, long long> as[200069];//存储每颗雷的信息
long long fd(long long x)//并查集
{
	if (dsu[x] != x)
	{
		dsu[x] = fd(dsu[x]);
	}
	return dsu[x];
}
int main()
{
	long long t, rr, i, ii, l, y, x, p, z;

	scanf("%lld", &t);//组数
	for (rr = 0; rr < t; rr++)
	{
		scanf("%lld%lld", &n, &d);//n颗雷 半径为d的地雷会爆炸
		for (i = 1; i <= n; i++)
		{
			scanf("%lld%lld%lld", &x, &y, &a[i]);//a存储下班为i的爆炸时间为i
			as[i] = { {x,y},i };//雷的信息,y,x,第i颗雷
			dsu[i] = i;//并查集初始化
		}
		for (ii = 0; ii < 2; ii++)//两次,一次跑x一次跑y
		{
			sort(as + 1, as + n + 1);//根据第一坐标优先其次第二坐标优先在者编号优先从小到大排序

			for (i = 1; i <= n; i++)
			{
				y = as[i].fr.fr;//x/y
				x = as[i].fr.sc;//y/x
				p = as[i].sc;//当前 编号

				if (i > 1 && y == as[i - 1].fr.fr && x - as[i - 1].fr.sc <= d)//一个坐标相同,另外一个坐标相差为d就为一个集合的雷
				{
					l = as[i - 1].sc;
					a[fd(p)] = min(a[fd(p)], a[fd(l)]);//爆炸时间为较小的那个
					dsu[fd(l)] = fd(p);//合并成一个集合p
				}
			}
			for (i = 1; i <= n; i++)//交换x,y坐标再跑一次
			{
				swap(as[i].fr.fr, as[i].fr.sc);
			}
		}
		//接下来的问题就变成了有nn个爆炸时间不同的雷,每秒可以点爆一个,最快几秒可以点爆完成,贪心的去做,每次都点爆离当前时间最小的一颗雷即可
		nn = 0;
		for (i = 1; i <= n; i++)
		{
			if (fd(i) == i)
			{
				nn++;
				ex[nn] = a[i];
			}
		}
		sort(ex + 1, ex + nn + 1, greater<long long>());
		ex[nn + 1] = -inf;
		for (i = 1; i <= nn; i++)
		{
			if (ex[i + 1] <= i - 1)break;
		}
		printf("%lld\n", i-1);
	}
}

.equals(Obje​​ct)方法在Java中用于比较两个对象是否相等。它检查两个对象的内容是否相同而不是引用是否相同。通常,我们可以使用"=="运算符来比较基本数据类型的值或判断两个对象引用是否相等。但是,对于比较复杂的对象,比如自定义的类对象,它们可能具有相同的属性值,但却不被认为是相等的,因为它们不是同一个对象的实例。 .equals(Obje​​ct)方法为我们提供了一种自定义比较两个对象内容的方式。这个方法是从Object类继承而来的,因此在所有的类中都可用。某些类,比如String类、Integer类等,已经重写了.equals(Obje​​ct)方法,以便实现比较它们的内容。但是,对于自定义的类,如果不重写.equals(Obje​​ct)方法的话,将继承Object类的默认实现,即比较两个对象的引用是否相等。 与"=="运算符相比,.equals(Obje​​ct)方法的作用更灵活、更具体。它可以根据具体的比较规则来决定两个对象是否相等。但是,由于.equals(Obje​​ct)方法的默认实现比较对象的引用,所以在自定义类中使用.equals(Obje​​ct)方法时,需要注意重写该方法以实现我们自己的比较逻辑。 综上所述,.equals(Obje​​ct)方法在Java中是相对不寻常的,因为大部分时候我们可以使用"=="运算符来比较对象引用是否相等。然而,在比较复杂对象内容时,.equals(Obje​​ct)方法提供了一种更具体、更灵活的比较方式。这是Java中为了满足不同需求而提供的一种对象比较工具。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值