洛谷:题解 P1047 【校门外的树】

洛谷:题解 P1047 【校门外的树】

题目:
题目描述
某校大门外长度为 ll 的马路上有一排树,每两棵相邻的树之间的间隔都是 11 米。我们可以把马路看成一个数轴,马路的一端在数轴 00 的位置,另一端在 ll 的位置;数轴上的每个整数点,即 0,1,2,\dots,l0,1,2,…,l,都种有一棵树。

由于马路上有一些区域要用来建地铁。这些区域用它们在数轴上的起始点和终止点表示。已知任一区域的起始点和终止点的坐标都是整数,区域之间可能有重合的部分。现在要把这些区域中的树(包括区域端点处的两棵树)移走。你的任务是计算将这些树都移走后,马路上还有多少棵树。

输入格式
第一行有两个整数,分别表示马路的长度 ll 和区域的数目 mm。

接下来 mm 行,每行两个整数 u, vu,v,表示一个区域的起始点和终止点的坐标。

输出格式
输出一行一个整数,表示将这些树都移走后,马路上剩余的树木数量。

输入输出样例
输入 #1 复制

500 3
150 300
100 200
470 471

输出 #1 复制

298


思路:找出计算区间的方法

模拟我们计算区间的方式:
在这里插入图片描述

(其实可以用栈来模拟这个过程的)

  • L和R永远是成对的,相互抵消
  • 所以用一个temp值去模拟抵消的过程
    :当遇到L就temp++,遇到R就temp–
  • 如果temp=0了,就可以计算该区间

跟着这个思路去模拟:

  1. 建立横坐标由最小值到最大值:将两个数组加起来再排序

    array为坐标数组,hashMap记录坐标值是L还是R

		for (int i = 0; i < m; i++) {
			array[i] = left[i];
			hashMap.put(left[i]+"l", "left");
		}
		for (int i = 0; i < m; i++) {
			array[i+m] = right[i];
			hashMap.put(right[i]+"r", "right");
		}
		Arrays.sort(array);
  1. xl存需要计算区间L的值,count为区间值

    遍历坐标数组array的值进行判断

    1.当前值为L且temp=0L -----------> 记录xl为需要计算区间L的值

    2.当前值为L----------->temp++

    3.当前值为R----------->temp–

    4.temp==0:说明该值为计算区间的R值:进行计算(count+=array[i] -xl+1;)

		int temp = 0;
		int count = 0;
		int xl = array[0];
		for (int i = 0; i < array.length; i++) {
			String lString = array[i]+"l";
			String rString = array[i]+"r";
			if (hashMap.containsKey(lString)&&temp==0) {
				xl = array[i];
			}
			if (hashMap.containsKey(lString)) {
				temp++;
			}
			if (hashMap.containsKey(rString)) {
				temp--;
			}
			if (temp==0) {
				count+=array[i] -xl+1;
				
			}
		}

完整代码:

package 洛谷;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Scanner;


public class P1047校门外的树 {
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		int l = scanner.nextInt(), m = scanner.nextInt();
		int[] left = new int[m];
		int[] right = new int[m];
		Map<String,String> hashMap = new HashMap<String,String>();
		for (int i = 0; i < m; i++) {
			left[i] = scanner.nextInt();
			right[i] = scanner.nextInt();
		}
		int[] array = new int[m+m];
		for (int i = 0; i < m; i++) {
			array[i] = left[i];
			hashMap.put(left[i]+"l", "left");
		}
		for (int i = 0; i < m; i++) {
			array[i+m] = right[i];
			hashMap.put(right[i]+"r", "right");
		}
		Arrays.sort(array);
	
		
		int temp = 0;
		int count = 0;
		int xl = array[0];
		for (int i = 0; i < array.length; i++) {
			String lString = array[i]+"l";
			String rString = array[i]+"r";
			if (hashMap.containsKey(lString)&&temp==0) {
				xl = array[i];
			}
			if (hashMap.containsKey(lString)) {
				temp++;
			}
			if (hashMap.containsKey(rString)) {
				temp--;
			}
			if (temp==0) {
				count+=array[i] -xl+1;
				
			}
		}
		System.out.println((l+1)-count);
	}
}

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值