自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(39)
  • 收藏
  • 关注

原创 Codeforces 847 div3 A-F

给每个给定的序列的a[j]->a[j+1]建一条边来代表它们的先后顺序,然后记录每个点的入度,然后会发现第一个数的入度一定为0,然后按照拓扑排序做,最后输出拓扑序列就是答案了。每次遍历到数a[i],直接从a[i]往后一个一个数,看map中该数的个数是否大于等于1,如果是则数的个数减一且接着往后数,否则就不再数下去了。不同的是,那题要去掉第一个数,给后面的数建边;x的二进制位0的位置,a和b一定相同,要么0要么1,假设a和b同时为1的那些位置的二进制权值和为t,则a=x+t,b=0+t。

2024-08-15 22:56:16 548

原创 Codeforces 855 div3 A-F

一共25个字符,所以枚举那个不存在的字符(假设编号为i),然后枚举所有不存在该字符的字符串,找到该字符串对应的状态b[j],两个字符串合体成为一个字符串时,它们的状态b直接异或就是新的字符串的状态了,因为只有。每次删两个字符,故删除的情况有n-1种,可以形成n-1个新的字符串,答案ans最初为n-1,但是每次遇到s[i-1]==s[i+1]时,我们就要将ans--换,一次类推,i,i+1,i+2,... 都是可以互换的,如果所有s[i]和t[i]不同的字符都可以互换,则一定可以将s变成t。

2024-08-15 22:52:25 751

原创 Codeforces 874 div3 A-G

这题是n个点n条边,每个点最多只有两个邻点,且可能有重边,所以一个连通块最多一个环,在合并两个点的时候,记录是否有环,如果有,则sum3++,记录连通块的个数sum2。,然后到了下一个区间,就要将该区间的第一个数去掉,类似于滑动窗口,把数去掉的同时还要除以第一个数的个数,新加一个数就要乘以新加的数的个数。排序去重后的结果为6,7,8,9,10,11,个数分别为1,1,1,1,2,1。7,8,9,10,该方案的个数为1*1*1*2=2。6,7,8,9,该方案的个数为1*1*1*1=1。

2024-08-10 22:04:31 957

原创 Codeforces 867 div3 A-G2

第二次dfs2利用换根DP,也是从1开始搜,计算时先不减去操作的花销c,将每个点到达其他点的最大距离都求出来,然后在统计答案的时候把每个点的d1减去c*该节点的深度。用个map记录a种每个数出现的次数,然后枚举每个数作为中间的数,枚举中间的数的因子判断两边的数是否存在,存在答案就加上mp[x]*mp[x/b]*mp[x*b]如果有正数有负数的话,则最大值要么是最大的两个正数相乘,要么是两个最小的负数相乘,因为数可以随便删,所以直接排序,取两端的两个数相乘的最大值。如果有偶数个字符,记录每个字符出现的个数。

2024-08-10 22:04:10 864

原创 Codeforces 883 div3 A-G

数据范围很小,所以考虑状态压缩,把每个状态用对应的十进制数表示,然后把所有状态与其能到达的状态连一条边,能到达的状态也就是吃下所有药物后的状态。假设当前状态为s,则用了第i种药物后的状态为s|b[i]&(~a[i]),|b[i]很好理解,关键是&(-a[i])这个手动模拟一下就清楚了。2、k最大幂次大于等于3来凑1e18,可以发现(1e6)^3=1e18,所以大于2我们只需要枚举2~1e6然后根据上一题的模式来写。模拟题,直接找每一行,每一列,每个对角线是否有三个元素相同,如果没有,则是平局。

2024-08-06 20:27:08 606

原创 Codeforces 881 div3 A-F1

处理所有的询问,用前缀和直接O(1)算出来当前区间1的个数,如果当前区间1的个数大于0的个数,则直接返回true;更新1~idx最小子段和:s[idx].x=min(minn[idx],s[a].x)更新1~idx最大子段和:s[idx].y=max(maxx[idx],s[a].y)//s[i]={1~i的最小子段和,1~i的最大子段和}更新1~idx最大后缀:maxx[idx]=max(b,maxx[a]+b)更新1~idx最小后缀:minn[idx]=min(b,minn[a]+b)

