腾讯校园招聘笔试 2019-8-17 第三题

24 篇文章 0 订阅

小Q在进行一场竞技游戏,这场游戏的胜负关键就在于能够能争夺一条长度为L的河道,即可以看作是[0,L]的一条数轴。

这款竞技游戏当中有n个可以提供视野的道具-真视守卫,第i个真视守卫能够覆盖区间[xi,yi]。现在小Q想知道至少用几个真视守卫就可以覆盖整段河道。

输入:

输入包括n+1行。

第一行包括两个整数n和L(1<=n<=10^5,1<=L<=10^9)

接下来的n行,每行两个正整数xi,yi(0<=xi<=yi<=10^9),表示第i个真视守卫覆盖的区间。

输出:

一个整数,表示最少需要的守卫的数量,如果无解,输出-1。

 

分析:典型的贪心法。首先,关键的一点是需要将数组进行排序,我的解法是:首先对于输入的看做结构体,对其按照起始点进行排序。排序之后,设置当前的找到的末端,然后寻找起始点在当前末端之前的,能够向最远延伸的绳子,并且把这个绳子的结束点当做目前的末端。

结束条件:当前末端>=L,成功;没有找到满足上面条件的,返回-1.

代码如下:

struct guard{
	int start;
	int end;
};

bool cmp(guard &g1, guard &g2){
	if (g1.start == g2.start) return g1.end < g2.end;
	else{
		return g1.start < g2.start;
	}
}
int main(){
	
	//贪心法来做
	int n, L;
	cin >> n >> L;
	vector<guard> GA;
	guard g;
	for (int i = 0; i < n; i++){
		cin >> g.start >> g.end;
		GA.push_back(g);
	}
	sort(GA.begin(), GA.end(), cmp);
	
	//贪心法
	int ret = 0;
	int rowstart = -1;
	int rowend = 0;

	int index = -1;
	int cnt = 0;
	bool noresult = false;
	
	while (rowend<L)
	{
		int tmpend = rowend;
		bool find = false;
		for (int i = index + 1; i < n; i++){
			
			if (GA[i].end <= rowend) continue;

			//如果起始点都已经大于目前的末端了,就跳出循环,因为是按照起始点的升序排列的,后面的更不可能满足条件
			if (GA[i].start > rowend) break;

			/*要覆盖0~L的所有范围,所以对于每个点,选择之后都要尽量向远延伸*/
			if (tmpend < GA[i].end){
				find = true;
				index = i;
				tmpend = GA[i].end;
			}
		}
		if (!find){//没有找到,说明不存在能接上去的绳子了
			break;
		}
		else{
			rowend = tmpend;
			cnt++;
		}
	}
	cout<< (rowend < L ? -1 : cnt);

	
	system("pause");
	return 0;
}

自己太菜了,要多学习,多思考。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值