首页 > 编程语言 >蓝桥杯 ALGO-29算法训练 校门外的树

蓝桥杯 ALGO-29算法训练 校门外的树

时间:2022-12-02 17:02:05浏览次数:50  
标签:count arr int 29 蓝桥 区域 ALGO 端点 区间

时间限制:1.0s 内存限制:256.0MB
关键字:区间处理
问题描述
  某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米。我们可以把马路看成一个数轴,马路的一端在数轴0的位置,另一端在L的位置;数轴上的每个整数点,即0,1,2,……,L,都种有一棵树。
  由于马路上有一些区域要用来建地铁。这些区域用它们在数轴上的起始点和终止点表示。已知任一区域的起始点和终止点的坐标都是整数,区域之间可能有重合的部分。现在要把这些区域中的树(包括区域端点处的两棵树)移走。你的任务是计算将这些树都移走后,马路上还有多少棵树。
输入格式
  输入文件的第一行有两个整数L(1 <= L <= 10000)和 M(1 <= M <= 100),L代表马路的长度,M代表区域的数目,L和M之间用一个空格隔开。接下来的M行每行包含两个不同的整数,用一个空格隔开,表示一个区域的起始点 和终止点的坐标。
输出格式
  输出文件包括一行,这一行只包含一个整数,表示马路上剩余的树的数目。
样例输入
500 3
150 300
100 200
470 471
样例输出
298
数据规模和约定
  对于20%的数据,区域之间没有重合的部分;
  对于其它的数据,区域之间有重合的情况。
【分析】由于马路的端点都有树,则L长的马路边一共有L+1棵树,如果当成L棵树的话,答案就会比原来的少了1,这是我刚开始犯的错误,又认真审题才发现,细节问题很重要,首先定义一个二维数组用来存储地铁区域s[l, r],也就是要移走的区间,每个区间里包含 count 棵树, count = (r - l +1)
1.先把区间按照左端点为依据进行排序,当左端点相等时,依据右端点升序排列
2.判断下一区间的左端点和当前区间的右区间的大小进行比较,可能会包含三种情况
第一种:两区间没有交集,则需要移走的数目count = count1 + count2
第二种:下一区间被当前区间所包含,这时移走的树木不变
第三种:下一区间和当前区间重合一部分,这时count = count + 下一区间的右端点 - 当前区间的右端点
最后输出为(L+1-count)
【参考代码】
C++:

#include<stdio.h>
#include<algorithm>
using namespace std;
struct Area
{
    int l, r;
};
Area a[101];
bool cmp(Area a, Area b)
{
    return a.l < b.l;
}
int main()
{
    int L, m, i;
    scanf("%d%d", &L, &m);
    for(i = 0; i < m; i++)
        scanf("%d%d", &a[i].l, &a[i].r);
    sort(a, a+m, cmp);
    int tot = 0, crt = -1;
    for(i = 0; i < m; i++)
    {
        if(a[i].l > crt)
        {
            crt = a[i].l;
            tot++;
        }
        if(crt < a[i].r)
        {
            tot += a[i].r - crt;
            crt = a[i].r;
        }
    }
    printf("%d\n", L-tot+1);
    return 0;
}

c:

#include<stdio.h>
typedef struct
{
int start;
int end;
int flag;
}extent;
int main()
{
int L,M,i,j;
extent e[101];
scanf("%d%d",&L,&M);
for(i=1;i<=M;i++)
{
scanf("%d%d",&(e[i].start),&(e[i].end));
e[i].flag=1;
for(j=1;j<i;j++)
{
if(!(e[i].end<e[j].start||e[i].start>e[j].end)&&e[j].flag)
{
e[j].flag=0;
if(e[i].start>e[j].start)
e[i].start=e[j].start;
if(e[i].end<e[j].end)
e[i].end=e[j].end;
}
}//调整区间 
}
for(i=1;i<=M;i++)
if(e[i].flag)
L=L-(e[i].end-e[i].start+1);
printf("%d",L+1);
return 0;
}

Java:

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int m = input.nextInt();
        int n = input.nextInt();
        int[] a = new int[2 * n];

        int d = 0, e, max;
        for (int i = 0; i < n; i++) {
            a[i] = input.nextInt();
            a[i + n] = input.nextInt();

        }
        max = a[0];
        for (int j = 0; j < 2 * n; j++) {
            if (max < a[j]) {
                max = a[j];
            }

        }
        int[] c = new int[max*10];
        for (int i = 0; i < n; i++) {
            for (int j = a[i]; j <=a[i + n]; j++) {
                c[j] = 1;
            }
        }
        for (int i = 0; i < max; i++) {
            if (c[i] == 1) {
                d = d + 1;

            }
        }
        e = m  - d;

        System.out.println(e);

    }

}

下面是我自己的思路写的Java实现的算法,思路很清晰,或许会有点麻烦:

import java.util.Scanner;