2024-08-06 20:26:43 274

原创 Codeforces 891 div3 A-G

然后用小根堆记录每个数,然后最小的数出队n-1次,因为一共有n-1个最小的数,第二小的数出队n-2次,...,把每个数存下来就OK了,然后记得加一个最大的数,直接加上次大的数就可以了。即a[i]*(x-a[i])=y,化简得a[i]^2-x*a[i]+y=0,即a^2-x*a+y=0。令c[i]=a[i]-b[i],即c[i]>=c[j]则表示i~j有一条边。下一个数是5,以5为一个端点的区间为[1,5],[2,5],[5,7]a[i]-b[i]>=a[j]-b[j],则i~j有一条边。

2024-08-02 23:00:25 1139

原创 Codeforces 888 div3 A-G

一个药水x可以被几种药物混合制成就建几条指向x的边,建完边后就用拓扑排序做,所有入度为0的药水的价格只能是它本身的价格,入度不为0的价格可以由其他的药水混合制成,最终的最低价格为min(直接买的价格,由其他药水混合的价格)把奇数和偶数分开排序,然后依次填充原数组奇数和偶数的地方,判断是否有前面的数大于后面的情况,如果有,则输出NO。因为a只丢了一个元素,所以原数组的1~n的排列中一定有两个数没出现,如果大于两个元素,则原数组不存在。1、a[1]==a[n],找有没有k个a[1]即可。

2024-08-02 11:21:12 345

原创 Codeforces 938 div3 A-G

删的时候会发现(d+1)/2个奇数d/2个偶数,所以对答案的贡献为d/2)这题的做法类似于滑动窗口,但是没有真的把滑动窗口写出来,而是每次直接记录滑动窗口内的每个数的个数,判断其中可以与b数组里面的数匹配的数的个数,简称有效数的个数。同理,对于1,2,3也一样,假设当前2,3的奇偶性相同,则一直删1,每删一个,就变一次奇偶性,贡献也是a/2,2和3同理,贡献为b/2和c/2。但是1,2,3的个数最开始都是奇数时,每个数贡献a/2,b/2,c/2后,最后剩下的情况就是1,1,1,0,此时的贡献也为1。

2024-07-29 22:53:53 426

原创 Codeforces 962 div3 A-F

由此可见,我们从前往后枚举每一个右端点j,找到在此之前的前缀和等于sum[j]的数,i+1就可以是区间的左端点,然后就可以用map存储每个相同前缀和对应的左端点的和。如果sum[i]==sum[j],则区间[i+1,j]的区间和为0,对答案的贡献为(i+1)*(n-j+1)如果sum[k]==sum[j],则区间[k+1,j]的区间和为0,对答案的贡献为(k+1)*(n-j+1)字符串只包含0和1,要找的区间0和1一样多,所以我们可以把0变成-1,转换成要找区间和为0的区间。二分操作的数中最小的数。

2024-07-29 22:53:34 337

原创 Codeforces 913 div3 A-G

对所有有关联的灯泡建一条有向边,显然,建完之后可能有环,对于环外的点,直接用拓扑序列做,遇到1就将该节点进入答案序列,然后给他变成0(注意关联节点的状态也要变),遇到0就不进入答案序列。所以直接用bfs依次找出每个环,存储环内的节点,记录环上的节点状态为1的个数,如果有奇数个1,则不可能关闭所有的灯,否则一定可以关闭所有的灯。做完拓扑序列后,对于环内的点,必定每个点的入度都为1,因为每个点的出度最多为1,而又要形成环,所以不可能有节点的入度大于1。直接看代码,看的时候一定要画个图模拟一下,不然有点难看懂。

2024-07-26 22:27:08 630

原创 Codeforces 903 div3 A-F

