当前位置: 首页 > article >正文

蓝桥杯备赛-贪心-管道

问题描述

有一根长度为 lenlen 的横向的管道,该管道按照单位长度分为 lenlen 段,每一段的中央有一个可开关的阀门和一个检测水流的传感器。

一开始管道是空的,位于 LiLi​ 的阀门会在 SiSi​ 时刻打开,并不断让水流入管道。

对于位于 LiLi​ 的阀门,它流入的水在 TiTi​ (Ti≥SiTi​≥Si​) 时刻会使得从第 Li−(Ti−Si)Li​−(Ti​−Si​) 段到第 Li+(Ti−Si)Li​+(Ti​−Si​) 段的传感器检测到水流。

求管道中每一段中间的传感器都检测到有水流的最早时间。

输入格式

输入的第一行包含两个整数 n,lenn,len,用一个空格分隔,分别表示会打开的阀门数和管道长度。

接下来 nn 行每行包含两个整数 Li,SiLi​,Si​,用一个空格分隔,表示位于第 LiLi​ 段管道中央的阀门会在 SiSi​ 时刻打开。

输出格式

输出一行包含一个整数表示答案。

样例输入

3 10
1 1
6 5
10 2

样例输出

5

评测用例规模与约定

对于 3030% 的评测用例,n≤200n≤200,Si,len≤3000Si​,len≤3000;

对于 7070% 的评测用例,n≤5000n≤5000,Si,len≤105Si​,len≤105;

对于所有评测用例,1≤n≤105​1≤n≤105​,1≤Si,len≤109​1≤Si​,len≤109​,1≤Li≤len​1≤Li​≤len​,Li−1<Li​Li−1​<Li​​。

#include<iostream>
#include<vector>
#include<algorithm>
#include<climits>
using namespace std;
//二分猜时间+逐一检验是否覆盖整条管道(求每一次开水后的区间,然后排序)
//终于在九点多百分之百通过(哭)
//细节很多,尤其是关于数组,还有
struct boon {//开阀的管道
	int l;
	int s;
};
int n, len;
vector<boon> kai;
bool check(long long t) {//这里要改成long long,保持统一
	vector<pair<long, long>> guanzi;
	long long left;
	long long right;
	for (int i = 1; i <= n; i++) { 
		if (t >= kai[i].s) {
			left  = kai[i].l - (t - kai[i].s);
			right = kai[i].l + (t - kai[i].s);
			guanzi.push_back({ left,right });//注意写法
		}
	}//遍历得到区间
	if (guanzi.size() == 0) return false;//忽略了为空直接跳出
	sort(guanzi.begin(), guanzi.end());//不能+n,可能有的管道没有开,没有被放入
	if (guanzi[0].first > 1) {
		return false;
	}//第一个没灌水直接跳出
	else {
		long long start = guanzi[0].first;
		long long end = guanzi[0].second;
		for (int i = 1; i < guanzi.size(); i++) {//不是n
			if (guanzi[i].first - end>=2) {//[1,3][4,6]是满足的,不能用guanzi[i].first>end
				return false;
			}///有间隙,没重合
			else {
				if (guanzi[i].second > end)
					end = guanzi[i].second;
			}//重合了进行合并
		}
		if (start <= 1 && end >= len){return true;}
		else { return false; }
	}
}
int main() {
	cin >> n >>len;
	kai.resize(n + 2);
	for (int i = 1; i <= n; i++) { cin >> kai[i].l >> kai[i].s; }
	long long ltime = 0;
	long long rtime = INT_MAX;//时间的区间,rtime可以是2e9
	while (ltime < rtime) {
		long long mid = (ltime + rtime) / 2;//long long 防止溢出
		if (check(mid)) {//全覆盖
			rtime = mid;
		}
		else {//未覆盖
			ltime = mid + 1;
		}
	}
	cout << ltime;
	return 0;
}


http://www.kler.cn/a/590736.html

相关文章:

  • MySQL 进阶学习笔记(包括MySQL的存储引擎、索引、SQL优化、视图、存储过程、触发器、锁InnoDB引擎和MySQL管理)的相关内容详细版
  • 使用vue3+el-form实现动态新增名称,值,并对名称进行必填校验
  • npm 报错 unable to resolve dependency tree
  • 企业级 GitLab 开发流程全解
  • 功能强大的电脑硬件检测及驱动安装工具
  • 突破 HTML 学习瓶颈:表格、列表与表单的学习进度(一)
  • docker4-容器命令及其案例
  • SpringBoot-已添加并下载的依赖,reload和mvn clean 后还是提示找不到jar包问题
  • 东芝2323AMW纸盒和输稿器安装注意事项(也适用于2523A等白壳机)
  • Spring Boot集成MQTT完整示例和常见问题的解决方案
  • Netty基础—8.Netty实现私有协议栈二
  • 激光slam学习笔记10---ubuntu2004部署运行fastlivo2踩坑记录
  • 【Ratis】ReferenceCountedObject接口的作用及参考意义
  • springboot多种生产打包方式教程
  • 【从零开始学习计算机】计算机网络(一)计算机网络分层结构
  • javaEE————文件IO(1)
  • MySQL使用pxc实现高可用
  • Day34 | 300. 最长递增子序列、674. 最长连续递增序列、718. 最长重复子数组、1143. 最长公共子序列
  • 卓越的用户体验需要智能内容
  • MiddleVR for Unity插件