首页
题库
公司真题
专项练习
面试题库
在线编程
面试
面试经验
AI 模拟面试
简历
求职
学习
基础学习课
实战项目课
求职辅导课
专栏&文章
竞赛
搜索
我要招人
发布职位
发布职位、邀约牛人
更多企业解决方案
在线笔面试、雇主品牌宣传
登录
/
注册
我是二哈
上海交通大学 Java
发布于浙江
关注
已关注
取消关注
@tangren:
题解 | 国旗计划(倍增:区间最值)
国旗计划:原题链接题意: 输入:第一行给你一个n和m,n代表边防战士的人数,m代表总共有几个站点,接下来有n行,每行给你两个站点C和D,战士行走的区间为[C,D],区间会重叠,但不会完全覆盖。 输出:输出每个战士,在以他自身的区间为起点的前提下,至少需要多少人可以使战士之间行走的区间形成一个环。做题思路: 初步入手本题,可以想到如果要判断成环,最好的办法是将环拆分成链,即当右边的点小于左边的点时,说明该点跨过了环,因此将右边的点加上站点总数,即可生成假设在一条链上的两点间的距离。初始输入代码: cin >>n>>m; for (int i=1;i<=n;i++) { cin >>w[i].l>>w[i].r; //破环成链 if (w[i].r<w[i].l)w[i].r+=m; } 在生成完链后,题目要求也变成了找到覆盖3-10的这个区间,问题是该怎么求解,找到最少的人数去覆盖这个区间,这里可以先试用贪心的思想进行思考,因为战士之间的区间是不会完全覆盖的,所以只要每次是下一个选中区间的起点是当前区间中,最靠近选择区间末的区间,即可完成最少人数成环这一条件。 以此为依据,在原先来链的基础上,再copy(复制)一份每个区间都加上一个环时的情况,用以判断当区间跨过环时,存在2-5的区间,但无法求解的情况,同时,因为题目只规定了战士不会被完全覆盖,但其顺序可能是被打乱的,所以为了满足区间查找的单调性,对数组进行sort排序。改进后输入代码: //输入+处理 cin >>n>>m; for (int i=1;i<=n;i++) { //记录id,在输出结果时,是原序输出 w[i].id=i; cin >>w[i].l>>w[i].r; //破环成链 if (w[i].r<w[i].l)w[i].r+=m; } //起点排序 sort(w+1,w+n+1); //复制一份 n2=n*2; for (int i=n+1;i<=n2;i++) { w[i]=w[i-n]; w[i].l+=m; w[i].r+=m; } 接下来是查找区间,但注意,如果直接查找区间会导致是o(n^2)的时间复杂度,也就是超时,因此需要优化区间查找,为此,来到本次题解的重中之中,倍增(st)。 在使用倍增前,先了解倍增的使用条件:必须要有单调性,很显然,这个条件已经满足。 其次是倍增的原理:同二分一样,二分的作用是不断缩减数组,以此来找到需要的数,而倍增则是不断增大。它的运算原理可以参考二进制定理:2^n=2^(n-1)+2^(n-2)+...+2^0+1。 因此其运行规则为:先走2^n步,倘若大于等于数值则说明步数过多,倘若小于,将将步数加上2^n,加至最后,加起来的总步数会是要求步数-1的值。st的代码://贪心选择区间+st生成静态数据void st(){ //自建图: int next=1; //链上共n2条 for (int i=1;i<=n2;i++) { //找到每个区间离右端点最近的左端点所在的区间 while (next <= n2 && w[next].l<= w[i].r)next++; //记录区间 go[i][0]=next-1; } //倍增:i = 1,2,4,8,16..共 logn 次 for (int i=1;(1 << i)<=n;i++) { //枚举每条线段 for (int s=1;s<=n2;s++) { //若走2^3步,2^3= 2^2+2^2 //先从 s 到走2^2步到中转站 //再从中转站走2^2到终点 go[s][i]=go[go[s][i-1]][i-1]; } }} 构建完图后,即可运用图表进行求解每位士兵的最少人数,即st的调用。//st的使用 void getRes(int x){ //len为终点长度,该长度代表能否成环 //now为初始的节点 //ans记录人数,因为放入了自身的初始节点,所以人数至少为1 int len=w[x].l+m,now=x,ans=1; //i初始为log2(n),20是为了方便计算 for (int i=20;i>=0;i--) { //从大到小开始查找 int to=go[now][i]; //当to存在,长度在len内 if (to && w[to].r<len) { ans=ans+(1<<i); //累加跳过的区域 now=to;//从新位置开始 } } //记录时使用id记录人数,毕竟sort过了,但输出要使用原序列 //ans+1因为ans是小于len的,还无法成环, //但因为st性质,他的下一步必定大于len,此时可以成环 res[w[x].id]=ans+1;} 最后直接输出存入的数值,即可得出答案,这里直接放ac代码:#include <bits/stdc++.h>using namespace std;const int maxn = 4e5 + 10;int n, n2, m;struct Index{ int id,l,r;//编号+区间 //以起始点小的排序 bool operator<(const Index &b) const { return l< b.l;}};Index w[maxn*2];//破环成链,因此空间需要开两份int go[maxn][25];//倍增记录自建图int res[maxn];//记录结果//贪心选择区间+st生成静态数据void st(){ //自建图: int next=1; //在链上选择共n2条 for (int i=1;i<=n2;i++) { //每个区间的下一个右端点最大的区间 while (next <= n2 && w[next].l<= w[i].r)next++; //区间i的下一个区间 go[i][0]=next-1; } //倍增:i = 1,2,4,8,16..共 logn 次 for (int i=1;(1 << i)<=n;i++) { //枚举每条线段 for (int s=1;s<=n2;s++) { //若走 2^3 步,2^3= 2^2+2^2 //先从 s 到走2^2步到中转站 //再从中转站走2^2到终点 go[s][i]=go[go[s][i-1]][i-1]; } }}//st的使用 void getRes(int x){ //len为终点长度,该长度代表能否成环 //now为初始的节点 //ans记录人数,因为放入了自身的初始节点,所以人数至少为1 int len=w[x].l+m,now=x,ans=1; //i初始为log2(n),20是为了方便计算 for (int i=20;i>=0;i--) { //从大到小开始查找 int to=go[now][i]; //当to存在,长度在len内 if (to && w[to].r<len) { ans=ans+(1<<i); //累加跳过的区域 now=to;//从新位置开始 } } //记录时使用id记录人数,毕竟sort过了,但输出要使用原序列 //ans+1因为ans是小于len的,还无法成环, //但因为st性质,他的下一步必定大于len,此时可以成环 res[w[x].id]=ans+1;}int main(){ //输入+初步处理 cin >>n>>m; for (int i=1;i<=n;i++) { w[i].id=i; cin >>w[i].l>>w[i].r; //破环成链 if (w[i].r<w[i].l)w[i].r+=m; } //起点排序 sort(w+1,w+n+1); //复制一份 n2=n*2; for (int i=n+1;i<=n2;i++) { w[i]=w[i-n]; w[i].l+=m; w[i].r+=m; } //倍增(st)开始 st(); //循环得出每个节点的最少成环人数 for (int i=1;i<=n;i++)getRes(i); //输出答案 for (int i=1;i<=n;i++)cout <<res[i]<<" "; cout <<"\n"; return 0;}
点赞 1
评论 1
全部评论
推荐
最新
楼层
还没有回复哦~
相关推荐
11-19 15:08
中国矿业大学(北京) 后端
25届浙江二本JAVA简历:估计投500份,最多3-5个面试
注:为保证用户信息安全,姓名和学校等信息已经进行同层次变更,内容部分细节也进行了部分隐藏另外:我们出这一系列校招简历指导的原因,就是看很多学生被忽悠,没有先定位大厂、中厂还是小公司,导致没有面试机会。 我们不放任何的广告和品牌名,完全是反馈牛客社区。大家也不要私信,现在比较忙,没空帮大家改简历。简历总体说明校招的第一法则就是必须要确定校招层次。开发岗分为大中小厂,不同的层次对学校背景、时间点、项目和考点的要求都不太一样,所以必须要确定就业的层次。 这是一份25届某二本的计算机的JAVA简历。如果是我们的老粉丝会知道,HR第一眼要看你学的专业满不满足招聘需求,所以投递简历的时候一定要注意,先...
投递联想等公司10个岗位 >
简历中的项目经历要怎么写
你觉得哪一届的校招最难?
点赞
评论
收藏
分享
11-20 17:20
山东理工大学 网络工程师
字节HR面挂,故事终究是没能等来想要的结局
字节hr面后泡39天挂,下周又下周的泡,泡的身心俱疲呀要说没有心理准备是假的,其实看了这么多人的经历,对这个流程也大概有个认识过了这么久,结果也很显而易见了,只是感觉多少有些遗憾吧,已经走了这么远,或许这可能真的是人生仅有一次去字节的机会了,作为网工,字节那么多的网络类岗位,我不敢想象在里面能接触到多少这个领域的知识我并不像很多大佬一样,手握无数的机会,区区字节不要也罢——我并不具备这种自信和底气The testaments they toldThe moon and its eclipseAnd Superman unrollsA suit before he liftsBut I'm no...
秋招你被哪家公司挂了?
字节求职进展汇总
点赞
评论
收藏
分享
10-04 17:25
门头沟学院 Java
双非JAVA后端简历,求拷打
某软件投了接近700份,回应寥寥无几。去官网投也没个回复
snqing:
Java已经饱和了,根本不缺人。随便一个2000工资的都200人起投递
点赞
评论
收藏
分享
11-20 22:23
上海交通大学 产品经理
面试篇 面试稳了还是挂了,怎么预判
面试分为很多种,个面或者群面,hr面或者业务面。对于心仪的公司岗位,我们往往迫不及待想知道面试结果,成熟公司一般不会直接当场告诉面试结果,那怎么通过和面试官沟通预判面试结果?先说面试稳了的迹象。1,面试官主动介绍部门和业务情况,并和你一起探讨业务问题,就差给你分配任务了2,面试官开始推销部门重要,业务核心,团队优秀和文化和谐,一副生怕你不接offer的担忧3,面试官和你沟通中已经超时,不介意延长时间继续聊,有点相见恨晚的感觉4,面试官咨询你是否可以提前来实习以及实习时间等再说面试挂了的迹象。1,面试官听完自我介绍,问了几个问题后,表现出无所谓甚至不耐烦的样子2,面试官对一些问题连续追问无果后,...
毕业求职不EMO
总结:哪家公司面试体验感最差
牛客创作赏金赛
点赞
评论
收藏
分享
点赞成功,聊一聊 >
点赞
收藏
评论
分享
回复帖子
提到的真题
返回内容
全站热榜
1
...
双非本科四年的总结
2.0W
2
...
sagima的阎良出差日记
1.4W
3
...
给正在秋招中枯燥的大家找个乐子听听吧,不被理解真的心寒
1.3W
4
...
简历这样写真的很难挂
8440
5
...
收到offer了!!!!
7419
6
...
浅谈二本Javaer进大厂的感悟
7200
7
...
请大家警惕“总包”骗局!
7076
8
...
提前化身黑子,保温了两次的华为,报批挂了
5107
9
...
双非文科本秋招三个大厂offer 我悟了
5093
10
...
大哥爆发了?
4766
正在热议
#
25届秋招总结
#
264447次浏览
2192人参与
#
0offer是寒冬太冷还是我太菜
#
887626次浏览
7910人参与
#
北方华创开奖
#
23692次浏览
260人参与
#
地方国企笔面经互助
#
2849次浏览
7人参与
#
学历or实习经历,哪个更重要
#
43486次浏览
329人参与
#
选完offer后,你后悔学本专业吗
#
13364次浏览
94人参与
#
查收我的offer竞争力报告
#
19619次浏览
256人参与
#
应届生被毁约被毁意向了怎么办
#
28242次浏览
243人参与
#
你最想要的公司福利是?
#
41912次浏览
146人参与
#
如何一边实习一边秋招
#
987464次浏览
12609人参与
#
一觉醒来,我觉醒了超级打工人系统
#
3325次浏览
36人参与
#
嵌入式转岗的难度怎么样
#
11209次浏览
251人参与
#
你最希望上岸的公司是?
#
76593次浏览
469人参与
#
如何写一份好简历
#
605123次浏览
8511人参与
#
面试体验感最好的是哪家?
#
83675次浏览
818人参与
#
机械应届生薪资要多少才合适?
#
12546次浏览
61人参与
#
牛客十周岁生日快乐
#
48780次浏览
759人参与
#
你认为第一份工作重要吗
#
5457次浏览
49人参与
#
985本硕1个中小厂offer,摆烂or继续努力
#
79964次浏览
589人参与
#
秋招OC许愿
#
228271次浏览
1881人参与
#
来聊聊机械薪资天花板是哪家
#
65797次浏览
445人参与
牛客网
牛客企业服务