每个数是由若干个质数的乘积组成,所以可以对每个a[i]分解质因数,然后判断每个质数出现的次数是否是n的倍数,如果是,则可以让所有数相等,否则不能。可以发现,2一共有5次幂,5也一共有5次幂,都是n=5的倍数,每个数只需得到一个2一个5即可,即每个数都可以变成10。旋转90度与原来相同,可以发现,旋转的过程中,每个数都与另外三个数相关联,如图(i,j)每次找a[i]、a[j]、x,使得a[i]=a[i]/x,a[j]=a[j]*x。f[i][1]:以i为根节点到任意一个被标记的点的次大距离。

2024-07-26 22:26:48 817

原创 Codeforces 923 div3 A-G

②k

2024-07-22 20:55:42 949

原创 Codeforces 916 div3 A-F

此时可获得的最大经验值为a[1]+a[2]+...+a[i]+(k-i)*(b[1~i]中的最大值)2、maxn-match*2>sum-maxn,则最大匹配数为match+sum-maxn。所以每次不管谁操作时,挑a[i]-1+b[i]-1的最大值即可。Alice选i,答案差值增加了a[i]-1+b[i]-1。2、Bob进行操作,则对答案的贡献为-(b[i]-1)Bob选i,答案差值减少了a[i]-1+b[i]-1。二者的差值为(a[i]-1)+(b[i]-1)

2024-07-22 20:55:17 562

原创 2022RoboCom世界机器人开发者大赛-本科组(初赛)

如果让所有颜色不同的点之间都有边也不会影响该二分图,所以一共有x*y种情况,但由于树中一开始就有n-1条边,所以二者之差就是答案,即x*y-(n-1)判断一个图是否是二分图可以用染色法:一共有两种颜色,每个点和它的相邻节点颜色不相同,看是否可以染色成功,如果可以,则是二分图,否则不是。给定一颗n个点n-1条边的树,问选择本没有边相连的两个点,使得将这两个点相连能够构成二分图,一共有多少种选择方案。枚举每两个点,如果这两个点之间没有边,则尝试往这两条边之间连一条边,如果连边之后是一个二分图的话,答案就加一。

2024-07-07 11:44:31 403

原创 2021RoboCom世界机器人开发者大赛-本科组(初赛)

换句话说,就是将所有不是防控地区的机场看成若干个连通块,然后判断起点和终点是否连通,如果连通,则可以出行,否则不能。根据题意,是按照到原点的距离进行排序,然后枚举每个点。对于每个防控地区,都标记一下,然后dfs搜索从起点到终点是否有不经过防控地区的路线,如果有,则可以出行,如果没有,则不能出行。2、对于每个点所能到的最远的地方对应的路径,找出这些路径的最小值,该最小值所对应的起点就是空降位置。所以,我们可以离线处理,即先存储所有的询问,然后逆序处理每一天的询问,每次将一个机场加入到连通块中。

2024-07-07 11:43:49 722

原创 矩阵乘法求Fibonacci数列

废话不多说,直接上笔记。

2024-06-10 20:05:15 257

原创 选课清单--数据结构课程设计(十字链表+哈希表实现)

代码写的有冗余,结构体应该有三个,一个学生,一个课程,一个十字链表的结构体,如果公用十字链表的结构体,学生和课程会有很多指针用不上,但是我懒,不想改了,将就着看吧......,被老师要求选这个题目做,不知道还有没有别的学校是这种题目,都可以相互借鉴hh)

2024-06-10 20:04:37 215

原创 蓝桥杯2022国赛B组--出差 C++

题目如上,这题与一般的最短路径题目的不同点在于,这里不只是两个点的连线有距离,在每个点也有距离(题中的隔离时间),所以在存图的时候,修改某些地方就行。假设t[N]数组存储在每个城市隔离的时间,g[N][N]存储图。

2024-05-15 20:48:20 314 1

原创 蓝桥杯2022国赛B组--卡牌 C++

二分

2024-05-15 20:37:34 200 1

原创 Codeforces Round #797(div3)

