程序设计思维Week3-作业 B-区间选点

B-区间选点

Description

数轴上有 n 个闭区间 [a_i, b_i]。取尽量少的点,使得每个区间内都至少有一个点(不同区间内含的点可以是同一个)。要求输入n以及n个区间,输出选点的数目

Sample


    Input

    2
    1 5
    4 6

    Output

    1

    Input

    3
    1 3
    2 5
    4 6

    Output

    2


Idea

首先将所有区间按右边界升序,右边界相同时左边界降序进行排列。对每个区间设置一个标志flag判断该区间是否已经有一个点,依序对每个区间进行判断,如果其中还没有点,取该区间的右边界确定为一点,可以使得该点被包含的区间个数最大化,体现贪心算法,然后对该区间之后的每个区间,判断这个点是否也在这些区间中,是则改变其标志,在之后的循环中直接跳过它。

Summary

该题属于区间问题之一,基本思想是贪心,遵守的贪心准则是对于其中还没有点的区间取其右边界为一点,使效益最大化,在正确的排序之后,这个点要么在后面区间当中要么小于其他区间的左边界,可以保证没有区间被忽略。

Codes

#include <iostream>
#include <algorithm>
using namespace std;
int n;

struct time {
	int a;
	int b;
	bool flag = false;
}t[100];

bool compare(time x, time y) {
	if (x.b != y.b)return x.b < y.b;
	else return x.a > y.a;
}

int main()
{
	cin >> n;
	for (int i = 0; i < n; i++)
		cin >> t[i].a >> t[i].b;
	sort(t, t + n, compare);
	int count = 0;
	int i = 0;
	while (i<n) {
		if (t[i].flag) {
			i++; continue;
		}
		int b;
		if (i < n) { b = t[i].b; count++; t[i].flag = true; i++;  }
		int index = i;
		while (index < n) {
			if (t[index].b >= b && t[index].a <= b) {
				t[index].flag = true;
				index++;
			}
			else index++;
		}
	}
	printf("%d\n", count);

}


发布了21 篇原创文章 · 获赞 5 · 访问量 785

猜你喜欢

转载自blog.csdn.net/weixin_44578615/article/details/104711970