首页 > 其他分享 >30. 区间交集

30. 区间交集

时间:2024-12-30 17:26:07浏览次数:3  
标签:idx 交集 30 ++ int 公共 区间

题目描述

给定一组闭区间,其中部分区间存在交集。

任意两个给定区间的交集,称为公共区间(如:[1,2],[2,3]的公共区间为[2,2],[3,5],[3,6]的公共区间为[3,5])公共区间之间若存在交集,则需要合并(如:[1,3],[3,5]区间存在交集[3,3],需合并为[1,5])。按升序排列输出合并后的区间列表

输入描述

组区间列表

区间数为 N: O<=N<=1000。

区间元素为 X:-10000<=X<=10000。

输出描述

升序排列的合并区间列表

备注

1、区间元素均为数字,不考虑字母、符号等异常输入。

2、单个区间认定为无公共区间。

用例

一、问题分析

首先读题,仔细看描述中的内容,发现需求是

1.给定一组闭区间,其中部分区间存在交集。

2.任意两个给定区间的交集,称为公共区间。

3.公共区间之间若存在交集,则需要合并,按升序排列输出合并后的区间列表

4.输入描述:组区间列表区间数为N,大于等于0小于等于1000.

区间元素为X,大于等于-10000小于等于10000

5.输入描述:升序排列的合并区间列表

6.备注:(1)区间元素均为数字,不考虑字母、符号等异常输入

(2)单个区间认为无公共区间。

二、解题思路

1.首先我们读取数据int N;区间数

scanf("%d", &N);

2.之后开始读取区间元素

int X[N][2];

for(int i = 0; i < N; i++) {

scanf("%d %d", &X[i][0], &X[i][1]);

}

3.然后我们计算公共区间

int Y[N * N][2];

int idx = 0;