3、i=1,j=n,双指针判断两个数能否结合成一组,如果a[i]+a[j]>=n,则表示可以结合,此时i++,j--,sum++(sum只加一因为a[i]+a[j]一定小于2*n),如果不能结合,j就往前移(不把i往后移是因为a[i+1]+a[j]<=a[i]+a[j],即更不可能结合),直到i和j相遇。1、设置一个数组cnt[],cnt[i]记录s[i]及其之前所出现的’W'的个数,cnt[i]=cnt[i-1]+(s[i]=='W')题意:求出每个任务运行的时间,详见代码。

2024-05-11 23:03:14 284 1

原创 Codeforces Round #515(div3)

2、从后往前用i枚举a的每一位,每次遇到‘1’(假设编号为i)就找该编号前面b中出现的1的个数,出现几个1就给ans加上几个当前位在a中的二进制权值,即2^(n-i-1)1、设置一个长度为书架两倍的数组,2*N,从中间开始放书,hh=N,tt=N+1,放书时hh往左减,tt往右加,数组a[N]记录每本书放在书架上的位置。2、遍历区间,对所有区间左端点小于等于last+1的的区间,找出它们中右端点最大的一个,选择右端点最大的一个区间,更新last为这个最大的右端点。=n,输出-1,否则输出区间的个数ans。

2024-05-11 23:02:10 423 1

原创 Codeforces Round #501 div3(C++)

题意:给定两个字符串s和t,问s能不能只通过相邻两个字母之间的交换变成t,如果可以,给出交换的序列ans[],ans[i]表示交换s[ans[i]]和s[ans[i]+1],所以只需要从前往后枚举字符串t,找出t[i]在s中出现的下标j,然后把s[j]从后往前移到下标为i的位置,同时更新序列ans。题意:给出一个图,只有'.'和'*'两个符号,求这些‘*’包含的星星个数,如果包含的星星可以全部覆盖所有的‘*’,则输出星星的个数及它们的信息,否则输出-1,详情见代码,有很详细的注释。C++代码如下(纯暴力)

2024-05-07 20:26:00 346

原创 Codeforces Round #498 (div3) C++

题意:将一个数组分成三块(可能有某块为空),能使左右两块相等的最大的相等值,每一块的值等于里面所有数的和,维护前缀和s[]和后缀和last[],用双指针寻找左右两块相等的最大值输出即可。题意:将数组分成k部分,要求每部分的最大值加起来最大,把每个数及其下标放在结构体中,对结构体按数进行从大到小排序,找出前k大的数,把他们的下标进行排序,按照下标找区间长度。题意:对于每对数(1和2,3和4,...),替换之后留下的都是小的那个数,而小数都是奇数,所以从前往后处理,遇到偶数减一,奇数不变。

2024-05-04 21:25:57 271

原创 第八届蓝桥杯--K倍区间

那么,在枚举到某个数s[j]时,我们怎么知道它前面出现的所有的i的个数,使得s[i]%k==s[j]%k呢,我们可以用一个数组存储,每次枚举,使cnt[s[i]%k]++;若s[i]%k==s[j]%k(i<j),则(s[j]-s[i])%k==0,所以a[i+1]~a[j]就是一个k倍区间。所以,这一题我们可以用前缀和,结合这个数学知识解决。首先,科普一个数学知识。假设数列的前缀和用s存储。

2024-04-16 20:49:09 296

原创 第九届蓝桥杯--递增三元组C++(二分)

对数组a和c进行排序,枚举数组b,对于b[i],求数组a中小于b[i]的最大下标,求数组c中大于b[i]的最大下标即可。

2024-04-16 20:48:42 150

原创 第八届蓝桥杯--包子凑数C++

