12 2020 档案

摘要:原题链接 KMP+前后缀匹配 别人眼里的模板题我能做N个小时... 错解思路: 将所给的未转化完成的字符串全部转化为第二种状态(即未翻译的状态),和上题一样的思路,将原串和新串和空格拼接在一起求公共前后缀,再利用公共前后缀求剩下的还未被纳入第二部分的原串.如果这样写易错点是aaaaa(密码文里a-> 阅读全文
posted @ 2020-12-31 22:39 acmloser 阅读(131) 评论(0) 推荐(0) 编辑
摘要:原题链接 如果直接枚举字符串前缀的子串,再将子串赋值到一个新串,就会O(n^2)超时,因此必须考虑优化 正确思路: 通过观察规律,我们可以发现当出现前缀在字符串出现次数为1的时候,后面包括这个前缀的新串,在字符串的出现次数也为1,经此优化即可 思路2: 根据ne数组计数,当ne[i]!=0时,ans 阅读全文
posted @ 2020-12-31 17:50 acmloser 阅读(80) 评论(0) 推荐(0) 编辑
摘要:原题链接 KMP+字符串的运用 一开始计算错了时间复杂度,还以为可以直接暴力.... 错解思路: 求公共最长的前缀和后缀,如果直接将字符串拼接在一起,如果遇到这样的测试样例eg:s1 = aaa,s2 = aaa就会输出错误,所以我们必须分隔开s1和s2 正解思路: 我们不能让s2认为属于s1部分的 阅读全文
posted @ 2020-12-31 10:41 acmloser 阅读(69) 评论(0) 推荐(0) 编辑
摘要:原题链接 求后缀凑成循环串还差几个字符 KMP练习 从前面的无线传输我们已经懂了怎么利用KMP求循环串长度,这里我们从尾下标就可以判断末尾是循环串的第几个字符 但这里有多种情况,分类讨论即可 1 #include <iostream> 2 #include <cstdio> 3 #include < 阅读全文
posted @ 2020-12-30 23:45 acmloser 阅读(70) 评论(0) 推荐(0) 编辑
摘要:原题链接 翻译一下题目就是求主串里有多少个子串 数据很小,貌似暴力就能过.但写这道题主要是练习KMP 默写KMP模板,j回溯时不要ne[j]直接等于0即可 j = ne[j]是求重叠子串的本质 1 #include <bits/stdc++.h> 2 using namespace std; 3 c 阅读全文
posted @ 2020-12-30 23:42 acmloser 阅读(78) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察KMP的运用 错误思路: 我是求字符串中没有重合的最长前后缀,但这样的思路遇到cabc这样的测试数据显然是错误的,因为字符串复制时不一定会复制>=两遍 正解思路: 按上面的思路,如果字符串复制两遍及以上,那么j的最大值就是答案,如果字符串复制少于2遍,答案应该是公共前后缀的长度+没有公 阅读全文
posted @ 2020-12-30 13:07 acmloser 阅读(60) 评论(0) 推荐(0) 编辑
摘要:原题链接 很容易分析出边界点是身高比h[i]高的人,单调栈里是形成单调递减栈.能与h[i]形成一对的人h<=h[i],而且h[i]能看到离他最近的比他高的人,所以本题我们需要利用单调栈的边界点和while循环里pop的点,因为要避免重复,所以我们只需要从左边或右边开始计算对数,而且我们还需要统计身高 阅读全文
posted @ 2020-12-29 13:58 acmloser 阅读(69) 评论(0) 推荐(0) 编辑
摘要:原题链接 在二维上运用单调队列,我们可以想象在矩阵上移动滑动窗口,以左上角为起点,在在窗口内部我们对每一行求最值,再对每一列求最值,那么左上角的元素一定是最值,只需要将每个滑动窗口最值存储即可 没什么坑,有思路很快就能做出来 1 #include <bits/stdc++.h> 2 using na 阅读全文
posted @ 2020-12-29 13:57 acmloser 阅读(112) 评论(0) 推荐(0) 编辑
摘要:原题链接 思路是来自y总的视频...我的第一反应是dfs.... 求最大矩形面积我们可以联想到那道经典的单调栈例题,因为这道题的n、m都不是很大,所以我们可以用O(n^2)的算法。枚举每一行,将每一行以及上面的矩形都看成直方图,即把每列F的个数当作那道题的阴影部分的高度,然后我们在每一行求它的左右最 阅读全文
posted @ 2020-12-29 13:52 acmloser 阅读(104) 评论(0) 推荐(0) 编辑
摘要:原题链接 根据题意,我们需要移除k位数字,并且让剩下的数最小,很明显光是找最大的数是没用的,我们需要找的是高位数且这位数字比下一位数字大,说明这一位数字移除就可以让剩下数字更小.但是也有可能出现移除位数不够的情况,此时的单调栈内是单调上升的序列,所以移除前面的数字只会让剩下的数字更大,所以我们要移除 阅读全文
posted @ 2020-12-29 13:50 acmloser 阅读(118) 评论(0) 推荐(0) 编辑
摘要:原题链接 本题是就是上一道乐扣将去除k位数字的要求换成了去重.要求同样是字典序最小. 这道题的注意点就是: 去重(只出现一次的再大也不能去掉) 已经在栈里的小写字母不需要再push进入,不管它多小 因此很容易分析出此单调栈是单调递增栈,到时候将栈内元素pop出再反转即可 1 class Soluti 阅读全文
posted @ 2020-12-29 08:54 acmloser 阅读(88) 评论(0) 推荐(0) 编辑
摘要:原题链接 光是题目读懂都花了很多时间 题意: n个订单,m长的营业时间(注意不止24h),给你月饼保鲜时长t,以及月饼制造成本s,求制作完N个订单的最小成本 这道题的小时制作成本是在1~m之间,也就是不是24小时制,我个人认为很坑的是第i小时的制作成本不是i~i+1小时,而是i-1~i小时.所以这道 阅读全文
posted @ 2020-12-28 18:29 acmloser 阅读(73) 评论(0) 推荐(0) 编辑
摘要:原题链接 如果把其中一个数组去掉,就是上道题去掉k位数字,获得最小数字的另一个描述.将上道题的top>a[i]改成top<a[i]即可. 但这道题有两个数组,两个数组总共需要去掉k位数,使得这k位数最大. 我的错解思路是将两个数组都排进一个数组里,但这样解不出来,并且排序很难排序.完全没有想过枚举( 阅读全文
posted @ 2020-12-27 19:17 acmloser 阅读(94) 评论(0) 推荐(0) 编辑
摘要:原题链接 单调队列+前缀和 之前一直不理解滑动窗口,通过这道题理解了点,i是窗口右边节点,i-k+1是窗口左边界点,而单调队列是用来求该窗口相关属性的一个工具,q[hh]不一定等于窗口的左边界. 比如,本道题q[hh]是用来求窗口下最小和的下标,与i-k+1的下标无关,我们求cnt是否+1只需要判断 阅读全文
posted @ 2020-12-27 19:12 acmloser 阅读(85) 评论(0) 推荐(0) 编辑
摘要:原题链接 前缀和+单调队列 这题维护的不是[i-k+1,i]的区间,而是[i-k,i-1]的区间,因为我们要求前缀和的最大值,这道题如果让单调队列维护递减的序列,而边界点不好确定(因为我们不知道区间多大),这样就不利于求前缀和,可以转化一下,让单调队列维护区间最小值,用当前的前缀和sum[i]减去区 阅读全文
posted @ 2020-12-27 19:07 acmloser 阅读(123) 评论(0) 推荐(0) 编辑
摘要:原题链接 单调队列+前缀和 本题需要用到上题的破环成链的思想,因为可以正反方向两个方向找切割点,因此我们需要正反两个方向的前缀和,当我们反向搜索时,没必要从size()-1开始,可以同样设下标为1,然后从2*len-1开始加前缀和. 这里有几个需要注意的点: 这里需要将字符串转化成数字,如果在首位插 阅读全文
posted @ 2020-12-27 19:04 acmloser 阅读(78) 评论(0) 推荐(0) 编辑
摘要:原题链接 根据题意,很明显我们需要两个单调队列分别维护最小值与最大值.这里我用了双指针指向窗口的起点与终点.要注意的是如果差<m或者符合条件我们需要更新窗口的右端,如果>k我们需要更新窗口的左端 答案最小可以取0,所以maxn不要设置为负数 注意,第一次一定可以进while循环的,因为第一次队列差值 阅读全文
posted @ 2020-12-27 19:02 acmloser 阅读(91) 评论(0) 推荐(0) 编辑