蓝桥杯 C++ 算法训练 藏匿的刺客 贪心

博客内容描述了一个关于区间覆盖的问题,其中涉及到一个强大的帝国kAc和反抗者鹏。问题要求找出最少人数来覆盖所有被看守员发现的草堆。通过排序区间并检查它们的重叠,可以确定最少人数。提供的C++代码实现了这一算法,通过遍历和比较区间边界来解决此问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.问题描述

  强大的kAc建立了强大的帝国,但人民深受其学霸及23文化的压迫,于是勇敢的鹏决心反抗。
  kAc帝国防守森严,鹏带领着小伙伴们躲在城外的草堆叶子中,称为叶子鹏。
  kAc帝国的派出的n个看守员都发现了这一问题,第i个人会告诉你在第li个草堆到第ri个草堆里面有人,要求你计算所有草堆中最少的人数,以商议应对。
  “你为什么这么厉害”,得到过kAc衷心赞美的你必将全力以赴。

2.输入格式

  第一行一个数字n,接下来2到n+1行,每行两个数li和ri,如题。

3.输出格式

  输出一个数,表示最少人数。

4.样例输入

5
2 4
1 3
5 7
1 8
8 8

5.样例输出

3

6.数据规模和约定

  30%的数据n<=10
  70%的数据n<=100
  100%的数据n<=1000
  所有数字均在int表示范围内

7.思路

有n个看守员,每个人只能发现第li个草堆到第ri个草堆中有人,需要找到所有草堆中最少有多少人。

定义:二维数组a[i][2],a[i][0]表示左端点,a[i][1]表示右端点。

t为当前区间i的右端点。

A数组为标记数组,若区间i满足条件,则加入到A数组中。

思路:首先将每个小区间按右端点值从小到大排序,然后比较当前区间i的右端点与下一个区间i+1左端点的大小情况,若下一个区间i+1左端点值大,则标记下一个区间i+1的A数组对应位置元素为1,并更新t为下一区间i+1的右端点值。重复此操作,直到n个区间全部找完。

最后根据A数组的情况,若值为1,则sum++,最后输出sum的值,则为最少人数。

以样例输入为例,画出示意图。

按区间右端点从小到大排序,若无重合,就将A数组对应位置标记为1,最后找出A数组中元素为1的个数。

 

 

8.实现:C++代码

#include<iostream>
using namespace std;
int main(){
	int n;
	cin>>n;
	int a[1001][2]={0};
	for(int i=0;i<n;i++){
		cin>>a[i][0]>>a[i][1];
	}
   //需要找到能覆盖所有草堆的 最小数 
	 //将每个区间按右端点排序 
	for(int i=0;i<n-1;i++){
		for(int j=i+1;j<n;j++) {
			if(a[i][1]>a[j][1]){
				int t1=a[i][0];
				a[i][0]=a[j][0];
				a[j][0]=t1; 
				int t2=a[i][1];
				a[i][1]=a[j][1];
				a[j][1]=t2; 
			}
		}		
	}
	//将最小的右端点和下一个区间的左端点比较,若下一个区间的左端点大于当前最小的右端点,说明两区间未重合,标记下一个区间,并且更新最小右端点为该区间的右端点。 
	int A[100]={0};//标记数组
	int t=a[0][1];//最小右端点
		A[0]=1;
		for(int j=1;j<n;j++){
			if(a[j][0]>t){//左端点大于于右端点
				A[j]=1;
				t=a[j][1];
			}
		}
	
	int sum=0;
	for(int i=0;i<n;i++){
	   if(A[i]==1)sum+=1;
		//cout<<A[i]<<" ";
	}
	cout<<sum;		
	
	return 0;
	}
	

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值