public class 校门外的树 
{
    public static void main(String[] args) 
    {
        Scanner sc = new Scanner(System.in);
        int L = sc.nextInt();//马路的长度
        int n = sc.nextInt(); //有多少个区域
        int[][] arr = new int[n][2]; //创建二维数组,存储区域的端点
        for (int i=0; i<n; i++)
        {
            for (int j=0; j<2; j++)
            {
                arr[i][j] = sc.nextInt();
            }
        }
        //依据左端点 对区域进行升序处理
        int temp = 0;
        for (int i=0; i<n; i++)
        {
            for (int j=i; j<n; j++)
            {
                if (arr[i][0] > arr[j][0])
                {
                    temp = arr[j][0];
                    arr[j][0] = arr[i][0];
                    arr[i][0] = temp;

                    temp = arr[j][1];
                    arr[j][1] = arr[i][1];
                    arr[i][1] = temp;
                }
                //当左端点相同时,依据右端点排序
                else if (arr[i][0] == arr[j][0])
                {
                    if (arr[i][1] > arr[j][1])
                    {
                        temp = arr[j][1];
                        arr[j][1] = arr[i][1];
                        arr[i][1] = temp;
                    }
                }
            }           
        }
        //进行计数处理
        int count = arr[0][1] - arr[0][0] + 1; //初始化等于第一段区域需要移走的树木
        //判断下一区域与当前区域的端点关系
        for (int i=0; i<n-1; i++)
        {
            if (arr[i+1][0] > arr[i][1])  //无交集
            {
                count += arr[i+1][1] - arr[i+1][0] + 1;
            }
            else if (arr[i+1][0] == arr[i][1])  //相接
            {
                count += arr[i+1][1] - arr[i+1][0];
            }
            else //有交集
            {
                if (arr[i+1][1] > arr[i][1])
                {
                    count += arr[i+1][1] - arr[i][1];
                }
                else //包含时不做处理,如果升序完成之后,这一步好像是多余的
                    continue;               
            }
        }
        System.out.println(L + 1 - count);
    }
}

标签:count,arr,int,29,蓝桥,区域,ALGO,端点,区间
From: https://blog.51cto.com/linmengmeng/5907234

相关文章

  • 蓝桥杯 ADV-103算法提高 逆序排列
    关键字循环语句数组操作问题描述编写一个程序,读入一组整数(不超过20个),并把它们保存在一个整型数组中。当用户输入0时,表示输入结束。然后程序将把这个数组中的值按......
  • 蓝桥杯 ALGO-40算法训练 会议中心 (APIO 2009)
    时间限制:2.0s内存限制:512.0MB关键字:APIO2009会议中心Siruseri政府建造了一座新的会议中心。许多公司对租借会议中心的会堂很感兴趣,他们希望能够在里面举行会议。......
  • 蓝桥杯 ALGO-55算法训练 矩阵加法
    时间限制:1.0s内存限制:512.0MB问题描述给定两个N×M的矩阵,计算其和。其中:N和M大于等于1且小于等于100,矩阵元素的绝对值不超过1000。输入格式输入数......
  • 蓝桥杯 ALGO-45算法训练 调和数列问题
    问题描述输入一个实数x,求最小的n使得,1/2+1/3+1/4+…+1/(n+1)>=x。输入的实数x保证大于等于0.01,小于等于5.20,并且恰好有两位小数。你的程序要能够处理多组数据,即......
  • 蓝桥杯 ALGO-34算法训练 纪念品分组
    时间限制:1.0s内存限制:256.0MB关键字:贪心排序问题描述元旦快到了,校学生会让乐乐负责新年晚会的纪念品发放工作。为使得参加晚会的同学所获得的纪念品价值相对......
  • algorithm of linking clip-level action detections
    2017TCNN- TubeConvolutionalNeuralNetwork(T-CNN)forActionDetectioninVideos-ICCV 这篇论文的clip-levellinking算法其实是从2015年findactiontubes论......
  • 2022.11.29 vjudge构造、思路题
    WeightingaTree构造切入点:调整总结:图上的题,可以先考虑树上的做法。(尤其是构造题)首先我们要知道这种“点与跟他连着的所有边的关系”什么的题的套路就是找生成树。-......
  • day29
    【0101.对称二叉树】/***Definitionforabinarytreenode.*structTreeNode{*intval;*TreeNode*left;*TreeNode*right;*TreeN......
  • 29. Divide Two Integers
    Dividetwointegerswithoutusingmultiplication,divisionandmodoperator.Ifitisoverflow,returnMAX_INT.那么如果每次不仅仅减去1个除数,计算速度就会增加,但......
  • 《安富莱嵌入式周报》第293期:SEGGER开源其C/C++库源码emRun,丰富EMC电磁兼容资,OTA开源
    往期周报汇总地址:http://www.armbbs.cn/forum.php?mod=forumdisplay&fid=12&filter=typeid&typeid=104 视频版:https://www.bilibili.com/video/BV1ND4y1v7ik/ 1、......