C - 区间覆盖

题意介绍

区间覆盖问题,数轴上有若干的区间,选择最少的区间能够覆盖指定线段

题意分析

做这道题的时候主要遇到两个问题:
(1)一直wa,一直不知道为什么,问了其他同学终于知道了,这道题有坑!一直认为(1,2)和(2,4)可以覆盖(1,4)线段,殊不知(1,2)和(3,4)也算是覆盖了(1,4)线段。
(2)上面的问题解决之后,运行又出现超时问题,因为需要将所有区间排序,所以可以找到所有区间的左端点的最小值和右端点的最大值,先判断最小值是否小于下线段的左端点,最大值是否大于右端点,如果这个条件不满足,直接continue就可以,满足条件再往下走。
用到一个数组来标记某个区间是否已经访问过,用now标记每次需要加入的区间,bz用来标记能否覆盖指定线段,不能覆盖跳出循环。

#include<stdio.h>
#include<algorithm>
#include<math.h>
using namespace std;

#define INF 0X7fffffff

struct p {
	int a, b;
	
}d[20000000];

int N, T;



bool cmp(p p1, p p2) {
	if(p1.a!=p2.a)
	return p1.a < p2.a;
	else return p1.b > p2.b;
}

int main() {
	
	while (scanf("%d%d",&N,&T)!=EOF) {
		
		int mi = INF, ma = -1;
		for (int i = 0; i < N; i++) {
			scanf("%d%d", &d[i].a, &d[i].b);
			mi = min(mi, d[i].a);
			ma = max(ma, d[i].b);
		}
		
		if (mi > 1 || ma < T) {
			printf("-1\n");
			continue;
		}

		sort(d,d+N,cmp);
		int *v = new int[N];
		for (int i = 0; i < N; i++) v[i] = 0;

		p now;
		int count = 0;
		now = d[0];
		v[0] = 1;
		count++;
		int bz = 0;
		int j = -1;

		while (now.b < T) {
			int k = -1, M = -1;
			for (int i = j + 1; i < N; i++) {
				if (!v[i]) {
					if (M<d[i].b&&d[i].a <= now.b + 1 && d[i].a>now.a) {
						M = d[i].b;
						k = i;
					}
				}
			}
			if (k == -1) {
				bz = 1;
				break;
			}
			now = d[k];
			j = k;
			v[k] = 1;
			count++;
		}
		if (bz) printf("-1\n");
		else printf("%d\n", count);
    }
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值