ACM入门题-区间覆盖-Go语言

16 篇文章 0 订阅

ACM入门题-区间覆盖-Go语言

时间限制:C/C++ 1000MS,其他语言 2000MS
内存限制:C/C++ 256MB,其他语言 512MB
分数:100

描述

给定n个闭区间[ai; bi],其中 i=1,2,…,n。 这些区间的总和可以表示为闭合的成对非相交区间的总和。 我们要用最少的间隔找到这样的表示。 此表示的间隔应按升序写入输出。 我们说区间 [a; b] 和 [c; d] 是升序当且仅当 a <= b < c <= d。
输入一系列间隔的描述,计算满足上述条件的成对非相交区间,升序输出计算出的区间

输入描述

在输入的第一行有一个整数 n,3 <= n <= 50000。这是间隔数。 在第i+1行,1 <= i <= n,有区间[ai; bi] 形式为两个整数 ai 和 bi 由一个空格隔开,分别是区间的开始和结束,1 <= ai <= bi <= 1000000。

输出描述

输出应包含所有计算的成对非相交区间的描述。 在每一行中都应该写一个区间的描述。 它应该由两个整数组成,由一个空格隔开,分别是间隔的开始和结束。 间隔应按升序写入输出。

用例输入 1

5
5 6
1 4
10 10
6 9
8 10

用例输出 1

1 4
5 10

思路

这种方案不是最优解,但是理解起来不难。

  • 先排序,如果左边界相同则按右边界排序。这里在Go语言里可以调用sort包
  • 从小往大遍历,需要三个中间值来完成搜寻答案。这里左边界是单调递增的,可右边界可不一定,所有要记录它的最大值。

image-20220404192801577

AC代码

package main

import (
	"fmt"
	"sort"
)

func main() {
	var n, l, r int
	fmt.Scan(&n)
	grid := make([][]int, n)
	ans := make([][]int, 0)
	for i := 0; i < n; i++ {
		fmt.Scan(&l, &r)
		grid[i] = []int{l, r}
	}
	sort.Slice(grid, func(i, j int) bool {	// 排序
		if grid[i][0] < grid[j][0] {
			return true
		} else if grid[i][0] == grid[j][0] {
			if grid[i][1] < grid[j][1] {
				return true
			} else {
				return false
			}
		}
		return false
	})
	var max = func(a, b int) int {
		if a > b {
			return a
		}
		return b
	}
	bg, ed, tmp := 0, 1, 0
	for ed < n {
		tmp = max(tmp, grid[ed-1][1])
		if grid[ed][0] > tmp {
			ans = append(ans, []int{grid[bg][0], tmp})	// 确定左右边界添加答案
			bg = ed
		}
		ed++
	}
	ans = append(ans, []int{grid[bg][0], tmp})
	for i := 0; i < len(ans); i++ {
		fmt.Println(ans[i][0], ans[i][1])
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值