- 博客(25)
- 收藏
- 关注
原创 处理斜率问题
如果需要储存斜率或者判断一点是否在一条直线上,可以用向量储存斜率(如(x1-x0,y1-y0))此前提是要化简,即除去gcd,并且应对象限进行处理,如(-3,4)和(3,-4)是否在一条直线上,就需进行判断如果x<0的话可将x,y直接进行变号用set存储(set自动去重)例题:消灭老鼠#include<iostream>#include<algorithm>#include<set>using namespace std;typedef pair&
2022-03-06 19:26:05 831
原创 金发姑娘和 N 头牛
解题思路:这头牛在数轴赏每上每个区域的贡献度不同,需要将每头牛的在数轴上不同区间的贡献度用差分数组记录下来,寻找最大的一块区域即可。题目链接 for (int i = 0; i < n; i ++ ) { int l, r; scanf("%d%d", &l, &r); b[-INF] += x; b[l] += y - x; b[r + 1] += z - y; b[I...
2022-01-21 00:03:14 296
原创 美丽序列(dp)
美丽序列思路:f(i,j,L,k)表示处理到 i 个数且上个数为j 在递减序列中为序为L 当前和为k的美丽序列数量#include<iostream>#include<algorithm>using namespace std;const int N = 45,M=1e9+7;int a[N];int f[N][N][3][1650];int main(){ int n; cin >> n; for (int i = 1; i &l...
2022-01-06 00:02:44 297
原创 牛客 删括号
删括号思路:在思考这题时发现此题和编辑距离题目十分相似。编辑距离对于本题题目的状态设置看完题解后感觉十分巧妙,在原有二维基础上加了个记录删除’(‘括号数来进行状态转移。状态设置:布尔类型(bool)f(i,j,k)表示s串删除进行删除操作后,可以与t串匹配,删除的左括号与右括号之差为k。也就说明当k为0时删除的是合法序列。那么状态如何转移呢:不难发现在dp[i][j][k]合法的情况下,如果此时 s[i]=t[i]且k=0 那么说明dp[i+1][j+1][0] 也是合法的。而后对于...
2021-12-30 00:16:05 562
原创 被3整除的子序列
被3整除的子序列思路首先研究下此题目的状态空间,比如132这个集合{1,3,2,12,13,23,132}在这个状态集合中寻找能被3整除的数量(即各个数相加和能被3整除),那么如何设计存储这个状态空间以及状态如何转移呢,比如现在字符串为13的状态空间为{1,3,13},后面添加个字符串即在此状态空间基础上每个状态都加一个后面的字符串,最后加上那个字符串本身。那么这样可构思出如何存储状态空间。f[ i ] [ j ]:表示进行到第i个字符串时,%3为j数的个数那么f[i][j]的数可由f[i-1]..
2021-12-28 11:37:57 516
原创 穿过圆(bitset)
题目链接穿过园题目大意平面上又许多不相交的园包围着点,每回询问两个点 a ,b 询问从a到b至少穿过多少个圆。思路最开始想到暴力的解法,也就是对每个点进行遍历,看其是否在园内,并将此点在多少个园内的数量记录在一个数组cnt中,然后记录a和b在相同园内的数量(假设记作k),拿cnt[a]+cnt[b]-2*k即为答案,这样做的时间复杂度过大无法通过题目要求。听课后学会了一种压位的做法,即用bitset存储这个点对于各个园的状态,在园内为0,在园外为1,然后将两个点的二进制位数亦或,此时二进制...
2021-12-27 00:26:23 144
原创 移动服务(dp)
移动服务状态设置:f[i][x][y]表示已经处理完前i个请求,且三个服务员分别在p[i], x, y的所有方案的集合;f[i][x][y]的值是集合中所有方案的花费的最小值;状态转移:有两种状态转移方式一种是一个状态由上一层的三种情况得到,一种是一个状态向下一种状态转移时只有三种情况,显然后者对于此题较为好算,也就是用i计算i+1的值。因为向下一个状态枚举时,一定有一个状态位于p[i]处,另外两个位于x和y处,就此可以有三种状态向下一个状态枚举,而对于最开始时,也就是p[0]处,状态..
2021-11-01 20:56:38 344
原创 KMP模板
next[i]数组的含义:若next[i]=j 则表示为下标为i的字符其最长前后缀为j,并且规定next[1]=0;匹配的过程:假设s[ ]为模板串 (较长) p[ ]为模式串(较短),当s[i]!=p[j+1]时,也就是j+1之后不配对但1~j+1时符合,此时挪动模式串至next[j],因为此时j的next[j]保存的是以j结尾的前后缀长度,所以只需要将模板串从next[j]开始匹配即可。求next[ ]模板for (int i = 2, j = 0; i <= n; i ++ )
2021-09-08 22:17:19 93
原创 Codeforces Round #714 (Div. 2) B. AND Sequences (思维)
题目题目大意:给定一个数据,求其全排列中满足 以下条件的数量。大致思路:如果想要等式左边等于右边,即二进制的每一位相等,那么必须找到一个数,即&上其他数对整个数不会产生影响,将这两个数放到等式两边,即可一定满足等式两边相等,那么怎么求这个数呢? cin>>a[0]; ll k=a[0]; //将k&上数组中所有的数,找到那个不会影响等式两边的数 for(int i=1;i<n;i++) { scanf("%lld",&a[i..
2021-04-12 20:05:41 174
原创 记忆化搜索(模板题)
滑雪dfs做法(超时)#include<iostream>#include<algorithm>using namespace std;const int N=310;int r,c;int h[N][N];int dx[]={0,1,0,-1};int dy[]={1,0,-1,0};int dfs(int x,int y){ int cnt=1; int max_cnt=0; for(int i=0;i<
2021-03-31 20:20:10 290
原创 cf B. Box Fitting(贪心+优先队列) 题解
B. Box Fitting大致思路:开一个优先队列,开始将w入队,因为方块高度全为1,故只看其长度即可,将其从大到小排队,优先队列里存每一行的剩余容量,如果a[i]大于与队顶(放不下),则开辟新一行,及将(w-a[i])入队,否则将(q.top()-a[i])入队,最后队列长度即为答案。#include<iostream>#include<algorithm>#include<queue>using namespace std;const int
2021-03-30 20:01:07 715 1
原创 树状数组学习(例题及题解)
树状数组:可以动态维护前缀和,查询时间复杂度O(log2n),修改时间复杂度O(log2n)。树状数组记录前缀和的方式为这个数的二进制表示中从长度是从右往左的第一个0的大小,即长度为x-lowbit(x)+1。代码模板int tr[N];int lowbit(int x) //求第一个0的位置{ return x & -x;}void add(int x, int c) 在位置为x的地方加上c{ for (int i = x; i <= n; i += .
2021-03-24 21:25:06 422
原创 日期类问题(蓝桥)
判断日期是否正确的模板int days[]={0,31,28,31,30,31,30,31,31,30,31,30,31}; //记录下每个月的天数,注意开头要加个0bool check(int data){ int year=data/10000,month=data/100%100,day=data%100;//提取出年月日 if(month>12||day==0||month==0) return false; if(month!=2&&day
2021-03-23 21:26:06 96
原创 带分数题解
带分数解题思路a,b,c三个没有相同数字。1.暴力枚举出9个数字的全排列。2.从全排列的结果中用两重循环暴力分解出三段,每段代表一个数。3.验证这三个数是否满足要求。全排列函数做法#include<iostream>#include<algorithm>using namespace std;typedef long long ll;int a[9]={1,2,3,4,5,6,7,8,9};int n;int cal(int s,int e)
2021-03-18 11:12:27 126
原创 费解的开关题解
费解的开关题目大意:给出一个5*5的01正方形,0表示灯关,1表示灯开。改变一个灯的状态要同时改变其上下左右的状态。输出将灯全部打开的最小步数,无法完成则输出-1。大致思路:1.每一个位置只会操作一次,操作两次等于没有操作没有意义2.对于每一行操作的顺序无关紧要3.假设确定了第一行的操作,那么能改变第一行的只能是第二行的开关,即如果第一行的灯是灭的,那么第二行同一列的灯必须改变状态让第一行变亮。4.当到最后一行时只需判断灯是否为全亮,如果为全亮则此方案合法故只需要得出第一行的顺序,后面的顺序
2021-03-18 10:38:25 235
原创 导弹拦截题解(dp+Dilworth定理)
导弹拦截本题的第一问为最长不上升子序列,重点在于第二问。第二问可分为两种做法1.贪心做法用如下方式维护数组g,数组长度cnt,意为cnt个不下降子序列。保存的是每一个不上升子序列中的最后一个数:遍历原序列,对于遍历到的每一个数x:1.若x大于g中每一个数,则新建一个不上升子序列,放入x;2.否则,找到g中大于等于x的最小的数,将其替换。由于g每次增加长度时,增加的数必然大于其前面g中的任何一个数;且每次替换时,不改变x与被替换数左右相邻两数的相对大小关系,故g必然维持单调递增。则g即为原..
2021-03-09 14:44:44 183
原创 食物链题解(并查集)
食物链首先可知 A 吃 B,B 吃 C,C 吃 A。故知道A和B,B和C的关系,便可推出A和C的关系。主要思想维护一个集合,若两动物已经在集合中,便可判断其关系是否正确,若不在集合中,便可加入集合。那么怎么判断当前加入的动物是A,B,C中的哪类动物呢?可以用一个距离数组记录(假设为d),那么d[i]为动物i到根节点的距离,将其%3即d[i]%3即可判断他是哪类动物(假设1吃0,2吃1,0吃2)并且不断维护这个数组即可。那么并查集find的模板代码为int find(int x) //p[..
2021-03-09 11:12:55 299
原创 最长上升子序列优化(贪心o(nlogn))
最长上升子序列贪心思路将每个上升子序列结尾元素的最小值存储下来,在计算长度时中只需在q数组中二分查小于此元素(假设为a[i])的最大数值即可,此时位序+1即为本数的最长上升lenth大小。代码模板#include <iostream>#include <algorithm>using namespace std;const int N = 100010;int n;int a[N];int q[N];int main(){ scanf("%.
2021-03-04 20:33:53 171 1
原创 方格取数题解(线性dp)
方格取数题目分析本题目是考察了dp中的数字三角形模型,只不过从一维上升到了二维。其中f[ i1 , j1 , i2 , j2 ] : 由数字三角形可以推广出从(1,1),(1,1)(1,1),(1,1)走到(i1,j1),(i2,j2)(i1,j1),(i2,j2)能获得的最大花生数目.主要思想把 f[i1][j1][i2][j2]f[i1][j1][i2][j2] 转化为 f[k][i1][i2]。其中k=i1+j1=i2+j2k=i1+j1=i2+j2: 两个小朋友同时走, 每..
2021-03-02 21:45:09 180
原创 八数码题解(bfs)
八数码分析本题是求最少交换次数,故先想到bfs,而本题的难点在于状态和步数的存储。以及状态的转移。如何记录下x和一个数交换后的状态?如何记录步数?主要思想一个巧妙的思想可以解决此类问题,状态可以用string类型来记录,求在3*3矩阵中的横纵坐标无非就是将其在string类型中的位序(假设为k)x=k/3,y=k%3。而查询起来也异常放边 直接用find函数即可找到(string类型作为stl的优势),而它的交换次数可用哈希来存储 即可定义unordered<string,int>..
2021-02-25 18:03:04 126
原创 C. Sum of Cubes(打表)题解
题目链接题目大意:给出一个数x判断是否有存在a,b使得a3+b3=x。思路:因为x的范围1<=x<=1012,故可判断出i是从1到10000循环,且时间限制在2s内,故可用打表的方法判断是否存在a,b。#include<iostream>#include<algorithm>#include<map>using namespace std;typedef long long ll;map<ll,int> m;int mai.
2021-02-22 20:45:54 243
原创 (线性dp)最长公共子序列 最短编辑问题 题解
最长上升子序列状态表示:f[i,j]表示为所有在第一个序列前i个字母中出现,第二个序列前j个字母中出现的子序列的最长长度。状态计算:将此问题分解成两半考虑如果两个字符相等,就可以直接转移到f[i-1][j-1],不相等的话,两个字符一定有一个可以抛弃,可以对f[i-1][j],f[i][j-1]两种状态取max来转移。代码#include <iostream>using namespace std;const int N = 1010;int n, m;char a[N]
2021-02-17 20:18:42 99
原创 背包九讲(1)
对于背包问题的状态表示:F[i,j]通常表示为对于不超过i个物品,背包容量不超过j的最大价值n表示物品数量,m表示背包容量。01背包问题01背包问题代码模板 for(int i=1;i<=n;i++) for(int j=0;j<=m;j++) { f[i][j]=f[i-1][j]; if(j-v[i]>=0) f[i][j]=max(f[i][j],f[i-1][j-v[i]]+w[i]);
2021-02-11 16:19:16 118
原创 数论学习(1)
质数概念:质数是指在大于1的自然数中,除了1和它本身以外不再有其他因数的自然数。如何判定质数?代码模板 时间复杂度O(sqrt(n))bool is_prime(int x) (试除法){ if (x < 2) return false; for (int i = 2; i <= x / i; i ++ ) if (x % i == 0) return false; return true;}因为因数总是成对出现的,
2021-02-04 22:17:33 490
原创 acwing学习笔记
差分作用: 用O(1)的时间复杂度完成对区间[l,r]加上c。思路:如要完成对a数组中的区间完成次操作,则需要构造辅助数组b来完成,b数组的实际含义为 b的前缀和为a(a3=b1+b2+b3)。例:一维差分如何构造差分数组构造差分数组在建立a数组时即可完成for(int i=1;i<=n;i++){ cin>>a[i] ; insert(i,i,a[i]);//相当于每次在i位置加上a[i]}如何完成区间加减void insert(int l,i
2021-01-26 21:05:19 810
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人