本文章用来记录Acwing蓝桥杯课程学习。
网站地址:https://www.acwing.com/
本人算法小白,文章只是按照自己理解编写,望各位大佬轻喷🙏。
503.借教室
视频讲解链接:https://www.acwing.com/video/5336/
题目
在大学期间,经常需要租借教室。
大到院系举办活动,小到学习小组自习讨论,都需要向学校申请借教室。
教室的大小功能不同,借教室人的身份不同,借教室的手续也不一样。
面对海量租借教室的信息,我们自然希望编程解决这个问题。
我们需要处理接下来 n n n天的借教室信息,其中第 i i i 天学校有 r i r_i ri 个教室可供租借。
共有 m m m 份订单,每份订单用三个正整数描述,分别为 d j , s j , t j d_j,s_j,t_j dj,sj,tj,表示某租借者需要从第 s j s_j sj 天到第 t j t_j tj 天租借教室(包括第 s j s_j sj天和第 t j t_j tj 天),每天需要租借 d j d_j dj 个教室。
我们假定,租借者对教室的大小、地点没有要求。
即对于每份订单,我们只需要每天提供 d j d_j dj个教室,而它们具体是哪些教室,每天是否是相同的教室则不用考虑。
借教室的原则是先到先得,也就是说我们要按照订单的先后顺序依次为每份订单分配教室。
如果在分配的过程中遇到一份订单无法完全满足,则需要停止教室的分配,通知当前申请人修改订单。
这里的无法满足指从第 s j s_j sj天到第 t j t_j tj 天中有至少一天剩余的教室数量不足 d j d_j dj 个。
现在我们需要知道,是否会有订单无法完全满足。
如果有,需要通知哪一个申请人修改订单。
输入格式
第一行包含两个正整数 n , m n,m n,m,表示天数和订单的数量。
第二行包含 n n n 个正整数,其中第 i i i 个数为 r i r_i ri,表示第 i i i天可用于租借的教室数量。
接下来有 m m m 行,每行包含三个正整数 d j , s j , t j d_j,s_j,t_j dj,sj,tj,表示租借的数量,租借开始、结束分别在第几天。
每行相邻的两个数之间均用一个空格隔开。
天数与订单均用从 1 1 1 开始的整数编号。
输出格式
如果所有订单均可满足,则输出只有一行,包含一个整数 0 0 0。
否则(订单无法完全满足)输出两行,第一行输出一个负整数 − 1 −1 −1,第二行输出需要修改订单的申请人编号。
数据范围
1 ≤ n , m ≤ 1 0 6 , 1≤n,m≤10^6, 1≤n,m≤106,
0 ≤ r i , d j ≤ 1 0 9 , 0≤r_i,d_j≤10^9, 0≤ri,dj≤109,
1 ≤ s j ≤ t j ≤ n 1≤s_j≤t_j≤n 1≤sj≤tj≤n
输入样例:
4 3
2 5 4 3
2 1 3
3 2 4
4 2 4
输出样例:
-1
2
难度:简单 |
---|
时/空限制:1s / 128MB |
总通过数:6205 |
总尝试数:19636 |
来源:NOIP2012提高组 |
差分 |
思路:
刚开始使用的暴力破解,但由于测试用例数据过大超时了😢,可以先看看补充那部分,补充有分析题目对应的时间复杂度分析。
因为题目要求没有满足条件要输出第一个没有满足的订单的的编号,第一时间想到的是可以根据订单的编号进行依次遍历,从第一份订单到最后一份订单,如果有一份订单没有满足就输出,没有则继续。但这样可能会TLE(Time Limit Exceeded),因此需要进行优化,而遍历寻找某一不满足条件的订单其实就相当于将这份订单分为两部分,这一份订单前的都能满足,订单后的都不能满足,其实就相当于二分查找第一个不满足条件的订单,因此使用二分查找优化。
要判断执行到某一订单 j j j时是否满足条件则需要设计一个check函数,如果使用 a [ i ] a[i] a[i]来代表第 i i i天 j j j订单及之前的订单在这一天要租借的教室的总数量,那么问题其实就可以转化为先求出每一天要租借的教室的总数量 a [ i ] a[i] a[i],将 a [ i ] a[i] a[i]跟这一天可以被租借的教室的数量 w [ i ] w[i] w[i]对比:
- 如果某一天要租借的教室的数量 a [ i ] > a[i]> a[i]>可以被租借的教室的数量 w [ i ] w[i] w[i],就说明没有满足订单,输出 − 1 -1 −1和订单编号;
- 如果某一天要租借的教室的数量 a [ i ] < = a[i]<= a[i]<=可以被租借的教室的数量 w [ i ] w[i] w[i],则继续比较下一天的数量。
求解 a [ i ] a[i] a[i]其实只需要给数组 a [ i ] a[i] a[i]依次加上所有订单在这一天要租借的教室的数量 d j d_j dj即可,我们要得到第 1 1 1天到第 n n n天每一天要租借的教室的数量 a [ i ] a[i] a[i],其实就相当于给每一份订单对应的第 s s s ~ t t t天的教室数量 a [ s ] a[s] a[s] ~ a [ t ] a[t] a[t]都加上这份订单要租借的教室的数量 d j d_j dj,这就运用到了差分的知识,给 a [ s ] a[s] a[s] ~ a [ t ] a[t] a[t]都加上 d j d_j dj其实就相当于让对应的差分数组的 b [ s ] + d j , b [ t + 1 ] − d j b[s]+d_j,b[t+1]-d_j b[s]+dj,b[t+1]−dj 。
接下来便可以开始编写代码。
代码:
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;
const int N =1e6+10;
int n,m;//天数和订单数量
int w[N];//可以被租借的教室的数量
int d[N],s[N],t[N];//订单要租借的天数、租借起始时间和结束时间
LL b[N];//差分数组
/**
* 检查处理订单mid时是否能租借成功
* @param mid 订单编号
* @return 是否能租借成功 true: 能 false: 不能
*/
bool check(int mid)
{
//初始化差分数组
memset(b,0,sizeof b);
//构建差分数组
for(int i=1;i<=mid;i++)
{
b[s[i]]+=d[i];
b[t[i]+1]-=d[i];
}
//a1=b1
//a2=b1+b2
//an=b1+b2+...+bn
LL s =0;//a[i],第i天所有订单要租借的教室的数量
for(int i=1;i<=n;i++)
{
s+= b[i];
if(s >w[i]) return false;//将这一天所有订单要租借的教室的数量与这一天可以被租借的的教室的数量对比
}
return true;
}
int main()
{
scanf("%d%d",&n,&m);
for (int i = 1; i <= n; i++) scanf("%d",&w[i]);
for (int i = 1; i <= m; i++) scanf("%d%d%d",&d[i],&s[i],&t[i]);
//二分查找
int l=0,r=m;
while(l<r)
{
int mid=l+r+1>>1;
if(check(mid)) l=mid;
else r=mid-1;
}
//如果满足r==m,说明l=r=m,所有订单都能满足
if(r==m) puts("0");
else printf("-1\n%d\n",r+1);
return 0;
}
补充:
题外话
黑客&网络安全如何学习
今天只要你给我的文章点赞,我私藏的网安学习资料一样免费共享给你们,来看看有哪些东西。
1.学习路线图
攻击和防守要学的东西也不少,具体要学的东西我都写在了上面的路线图,如果你能学完它们,你去就业和接私活完全没有问题。
2.视频教程
网上虽然也有很多的学习资源,但基本上都残缺不全的,这是我自己录的网安视频教程,上面路线图的每一个知识点,我都有配套的视频讲解。
内容涵盖了网络安全法学习、网络安全运营等保测评、渗透测试基础、漏洞详解、计算机基础知识等,都是网络安全入门必知必会的学习内容。
(都打包成一块的了,不能一一展开,总共300多集)
因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取
🐵这些东西我都可以免费分享给大家,需要的可以点这里自取👉:网安入门到进阶资源
3.技术文档和电子书
技术文档也是我自己整理的,包括我参加大型网安行动、CTF和挖SRC漏洞的经验和技术要点,电子书也有200多本,由于内容的敏感性,我就不一一展示了。
因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取
🐵这些东西我都可以免费分享给大家,需要的可以点这里自取👉:网安入门到进阶资源
4.工具包、面试题和源码
“工欲善其事必先利其器”我为大家总结出了最受欢迎的几十款款黑客工具。涉及范围主要集中在 信息收集、Android黑客工具、自动化工具、网络钓鱼等,感兴趣的同学不容错过。
还有我视频里讲的案例源码和对应的工具包,需要的话也可以拿走。
🐵这些东西我都可以免费分享给大家,需要的可以点这里自取👉:网安入门到进阶资源
最后就是我这几年整理的网安方面的面试题,如果你是要找网安方面的工作,它们绝对能帮你大忙。
这些题目都是大家在面试深信服、奇安信、腾讯或者其它大厂面试时经常遇到的,如果大家有好的题目或者好的见解欢迎分享。
参考解析:深信服官网、奇安信官网、Freebuf、csdn等
内容特点:条理清晰,含图像化表示更加易懂。
内容概要:包括 内网、操作系统、协议、渗透测试、安服、漏洞、注入、XSS、CSRF、SSRF、文件上传、文件下载、文件包含、XXE、逻辑漏洞、工具、SQLmap、NMAP、BP、MSF…
因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取
🐵这些东西我都可以免费分享给大家,需要的可以点这里自取👉:网安入门到进阶资源
————————————————
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。