随笔分类 - ACM / 双指针
摘要:原题链接 考察:单调栈 错误思路: 枚举滑动窗口大小,从头到尾计算.TLE O(n2) 正确思路: 根据a[i]对答案的贡献来计算,由题意得ans += (r-l)*a[i] 其中r是a[i]作为最大值的区间个数,l是a[i]作为最小值的区间个数.那么问题是如何计算区间个数. 首先明白单调栈和单调队
阅读全文
摘要:原题链接 考察:前缀和+二分+双指针 补一个大佬的神级解法 Go 错误思路: 纯双指针处理,写了几个小时没写出来..... 思路: 前缀和预处理,sum[i]表示1~i坐标有多少个1,那么[l,r]区间内1的个数为sum[r] - sum[l-1],那么我们可以枚举端点,计算[l,r]区间里有多少个
阅读全文
摘要:原题链接 考察:二分 再做一次还是没想到系列 蒟蒻本蒻 思路: 这道题的check函数很好想,就是枚举端点,找到区间>=l&&平均值>=mid的区间.暴力枚举是sum[j]-sum[i]>=(j-i)*mid.我们需要进行优化,要将二重循环优化到一维,i必须省去,我们求[i,j]区间是否平均值>=m
阅读全文
摘要:原题链接 考察:二分 思路: 嵌套二分,和上一题Matrix差不多,中位数和排序后的a数组都具有单调性. 更好的check函数是,score是a[j]与a[i]的差值,已经确定a[j],那么可以求出a[i]的位置(lower_bound),从而计算前面有多少个符合条件的. 为什么本题不会有不存在的情
阅读全文
摘要:原题链接 考察:二分 第一次做这题我还以为是dfs..... 思路: 首先烘干时间符合单调性,二分烘干时间,难点在如何写判断函数.首先两种情况: a[i]<=s,直接无视. a[i]>s,需要考虑它用烘干机的时间,注意不能直接算把它烘干完的时间,因为浪费的时间没有利用,假设它用烘干机的时间是t,那么
阅读全文
摘要:原题链接 考察:二分 思路: 首先这道题不是让我们求坐标,而是求具体的值.观察式子,当j不变时,i增大,值增大.分数满足单调性,j不变时,i也满足单调性.二分分数,枚举每一列有多少个满足分数<小于当前score,根据总数再继续二分score.在枚举每一列时,i也满足单调性,所以也用二分枚举i. 注意
阅读全文
摘要:原题链接 考察:双指针 思路: 很明显的双指针裸题,当i往前一步的时候,j要保持在与i在D的距离外. 1 #include <iostream> 2 #include <algorithm> 3 #include <cstring> 4 #include <set> 5 using namespac
阅读全文
摘要:原题链接 考察:双指针 or 二分排序 or 前缀和 思路: n<=105 n2的时间复杂度也会超时,所以我们只能枚举一个数,这就必须要利用乘法原理求得答案,已知题目要求 ai<bj<ck如果我们枚举aior ck可以发现无法省略其他层枚举,而我们枚举b,c与a就能利用乘法原理,找到小于bj与大于b
阅读全文
摘要:原题链接 考察:二分 or 递推 思路一: 二分初始能量值,check函数检查即可.要注意的是每次E都+=E-h,也就是 E = 2*E-h. 2100000不管用什么数据类型都会爆,因此必须考虑别的做法:此时思路有二: 高精度,但是高精很慢,尽量避免高精 避开运算,在E一定满足条件就return
阅读全文
摘要:原题链接 很容易分析出边界点是身高比h[i]高的人,单调栈里是形成单调递减栈.能与h[i]形成一对的人h<=h[i],而且h[i]能看到离他最近的比他高的人,所以本题我们需要利用单调栈的边界点和while循环里pop的点,因为要避免重复,所以我们只需要从左边或右边开始计算对数,而且我们还需要统计身高
阅读全文
摘要:原题链接 在二维上运用单调队列,我们可以想象在矩阵上移动滑动窗口,以左上角为起点,在在窗口内部我们对每一行求最值,再对每一列求最值,那么左上角的元素一定是最值,只需要将每个滑动窗口最值存储即可 没什么坑,有思路很快就能做出来 1 #include <bits/stdc++.h> 2 using na
阅读全文
摘要:原题链接 思路是来自y总的视频...我的第一反应是dfs.... 求最大矩形面积我们可以联想到那道经典的单调栈例题,因为这道题的n、m都不是很大,所以我们可以用O(n^2)的算法。枚举每一行,将每一行以及上面的矩形都看成直方图,即把每列F的个数当作那道题的阴影部分的高度,然后我们在每一行求它的左右最
阅读全文
摘要:原题链接 根据题意,我们需要移除k位数字,并且让剩下的数最小,很明显光是找最大的数是没用的,我们需要找的是高位数且这位数字比下一位数字大,说明这一位数字移除就可以让剩下数字更小.但是也有可能出现移除位数不够的情况,此时的单调栈内是单调上升的序列,所以移除前面的数字只会让剩下的数字更大,所以我们要移除
阅读全文
摘要:原题链接 本题是就是上一道乐扣将去除k位数字的要求换成了去重.要求同样是字典序最小. 这道题的注意点就是: 去重(只出现一次的再大也不能去掉) 已经在栈里的小写字母不需要再push进入,不管它多小 因此很容易分析出此单调栈是单调递增栈,到时候将栈内元素pop出再反转即可 1 class Soluti
阅读全文
摘要:原题链接 光是题目读懂都花了很多时间 题意: n个订单,m长的营业时间(注意不止24h),给你月饼保鲜时长t,以及月饼制造成本s,求制作完N个订单的最小成本 这道题的小时制作成本是在1~m之间,也就是不是24小时制,我个人认为很坑的是第i小时的制作成本不是i~i+1小时,而是i-1~i小时.所以这道
阅读全文
摘要:原题链接 如果把其中一个数组去掉,就是上道题去掉k位数字,获得最小数字的另一个描述.将上道题的top>a[i]改成top<a[i]即可. 但这道题有两个数组,两个数组总共需要去掉k位数,使得这k位数最大. 我的错解思路是将两个数组都排进一个数组里,但这样解不出来,并且排序很难排序.完全没有想过枚举(
阅读全文
摘要:原题链接 单调队列+前缀和 之前一直不理解滑动窗口,通过这道题理解了点,i是窗口右边节点,i-k+1是窗口左边界点,而单调队列是用来求该窗口相关属性的一个工具,q[hh]不一定等于窗口的左边界. 比如,本道题q[hh]是用来求窗口下最小和的下标,与i-k+1的下标无关,我们求cnt是否+1只需要判断
阅读全文
摘要:原题链接 前缀和+单调队列 这题维护的不是[i-k+1,i]的区间,而是[i-k,i-1]的区间,因为我们要求前缀和的最大值,这道题如果让单调队列维护递减的序列,而边界点不好确定(因为我们不知道区间多大),这样就不利于求前缀和,可以转化一下,让单调队列维护区间最小值,用当前的前缀和sum[i]减去区
阅读全文
摘要:原题链接 单调队列+前缀和 本题需要用到上题的破环成链的思想,因为可以正反方向两个方向找切割点,因此我们需要正反两个方向的前缀和,当我们反向搜索时,没必要从size()-1开始,可以同样设下标为1,然后从2*len-1开始加前缀和. 这里有几个需要注意的点: 这里需要将字符串转化成数字,如果在首位插
阅读全文
摘要:原题链接 根据题意,很明显我们需要两个单调队列分别维护最小值与最大值.这里我用了双指针指向窗口的起点与终点.要注意的是如果差<m或者符合条件我们需要更新窗口的右端,如果>k我们需要更新窗口的左端 答案最小可以取0,所以maxn不要设置为负数 注意,第一次一定可以进while循环的,因为第一次队列差值
阅读全文

浙公网安备 33010602011771号