我要去看流星雨(并查集)

我要去看流星雨
Problem:F
Time Limit:1500ms
Memory Limit:65535K
Description
“天琴座流星雨是已知最古老的流星雨之一,拥有2700年的观测历史。”天文学博士、科普作家高爽称,最早有记录的天琴座流星雨可以追溯到公元前687年,在《春秋》中就有所记载。

这几天,天琴座流星雨又刷了一次屏:不少网友表示对这个历史悠久的流星雨十分期待。

在2020年的4月22日,天琴座流星雨如约而至。在这个古老且浪漫的流星雨面前,谁能不动心呢???这时候哈利波特和赫敏穿越到现代去美丽的林大观看这场流星雨。

​这时,赫敏就问哈利波特一个难题,在这些流星雨能划分为几个区域呢?在星空中,任意相邻或坐标相同的流星引力之差不大于M,则称这两颗流星处于同一区域。可是哈利波特不会呀,只好来请教聪明的你了。

​ 相邻的定义为:每颗流星的上、下、左、右、前、后的六个相邻位置被称为相邻。

​ 现在让你求出这片星空的区域数量和最大的星空区域中的流星数量。
Input
第一行 n ,代表这个星空的流星数量。(n<=10000)

第二行整数 m ,代表亮度。(m<=1e9)

第三行到第 n+2 行,给定每一颗流星的坐标(x,y,z)和引力v。(0<=x,y,z,v<=1e9)
Output
一行整数 k 和 w ,代表区域数量和最大星空区域中的流星数量。
Sample Input
6
2
1 1 1 3
1 0 1 1
1 0 2 5
1 0 3 4
1 2 1 10
1 3 1 8
Sample Output
3 2

在这里插入图片描述

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const double PI = acos(-1.0);
int n, m, ans;
int s[10005], high[10005]; //并查集
bool flag[10];
struct star //结构体存储数据
{
    int x, y, z, v;
} a[10005];

int find_set(int x) //找到父结点,压缩状态
{
    if (x != s[x])
        s[x] = find_set(s[x]);
    return s[x];
}

void union_set(int x, int y) //合并
{
    x = find_set(x);
    y = find_set(y);
    if (x != y)
    {
        s[x] = s[y];        //x并到y上
        high[y] += high[x]; //将高度进行合并
        high[x] = 0;        //被合并的要清零
    }
}
bool check(int i, int j) //根据题意进行判断两点间的关系
{
    int dis = 0;
    dis += abs(a[i].x - a[j].x);
    dis += abs(a[i].y - a[j].y);
    dis += abs(a[i].z - a[j].z);
    if (dis <= 1 && abs(a[i].v - a[j].v) <= m)
        return 1;
    return 0;
}
int main()
{
    ios::sync_with_stdio(false);
    cin >> n >> m;
    for (int i = 1; i <= n; i++)
    {
        cin >> a[i].x >> a[i].y >> a[i].z >> a[i].v;
        s[i] = i;    //并查集初始化
        high[i] = 1; //初始化高度
    }
    for (int i = 1; i <= n; i++) //遍历两个点之间的关系
        for (int j = 1; j <= n; j++)
        {
            if (i == j)
                continue;
            if (check(i, j))     //检查
                union_set(i, j); //合并
        }
    int max_high = -1; //找到最大的高度
    for (int i = 1; i <= n; i++)
        if (s[i] == i)
        {
            ++ans; //有多少个区域
            max_high = max(high[i], max_high);
        }
    cout << ans << ' ' << max_high << endl;
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值