2020-8/20 数组进阶之差分序列

题目:校门外的树
【问题描述】
某校大门外长度为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% 的评测用例,区域之间没有重合的部分。
对于所有评测用例,区域之间有重合的情况。

大概思路:这道题用了差分序列的知识点,先简单说一下我理解的差分序列。差分序列可以只改变两个数的值,然后进行一次前缀和,来改变一定范围内的量,等同于把线段上的操作改变成了对点的操作。例如:对[a,b]内所有项+k,则令arr[a]+=k,arr[b+1] - =k,然后对新序列进行前缀和,就实现了[a,b]内所有项+1,顶替了一个for循环。本题就是如此,令需要挖去树的范围都+1,然后计算0的数目就是树的数目。
代码如下

import java.util.Scanner;
public class B校门外的树 {
    
    
	public static void main(String[] args) {
    
    
		Scanner sc = new Scanner(System.in);
		int L = sc.nextInt();
		int M = sc.nextInt();
		sc.nextLine();
		int s=0;
		int []arr = new int[L+1];
		int []arr2 = new int[L+2];//差分序列
		//因为要对i+1项进行操作,所以长度最少为L+2
		for(int i=1;i<arr.length;i++) {
    
    //差分序列
			arr2[0]=arr[0];
			arr2[i]=arr[i]-arr[i-1];
		}
		for(int i=0;i<M;i++) {
    
    //差分序列进行操作
//相当于挖树环节,100-150挖一颗数,重合的部分不作考虑,因为到最后记录的是0出现次数
			int begin = sc.nextInt();
			int end = sc.nextInt();
			arr2[begin]++;
			arr2[end+1]--;
		}
//定义第一项,如果没有被挖走,为index赋值为1
		int index=(arr2[0]==0?1:0);
		for(int i=1;i<=L;i++){
    
    
			arr2[i]=arr2[i-1]+arr2[i];
			if(arr2[i]==0)index++;//任何不等于0的,都是没有树的
		}
		System.out.println(index);
	}
}

欢迎大佬指正

猜你喜欢

转载自blog.csdn.net/weixin_45956597/article/details/108130111