选第i件物品:max(f[i-1][j-a[i]],f[i-1][j-2*a[i]],...,f[i-1][j-s*a[i]])(用max是因为只要有一个是1,就表示有这样的选法)题目给定的ai值小于等于100,又因为100以内最大的互质的两个数是99和100,所以100以内的所有数的最大的不能表示出来的数不超过99*100=9900,我们可以把10000设为上界。对于多个数,同样有这个定理,如果这多个数的公约数是1的话,则存在最大的不能表示出来的数,否则不存在。不存在最大的不能表示出来的数,输出INF。

2024-04-10 21:35:06 352

原创 第七届蓝桥杯--密码脱落C++(动态规划)

对于以上1,2两点,比较好理解,左(右)端点固定,即在最右(左)边加上s[l](s[r]),所以要加1。可以用简单的例子试一下,如下图所示,abc可以变成如下回文字符串,最少要加两个字符。对于每个小区间s[l~r],我们考虑左右端点s[l]和s[r]题目的意思是:给定一个字符串,至少加上几个字母才可以把它变成一个回文串。集合:区间i~j变成回文串的所有方案。这是一道区间DP问题,下面用闫氏DP法进行分析。属性:Min(最少加的字母数)最后输出,只需输出f[1][n]即可。第3点,为什么加2呢?

2024-04-10 21:19:44 159 2

原创 第六届蓝桥杯 生命之树C++(树形DP)

这道题看似每条边都是有向边,但是题目有一句话至关重要,对于非空点集S,当中的相邻两个点之间有一条边,但并未说明方向是什么,所以我们可以把所有的边看成是无向边,故点集S中每两个点都是相通的,这样题目就很好分析了。这里用max(0,f[ki])是因为我们要计算f[u]的最大值,如果加上它的相邻节点更小,那这个相邻节点一定不会选。假设u的相邻节点为k1,k2,k3,...,kn(除去u的父节点)最后输出的时候,我们遍历一下每个节点的f[i],找出最大的那一个就可以啦。集合:以u为根的子树的所有选择。

2024-04-03 23:36:13 436 1

原创 天梯赛 L2-038 病毒溯源C++

我们可以用一个vector<int> a[]来存储每个节点变异可到达的节点,即用该数组存储每条边,找到最长变异链并不难,只需要dfs一直往下暴搜就可以,关键是找最小序列需要绕个弯子。根据题目对最小序列的定义,显然,0 4 9 1 是这道题的答案。详情见代码,有详细注释!

2024-04-03 23:10:18 377

原创 第13届蓝桥杯--统计子矩阵C++

因为在i,j固定的时候,我们枚举的是end,每一次end都会往下走,而start会保持在当前的位置,如果下一行满足的话,在循环中的后面就会把从该子矩阵第二行的只占一行的子矩阵算在内了,如果我们现在就算的话,就会重复计算了。题目如上,很明显,这题需要用到二维前缀和,由于子矩阵的大小未知,所以如果用暴力枚举四个边界(上下左右),时间复杂度就为O(n^4),一定会超时,所以要想一个方法降低时间复杂度,这题我们可以用双指针。直到子矩阵的和小于等于k,start不再前进了,此时的宽度为j-i+1的子矩阵个数为。

2024-03-20 20:39:57 267 7

原创 第13届蓝桥杯--李白打酒加强版C++(动态规划DP)

最后输出的时候,只要输出f[n][m-1][1]就行,因为题目要求最后一次遇到的是花,且酒刚好被喝完了,所以最后一步之前剩下的酒为一斗。(上一步是店,酒的数量增加了一倍,所以上一步的酒是这一步的一半)表示经过了i次店,j次花,手中还有k斗酒的所有方案。(上一步是花,喝掉了一斗,所以上一步的酒多一斗)题目如上,可以用动态规划写。,因为初始状态就是一种方案。在最初的时候,要初始化。

2024-03-18 22:51:23 509 1

原创 C++集合set遍历方式

每次插入一个数到set中时,先判断一下是否已经在set中,如果是,则不插入,这样做的目的是为了让数组中没有重复元素。以上三个是我目前能写出来的了,主要是还没深入了解C++,之后学到了更多都会更新出来的。缺点:如果想要输出有序序列,就得先给数组排序,不方便。缺点:有些编译器版本低,不能用。缺点:遍历完之后集合也不存在了。