for(int i = 0; i < N; i++) {

for(int j = i + 1; j < N; j++) {

// 如果比较小的值大于下一个区间比较大的值的时候没有交集

// 如果比较大的值小于下一个区间比较小的值的时候没有交集

// 比较小或者比较大的值有一个在下一个区间内的时候有交集

// 如果比较小的值大于下一个区间比较小的值但是小于下一个区间比较大的值

// 证明至少有一个数相交,公共区间从X[i][0]开始

// 比如第一个区间是1 3 第二个区间是0 4,1比0大比4小,3比4小,所以整个第一个区间都是贡藕给你区间

if(X[i][0] >= X[j][0] && X[i][0] <= X[j][1]) {

// 如果前一个区间的比较大的值小于等于后一个区间比较大的值,那么整个前一个区间都是公共区间

if(X[i][1] <= X[j][1]) {

Y[idx][0] = X[i][0];

Y[idx++][1] = X[i][1];

//如果前一个区间比较大的值大于后一个区间比较大的值,那么它们的公共区间是从前一个数字比较小的值到后一个数字比较大的值

else {

Y[idx][0] = X[i][0];

Y[idx++][1] = X[j][1];

}

}

// 比如第一个区间是1 3 第二个区间是2 4,此时已经证明1不在2,4之间,

// 且3在2,4之间,那么我们的交集就是2,3

else if(X[i][1] >= X[j][0] && X[i][1] <= X[j][1]) {

Y[idx][0] = X[j][0];

Y[idx++][1] = X[i][1];

}

else if(X[j][0] >= X[i][0] && X[j][0] <= X[i][1]) {

if(X[j][1] <= X[i][1]) {

Y[idx][0] = X[j][0];

Y[idx++][1] = X[j][1];

else {

Y[idx][0] = X[j][0];

Y[idx++][1] = X[i][1];

}

}

else if(X[j][1] >= X[i][0] && X[j][1] <= X[i][1]) {

Y[idx][0] = X[i][0];

Y[idx++][1] = X[j][1];

}

}

}

4.然后我们要合并公共区间,首先我们对公共空间进行一个排序

qsort(Y, idx, sizeof(Y[0]), compare);

int Z[idx][2];

int idxz = 0;

for(int i = 0; i < idx; i++) {

Z[idxz][0] = Y[i][0];

while(i < idx && Y[i][1] >= Y[i + 1][0]) {

i++;

}

i--;

Z[idxz++][1] = Y[i][1];

}

5.输出结果

if(idx == 0) printf("None\n");

else {

for(int i = 0; i < idxz; i++) {

printf("%d %d\n", Z[i][0], Z[i][1]);

}

}

三、具体步骤

使用的语言是C

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 比较函数,用于qsort按照区间起始值从小到大排序
int compare(const void* a, const void* b) {
    int (*arr_a)[2] = (int (*)[2])a;
    int (*arr_b)[2] = (int (*)[2])b;
    int result = (*arr_a)[0] - (*arr_b)[0];
    if(result == 0) {
        return ((*arr_a)[1] - (*arr_b[1]));
    }
    return result;
}

int main() {
    int N;
    scanf("%d", &N);
    // 动态分配内存用于存储区间数据
    int** X = (int**)malloc(N * sizeof(int*));
    for (int i = 0; i < N; i++) {
        X[i] = (int*)malloc(2 * sizeof(int));
    }

    // 读取区间元素
    for (int i = 0; i < N; i++) {
        scanf("%d %d", &X[i][0], &X[i][1]);
    }

    // 计算公共区间,使用动态分配内存的数组来存储
    int** Y = (int**)malloc(N * N * sizeof(int*));
    for (int i = 0; i < N * N; i++) {
        Y[i] = (int*)malloc(2 * sizeof(int));
    }
    int idx = 0;
    for (int i = 0; i < N; i++) {
        for (int j = i + 1; j < N; j++) {
            // 简化的区间相交判断逻辑,先确定两个区间的最小值和最大值
            int min_start = (X[i][0] < X[j][0]) ? X[i][0] : X[j][0];
            int max_start = (X[i][0] > X[j][0]) ? X[i][0] : X[j][0];
            int min_end = (X[i][1] < X[j][1]) ? X[i][1] : X[j][1];
            int max_end = (X[i][1] > X[j][1]) ? X[i][1] : X[j][1];

            if (max_start <= min_end) {
                // 存在交集,计算公共区间并存入Y数组
                Y[idx][0] = max_start;
                Y[idx][1] = min_end;
                idx++;
            }
        }
    }

    // 对公共区间数组Y进行排序
    qsort(Y, idx, sizeof(Y[0]), compare);

    // 合并公共区间,使用动态分配内存的数组来存储合并后的区间
    int** Z = (int**)malloc(idx * sizeof(int*));
    for (int i = 0; i < idx; i++) {
        Z[i] = (int*)malloc(2 * sizeof(int));
    }
    int idxz = 0;
    for (int i = 0; i < idx; ) {
        Z[idxz][0] = Y[i][0];
        int end = Y[i][1];
        int j = i + 1;
        while (j < idx && Y[j][0] <= end) {
            if (Y[j][1] > end) {
                end = Y[j][1];
            }
            j++;
        }
        Z[idxz][1] = end;
        idxz++;
        i = j;
    }

    // 输出结果
    if (idx == 0) {
        printf("None\n");
    } else {
        for (int i = 0; i < idxz; i++) {
            printf("%d %d\n", Z[i][0], Z[i][1]);
        }
    }

    // 释放动态分配的内存
    for (int i = 0; i < N; i++) {
        free(X[i]);
    }
    free(X);
    for (int i = 0; i < N * N; i++) {
        free(Y[i]);
    }
    free(Y);
    for (int i = 0; i < idx; i++) {
        free(Z[i]);
    }
    free(Z);

    return 0;
}

标签:idx,交集,30,++,int,公共,区间
From: https://blog.csdn.net/bingw0114/article/details/143759547

相关文章

  • yolo数据集 - 2130张边坡排水沟堵塞数据集分享 - 无人机采集与数据增强处理
    项目概述本篇文章分享了一个yolo数据集,该数据集包含了2130张边坡排水沟堵塞的图像,图像均来自无人机采集,为高精度的边坡排水沟堵塞问题提供了宝贵的图像数据支持。数据集特点图像来源:所有图像均由无人机进行高空采集,确保了数据集的广泛性和代表性,涵盖了多种自然环境中的......
  • 2024-2025 集训队互测 Round 13 - 线段树与区间加
    前言:张定江的题,但是在讲课里面拉的,放在一堆答辩里面。这个题虽然是答辩,但是是有价值的。题面有一百个锅。不过不影响做题就是了。我们可以发现\(a_i=\sum\limits_{x\in\text{Subtree}(i)}lz_x\cdotlen_x\),故我们可以直接把\(v_a\)以特定方法加到\(v_b\)上,然后问题变成求......
  • 2024-12-30:所有球里面不同颜色的数目。用go语言,给定一个整数 limit 和一个大小为 n x
    2024-12-30:所有球里面不同颜色的数目。用go语言,给定一个整数limit和一个大小为nx2的二维数组queries,其中包含若干操作。我们有limit+1个球,它们的编号为[0,limit],每个球的编号都是独特的。一开始,所有的球都是无色的。每个操作的形式为[x,y],表示将球x染成......
  • P1303 A*B Problem——高精度乘法
    题目背景高精度乘法模板题。题目描述给出两个非负整数,求它们的乘积。输入格式输入共两行,每行一个非负整数。输出格式输出一个非负整数表示乘积。样例#1样例输入#112样例输出#12提示每个非负整数不超过\(10^{2000}\)。我的作答#include<stdio.h>#include......
  • Android13编译报错build/make/core/base_rules.mk:304: error: vendor/ma/prebuilts/t
    前言全局说明一、说明1.1环境:Android13二、报错build/make/core/base_rules.mk:304:error:vendor/ma/prebuilts/third_party/atlas/iadfs/qa/qtu:unhandledinstallpath"TARGET_OUT_DATA_EXECUTABLESforqtxtrics".三、解决方法3.1增加LOCAL_MODULE_PATH......
  • 11.30
    importpandasaspdimportnumpyasnpfromsklearn.model_selectionimporttrain_test_splitfromsklearn.ensembleimportRandomForestClassifierfromsklearn.metricsimportaccuracy_score,precision_score,recall_score,f1_score,classification_reportfromskle......
  • 如何正确开启3306端口以允许外部访问MySQL数据库
    问题描述:我正在尝试配置云服务器上的MySQL数据库,使其能够接受来自外部网络的连接请求。但是,当我试图开放3306端口时遇到了困难。请问应该怎样正确地开启这个端口?需要注意哪些事项?解决方案:您好,针对您想要开启3306端口以允许外部访问MySQL数据库的需求,我们整理了一份详细的指南供......
  • 2024-10-30《Android SDK》无法下载谷歌包
    关于AndroidSDK自定义目录始终无法下载谷歌包   最近重装了一下系统,然后在配置安卓SDK自定义路径的时候突然遇到了一个小问题,就是在配置好tools之后通过调用sdkmanager--list的时候突然显示warning,并且无法显示所有包。经过我一天的不懈努力,终于找到了问题的解决方法,那就......
  • 独家揭秘:AI算法如何让你的照片清晰度提升300%
    嘿,亲爱的小伙伴们!今天要和大家分享一个超级棒的小秘密,保证让你的照片从此美得冒泡!......
  • Windows10 64环境下用Qt5.12.12自带的mingw730_64构建编译OpenCV4.1.0时cmake-3.20.6
    一、环境条件说明:操作系统:Windows1064环境编译工具:用Qt5.12.12自带的mingw730_64构建构建对象:编译OpenCV4.1.0的Release64位和Debug64位动态链接库构建工具:CMake中的参数配置二、cmake-3.20.6中的参数配置1、按照下图配置好OpenCV4.1.0的源代码目录和构建编译输出目录,然......