2024-03-17 13:53:49 1911 2

原创 第4届蓝桥杯--大臣的旅费C++

在找到最远路径ans之后,路程的花费就是ans*10+(1+2+...+ans)=ans*10+ans*(1+ans)/2;由于答案可能会很大,就输出ans*10+(long long)ans*(ans+1)/2即可。搜的时候,以任意一个点为起点都行,我这里写的dfs(1),从一号点开始搜。首先,要存储图,由于该图是稀疏图,所以用邻接表存储图。

2024-03-15 23:31:04 336 1

原创 PTA L2-023 图着色问题C++

首先,用邻接矩阵把图存储下来,然后对于每一种方案,判断合不合理,写一个函数进行判断,如果有相邻点是相同的颜色,则不合理,颜色不是k种也不合理。每一种方案,我们可以用stl库中的集合set存储,因为set自带去重功能,se.size()可以记录一共用了几种颜色。由题意可知,要求用k种颜色将图的每个顶点染色,相邻点不能有相同的颜色。set包含在头文件 #include 中。

2024-03-15 19:45:53 781 2

原创 C++字符串string常用函数

首先是最常用的输入函数,cin>>s和getline(cint,s),前者不能读入空格,后者可以。截取a中从下标为i的字符开始,长度为k的子串;判断字符串中某个字符是否为数字或字母,如果是就返回true,否则返回false。在字符串s中找一个子串,若找到了,返回要寻找的字符串第一个字母在s中的下标。判断字符串中某个字符是否为数字,如果是就返回true,否则返回false。截取a中从下标为i的字符开始,长度为k的子串。1、s.length()和s.size()都是字符串s的长度,用法如下。

2024-03-14 21:03:15 403

原创 PTA L2-013 红色警报C++

个人认为题目没有说清楚,我之前以为是每一个被攻占的城市单独处理,不影响后面的被攻占的城市,后来发现理解错了。如果当前城市在其他连通块里面,有两种情况,cnt1=cnt+1或者cnt1>cnt+1,若cnt1=cnt+1,则去掉该城市其他城市还是联通的,若cnt1>cnt+1,则其他城市不连通了。题目如上,我们可以用邻接矩阵g[][]存储图,如果城市i和城市j有通路的话,令g[i][j]=1。所以,操作之后,若cnt1>cnt+1,则为情况2,否则为情况1。首先,记录当前连通块的数量cnt。

2024-03-14 20:32:27 481

原创 第14届蓝桥杯---子串简写C++

对答案的贡献,由于字符串长度大于等于k,所以只需要知道从i-k+1及其之前c1的个数sum[i-k+1],那么sum数组该如何更新呢?枚举到每一个c2时,ans+=sum[max(0,i-k+1)],这里用max(0,i-k+1)是为了防止数组下标越界。题目如上,要求以c1开头,c2结尾的长度>=k的所有子串的个数,很明显暴力会超时(O(n^2))枚举到每一个位置时,更新 sum[i]=sum[i-1]+(s[i]==c1);从前往后枚举,枚举到每一个c2(假设下标为i)时,求出。此时题目就分析完成了!

2024-03-13 23:17:32 637 1

原创 PTA -- L3-001凑零钱 C++

因为我们要输出最小序列,从小到大排序后做动态规划,我们从前往后枚举时,如果当前数可选(假设当前枚举到了第i个数,即j>=a[i]且f[i+1][j-a[i]]不为0,如果f[i+1][j-a[i]]为0,则表示从第i+1个硬币到不了第i个硬币),则必选(输出a[i]),否则必不选。f数组用之前要初始化,由于i是倒序枚举的,所以在状态表示中我们要用到i+1,所以对于所有的i从1~n+1,f[i][0](从第i个及i之后的硬币中选,总数刚好为0元,就只有一种情况,就是一个硬币都不选)所以都要初始化为1。

2023-11-28 21:12:40 282 1

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除