
算法
CCSU_Cola
ACMer
展开
-
B. Take Your Places!(思维)
题目链接题意:给出一个序列,序列中相邻的数可以交换位置,问最少交换多少次使得奇偶性质相同的数不相邻。思路:因为如果交换过后的数组的如果为奇数开头,那么所有的奇数都在奇数位,而如果以偶数开头,那么所有的偶数都在奇数位,而且如果奇数位置摆放好了,那么偶数也摆放好了。所以只需要分别求出奇偶开头的花费数即可。代码:#include<bits/stdc++.h>using namespace std;#define ll long longint t,n,x;int main()原创 2021-09-26 15:49:23 · 257 阅读 · 0 评论 -
D. The Strongest Build(bfs+优先队列)
题目链接题意:有n个数组,需要在每个数组中选取一个下标,然后将这些选取的下标的数求和,但是有m个下标序列是被禁止的,在不与这些序列相同的前提下,输出一个求和后数字最大的下标序列。思路:用map嵌套vector对下标序列进行标记,然后用bfs进行广搜,每次改变最大序列的一个下标,然后压到优先队列中,以数的总和作为优先队列的第一值,然后每次结束后拿出的vector如果在map中没有出现过,则该序列的答案一定是最大值。代码:#include<bits/stdc++.h>using原创 2021-09-24 22:43:47 · 236 阅读 · 0 评论 -
P2597 [ZJOI2012]灾难(topsort+LCA)
题目链接题意:给一张图代表食物链,图中没有环,,如果x捕食y,那么有一条有向边,由x指向y,如果某个物种的捕食对象全灭绝了,那么该物种就会灭绝,定义了一个名词“灾难值”,每个物种的灾难值为它灭绝后,会导致多少物种灭绝。输出所有1-n物种的灾难值。思路:如果一个物种有多个捕食对象,那么该物种的所有捕食对象都灭绝了才会使得该物种灭绝,可以知道一个物种捕食对象都灭绝的条件为它所有捕食对象的最近公共祖先灭绝以及能够使得最近公共祖先灭绝的其他物种灭绝,于是可以根据这个条件重新建图,即为将一个物种挂到它所有捕食原创 2021-09-20 11:02:58 · 187 阅读 · 0 评论 -
AtCoder Beginner Contest 218 F Blocked Roads(并查集+搜索)
题意:给出n个点和m条边,1-m条边会依次不可通过,求出每个边不可通过时,1-n的路径最小值。思路:如果依次求最短路,时间复杂度为m*m*logn,显然是不可以的,于是我想到可以将不受限制时的最短路求出来,那么该路径最长为n个边组成,也就是n-1条边,我们可以将这些边标记起来,然后如果删除的边不是其中的,则直接输出不受限制的答案,否则在某条变不能通过的情况下重新跑一次bfs,时间复杂度为n*m。因为最短路一定在最小生成树中,于是我采用了先生成最小生成树,再标点最短路的方法。代码:#includ原创 2021-09-12 15:37:41 · 279 阅读 · 0 评论 -
P3761 [TJOI2017]城市
题目链接从加里敦大学城市规划专业毕业的小明来到了一个地区城市规划局工作。这个地区一共有n座城市,n-1条高速公路,保证了任意两运城市之间都可以通过高速公路相互可达,但是通过一条高速公路需要收取一定的交通费用。小明对这个地区深入研究后,觉得这个地区的交通费用太贵。小明想彻底改造这个地区,但是由于上司给他的资源有限,因而小明现在只能对一条高速公路进行改造,改造的方式就是去掉一条高速公路,并且重新修建一条一样的高速公路(即交通费用一样),使得这个地区的两个城市之间的最大交通费用最小(即使得交通费用最...原创 2021-09-08 18:21:17 · 162 阅读 · 0 评论 -
牛客小白月赛37 I 加减
题目链接思路:枚举l,二分一个r,判断区间内全等于一个值是否满足修改次数小于等于k,因为区间是排序过的,所以只需拿出中位数,然后判断其他数到修改为中位数需要的修改次数是否小于等于k。代码:#include<bits/stdc++.h>using namespace std;#define ll long longll a[100010];ll sum[100010];ll check(int l,int r){ int mid=(l+r)>>1;原创 2021-09-03 12:53:18 · 767 阅读 · 0 评论 -
E. Carrots for Rabbits(贪心+优先队列)
题目链接题意:给定n个物品,每个物品有一个体积,可以将一个物品拆开成很多份,最后需要一共k份,答案为每个物品的体积的平方总和,输出答案的最小值。思路:我的思路本来为将最大的物体从优先队列里拿出来,然后拆成均等的两份,然后再放回优先队列,交一发wa了,然后发现物品有时候直接拆成三份或更多份会更优,比如10拆成三份为3,3,4,但是如果按照我的方法为2,3,5。看题解发现大佬的做法是先算出不拆的答案,然后将之前不拆的答案和每个物品拆成两份的答案做差,然后每次拿出最大的减去,然后再计算拆多一份的答案压入队原创 2021-09-01 21:22:27 · 227 阅读 · 0 评论 -
UVA - 1423 Guess(拓扑排序)
题目链接思路:根据sum[j]-sum[i]>0,可以知道j的值比i高,也就是可以连一条j到i的有向边,sum[j]-sum[i]<0,则反过来建边,由此跑拓扑序,排在前面的值一定大于或等于后面的,可以按照入队的顺序给值。代码:#include<bits/stdc++.h>using namespace std;#define ll long longstruct tt{ int x,to;};tt e[20010];int t,n;char p[原创 2021-08-17 09:12:16 · 153 阅读 · 0 评论 -
E - Good Triple(思维求贡献)
题目链接题意:给一个只包含0和1的字符串S,问在字符串中有多少个区间[L,R]包含S[l]==s[l+k]==s[l+2*k],且L<=l,l+2*k<=R。思路:因为只包含0和1两种字符,可以知道不构成题目条件的串的长度不会大于9,也就是说只需要暴力求解即可,枚举以L为起点,得到满足条件的最小R。答案加上strlen(s)-R+1即可。#include<bits/stdc++.h>using namespace std;#define ll long longc原创 2021-08-15 12:56:45 · 177 阅读 · 0 评论 -
B - Two chandeliers(扩展中国剩余定理+二分)
题意:有两个灯泡,灯泡都为变色灯,分别有n和m种颜色,每个颜色用ai和bi表示(ai互不相同,bi互不相同),灯每天按照序列顺序更换一次颜色,问多少天之后一共出现过k天两个灯的颜色互不相同。思路:先将每个颜色出现在ai和bi中出现的位置存起来,然后根据扩展中国剩余定理,求相同的颜色第一次相同的位置pos%n==x&&pos%m==y,x和y分别表示该颜色在ai和bi中出现的位置,然后每个颜色下次相同的位置即为pos+lcm(n,m),通过这个可以求出某个位置之前该颜色出现的次数,二分答案原创 2021-08-13 15:23:49 · 139 阅读 · 0 评论 -
AcWing 3800. 奇数还是偶数(思维)
题目链接给定一个整数nn,它可以被表示为一个k位的b进制数,如下所示:n=a1⋅(b^k−1)+a2⋅(b^k−2)+…+ak−1⋅b+ak举例说明,如果b=17,k=3,a=[11,15,7],那么n=11⋅17^2+15⋅17+7=3179+255+7=3441。思路:1.如果b是偶数,那么a[1]到a[k-1]都是乘以偶数,答案都为偶数,所以只受最后一个a[k]的奇偶数的影响。2.如果b是奇数,那么a[1]到a[k-1]都是乘以奇数,答案不会收到b的影响,仍为a[...原创 2021-08-11 20:21:57 · 94 阅读 · 0 评论 -
1073. 树的中心(树形dp)
题目链接给定一棵树,树中包含nn个结点(编号1~n)和n−1 条无向边,每条边都有一个权值。请你在树中找到一个点,使得该点到树中其他结点的最远距离最近。思路:既然要找到一个点距离最远的点的距离最近,那么如果以任意点为根节点去dfs,那么某个点距离最远的点一定会被其下面最远的点更新,这个可以通过树形dp直接能到达的最深的深度即可,但是它同时也会被其父节点能到达的最远距离更新,于是我们每个点需要维护一个最大值和次小值和该点的最大值是哪个儿子节点更新的,然后再跑一次dfs,即可得到某个节点的父亲...原创 2021-08-11 13:20:01 · 145 阅读 · 0 评论 -
P5536 【XR-3】核心城市(树的直径)
题目链接X 国有n座城市,n − 1 条长度为1的道路,每条道路连接两座城市,且任意两座城市都能通过若干条道路相互到达,显然,城市和道路形成了一棵树。X 国国王决定将k座城市钦定为 X 国的核心城市,这k座城市需满足以下两个条件:这k座城市可以通过道路,在不经过其他城市的情况下两两相互到达。 定义某个非核心城市与这k座核心城市的距离为,这座城市与k座核心城市的距离的最小值。那么所有非核心城市中,与核心城市的距离最大的城市,其与核心城市的距离最小。你需要求出这个最小值...原创 2021-08-10 23:35:33 · 207 阅读 · 0 评论 -
P1395 会议(树的重心)
题目链接有一个村庄居住着n个村民,有n-1 条路径使得这n个村民的家联通,每条路径的长度都为1。现在村长希望在某个村民家中召开一场会议,村长希望所有村民到会议地点的距离之和最小,那么村长应该要把会议地点设置在哪个村民的家中,并且这个距离总和最小是多少?若有多个节点都满足条件,则选择节点编号最小的那个点。题意:找到树的重心,然后求所有点到树的重心的距离和。思路:树形dp根据重心的性质找到重心,然后再跑dfs求距离和。#include<bits/stdc++.h>us...原创 2021-08-09 10:06:31 · 356 阅读 · 0 评论 -
3789. 隐藏字符串(dp)
题目链接题意:给定一个由小写字母构成的字符串s。我们称字符串t隐藏于字符串s中,如果它满足:存在一个字符串ss的子序列,与其一一对应。 该子序列的各个元素的下标可以构成一个等差序列。例如,字符串aab就隐藏于字符串aaabb中,因为aaabb的第1,3,5 个元素刚好可以构成aab,而这恰好是一个公差为2的等差数列。字符串tt可能隐藏于字符串s中多次,这取决于共有多少个s的不同子序列满足与字符串t一一对应,且各个元素下标可以构成一个等...原创 2021-08-01 00:00:18 · 308 阅读 · 0 评论 -
3583. 整数分组 (双指针+dp)
链接题意:给定n个整数a1,a2,…,an。现在,请你从中挑选一些数,并将选出的数进行分组。要求:选出的数最多划分为k组(至少1组)。 同一组内,任意两数之差的绝对值不超过5。 所选出的数尽可能多。请问,最多可以选出多少个数进行分组?代码:#include<bits/stdc++.h>using namespace std;int w[5010];int f[5010][5010];int main(){ int n,m; ...原创 2021-07-27 10:28:32 · 122 阅读 · 0 评论 -
永不言弃 (topsort+优先队列)
题目链接题意:小沙最喜欢打怪升级了,今天他玩了一个游戏,需要从初始关卡开始,击败n个关卡才能通关整个游戏,对于每个关卡都会有两种通过方式。小沙初始的属性值为s,当游戏角色的属性大于关卡最高上限时,可以强行通过该关卡,又或者拥有通过该关卡的必过道具(并不是消耗品)。每个关卡通过后可能会开启一个或多个后置关卡,但每个关卡开启也需要若干个前置关卡,只有前置关卡全部通过后,才能开启该关卡。特别注意,除了一号关卡,如果一个关卡没有任何前置关卡,那么这个关卡则永远无法开启。每个关卡仅能游玩一次,且每个关原创 2021-07-18 13:19:06 · 159 阅读 · 1 评论 -
小G的LY数对 (手写hash表)
题目链接题意:小G定义LY数对为两个数x,y在二进制的异或操作后恰好有两位是1小G现在有两个数组a,b长度分别为n,m现在小G想知道有多少对i,j满足(1<=i<=n,1<=j<=m)满足a[i]和b[j]是LY数对思路:既然需要有两位不一样,那么改变a的一位如果与改变了一位的b相同,说明它们为其中一对,但是如果a与b直接相等我们不能计入答案,所以需要删除出来。代码:#include<bits/stdc++.h>using namespace原创 2021-07-15 15:28:01 · 136 阅读 · 0 评论 -
3760. 最大剩余油量 (树形dp)
题目链接题意:一个国家由nn个城市组成,这n个城市由n−1 条双向道路连接,呈一个树形结构。每个城市都设有加油站,在第ii个城市可以购买wi 升汽油。汽车在道路上行驶,毫无疑问也会消耗汽油,每条道路的具体耗油量也会给出。现在,需要制定一条汽车的行进路线,从任意城市s出发,经过一条简单路径,到达任意城市e结束。注意,行进路线也可以只包含一个城市(也就是哪都没去)。汽车初始时油箱是空的,但是可以在路线中经过的每个城市购买汽油,包括开始城市和最终城市。如果在...原创 2021-07-13 18:43:27 · 124 阅读 · 0 评论 -
B 计算几何(数位dp)
问题链接由于小L追女孩子的时间不多了,于是这里只有简单版题意。共有T组询问,每次给定l,r,你需要求出在[l,r] 中有多少个数在二进制下1的个数有奇数个。例如4=(100)2,在二进制下有1个1,那么如果l=r=4,答案为1。例如5=(101)2,在二进制下有2 个 1,那么如果l=r=5 ,答案为0。思路:将每个数用二进制分解,然后数位dp得到0到L-1的奇数个1的数的个数,以及0到R的奇数个1的数的个数。做减法输出即可。代码:...原创 2021-07-08 12:25:28 · 99 阅读 · 0 评论 -
D 作弊(哈夫曼树)
题意:采用摇头和点头表示字母,使得多个字母同时表示时不会产生错误,问某个串在这个前提下表示出来需要的最少动作。思路:由于每个字母需要能够识别,可以构造一棵树,每个变代表点头或者摇头,然后每个字母为叶子节点,这样就可以使得每个数都不同,然后采用哈夫曼树的建树方法,出现次数少的字母离根节点远一些一定是最优的。代码:#include<bits/stdc++.h>using namespace std;#define ll long longstring str;priority_原创 2021-07-07 12:35:29 · 97 阅读 · 0 评论 -
数学家的迷题(bitset+线段树)
题意:给一个序列,共有两个操作。1.可以修改某个位置的值为x。2.给一个区间l,r,T=a[l]×a[l+1]×...×a[r−1]×a[r],问T有多少个质因子。思路:多个数相乘的答案的质因子个数为每个数字的质因子存入集合去重后的个数。因为需要对每个数的质因子进行去重和存储,可以用bitset存储质因子,然后做与运算即可,但是由于空间限制,我们应先将小于1e5的质因子求出来,然后直接处理,由于求出来后直接for循环分解也会超时,需要优化成直接找到最小质因子的方式,然后建立线段树进行单点修改和区原创 2021-07-07 09:33:50 · 183 阅读 · 0 评论 -
寻找字符串的最小表示法
时间复杂度为O(n),只需要用两个指针遍历一次字符即可找到。(最小表示法即为将字符串首位相接,然后每个点都可作为头,找字典序最小的那个)#include<bits/stdc++.h>using namespace std;const int maxn=2000010;string str1,str2;int n;int find(string str){ int i=0,j=1; while(i<=n&&j<=n){ i原创 2021-07-07 09:19:36 · 242 阅读 · 0 评论 -
C 哲学家的沉思 (倍增)
题目链接题意:给一个序列ai,q次询问,每次给出一个l和r,问区间l,r最少分成几段能够使得a[Li]是Li到Ri之间的最大值。思路:维护一个当前点能够到达的最远距离+1,然后倍增维护一下,查询时只需要倍增求出最小值即可。代码:#include<bits/stdc++.h>using namespace std;#define ll long longint a[100100];int f[100100][25];int main(){ int n,qq;原创 2021-07-06 15:12:48 · 155 阅读 · 0 评论 -
牛客练习赛85 B 音乐家的曲调(尺取法)
题目链接题意:在字符串中寻找三个字串,使得它们三个串的长度最大,每个串需要满足同一字符出现的次数不大于m次。思路:简单尺取法选取的是单一长度最大,且同一字符出现次数不大于m次。由于需要选取三段,我们可以先预处理一个前缀满足条件的最大长度以及后缀满足条件的最大的长度,然后最后再跑一次整个串,取一个max(L[l-1]+R[r+1]+(r-l+1)即可。代码:#include <bits/stdc++.h>using namespace std;#define ll long原创 2021-07-06 09:41:22 · 128 阅读 · 0 评论 -
牛客IOI周赛27-普及组 D 旅游(简单floyd)
题目链接题意:从s点开始游玩,由于疫情,游玩的景点必须经过消毒,且经过的路径的每个点都必须经过消毒。可以游玩则输出最短花费,否则输出-1。思路:由于经过的点必须经过消毒,即可以考虑只对消毒过的点进行放缩,用以维护最短路,然后判断终点是否消毒和能否到达即可。代码:#include<bits/stdc++.h>using namespace std;#define ll long longll dp[310][310];int n;void floyd(int x){原创 2021-07-05 12:07:52 · 171 阅读 · 0 评论 -
长沙学院2022蓝桥杯选拔赛第一场
A.楼下是签到题题解链接B.新物种思路:需要考虑三种情况,第一种为本身要走的长度小于2H,那么要走的路程为2H,第二种情况为本身要走的距离大于2H且模H不为0,那么需要走实际距离/H+1个H,第三种情况为本身要走的距离模H为0,直接输出1,因为两个距离相等。代码:#include<bits/stdc++.h>using namespace std;int main(){ int t; scanf("%d",&t); while(t--)原创 2021-06-27 10:42:32 · 568 阅读 · 1 评论 -
长沙学院第一届“360湖南网安基地杯”程序设计竞赛
A.时间间隔思路:直接算出两个日期为当年第几天,然后输出答案两个日期相减的绝对值即可。#include<iostream>#include<algorithm>#include<cstring>using namespace std;typedef long long ll;#define N 1010int n;int a[2],b[2];int date1[12] = {31,28,31,30,31,30,31,31,30,31,30,3原创 2021-05-29 18:03:37 · 587 阅读 · 2 评论 -
AcWing 356 次小生成树(LCA+并查集)
链接: [AcWing 356. 次小生成树 - AcWing]()思路: 先并查集建图,构造最小生成树,次小生成树即为在最小生成树上加一条边构成一个环,然后去掉原图中最大的边即可,但此处最小生成树为严格次小,所以除了两个点之间的最大边权,还需维护一个次大边权,否则替换的边权可能和最大边权相等。可以在bfs处理LCA的过程中维护出来,然后后续加边时,查找两点之间的最大和次大边权,判断是否能够替换即可。#include<bits/stdc++.h>using namespace std;#原创 2021-05-11 17:36:21 · 164 阅读 · 2 评论 -
AcWing 164. 可达性统计(拓扑排序+bitset优化)
AcWing 164. 可达性统计链接: https://www.acwing.com/problem/content/166/思路: 先拓扑排序得到图的拓扑序列,然后从拓扑序最后的开始更新,需要使用bitset更新可达点,因为需要除去重复的点,然后直接使用bitset的内置函数count一下1的数量即可。#include <bits/stdc++.h>using namespace std;int d[30010];int n,m;vector<int>ve;vec原创 2021-05-10 22:44:06 · 139 阅读 · 1 评论 -
2021.5.9 第十二届蓝桥杯大赛软件赛省赛第二场大学B组(个人题解)
试题A:求余直接输出答案即可答案:1#include <bits/stdc++.h>using namespace std;int main(){ int a=2021; printf("%d\n",a%20); return 0;}试题B:双阶乘思路: 因为只需后面五位,为了防止超过数据范围,可以直接每次乘完之后都对100000取模,因为超过五位的数字对答案无影响,可以直接舍去。答案: 59375#include<bits/stdc++.h&原创 2021-05-10 00:07:30 · 1317 阅读 · 13 评论 -
AtCoder Beginner Contest 185 F - Range Xor Query(线段树或树状数组)
链接: https://atcoder.jp/contests/abc185/tasks/abc185_f题意: 给你n和m,n表示数组长度,m表示操作数量,然后给出数组,再给出m行操作,每行输入t,x,y。若t为1,则需将Ai的值改为Ai^y。t为2,则输出[l,r][l,r][l,r]区间的异或值。思路:该题需要单点修改和区间查询,很明显可以使用线段树进行操作,我首先用的是线段树,但是后面看其他大佬的题解有更为简单的方式,也就是树状数组,因为树状数组可以进行单点修改,且异或值可以通过树状数组维护为一原创 2021-05-07 08:47:31 · 308 阅读 · 0 评论 -
AtCoder Beginner Contest 184 F - Programming Contest(双向dfs)
链接: https://atcoder.jp/contests/abc184/tasks/abc184_f题意:给出n个数字和一个数字m,问在n个数字中取任意个数相加能得到的最大的不超过m的数的大小。思路:n只有40,但是如果暴搜的话时间复杂度会是2的40次方,一定会超时,但是如果成两部分,处理出两部分的所有取值,然后枚举前部分的值,在后半部分二分查找最大的满足与前部分值相加小于m的值,然后取每次最大的输出即可,具体看代码。#include<bits/stdc++.h>using nam原创 2021-05-05 14:12:38 · 246 阅读 · 0 评论 -
(牛客2021)第一届河北工业大学程序设计竞赛(部分题解)
A.WELCOME!直接输出#include<bits/stdc++.h>using namespace std;int main(){ printf("Welcome to The First Programming Competition of Hebei University of technology!"); return 0;}B.POOLING题意: 给出n * m大小的图,求出该图中每个大小为k * k的子图中的最大的数是多少。思路: 因为n和m很原创 2021-05-03 22:25:34 · 1419 阅读 · 10 评论 -
2021年度训练联盟热身训练赛第七场 K题预处理加二分
题意: 给出n个序列,长度都为m,且顺序是按照字典序排序的,需要你选取一个区间来截取每个字符串,该区间需要满足截取下来的字符串按照字典序重排后的顺序和原字符串的顺序相同。思路: 既然截取下来的字符串按照字典序重排后的顺序需要和原字符串顺序相同,那么我截取的字符串必须是原来排在上面的字符串比下面的字符串字典序更小,所以我们可以采取枚举区间的左端点L再查找该区间的右端点R即可,找到距离L最近的一点且该位置上当前串的字符小于它的下一个串的字符定为R1,然后根据相同思路枚举1~n-1的串求出R2,R3…R(n-1原创 2021-05-03 15:58:42 · 203 阅读 · 0 评论 -
牛客小白月赛32 有始有终(双端队列)
有始有终题意: 求从一个格子(Sx,Sy)到另一个格子(Px,Py)的最小花费。条件1:一个点向相邻的点移动,若与相邻点的高度差不大于D,则无需使用技能便可以移动。条件2:若两个相邻点之间的高度差大于D,则需要发动技能将一点变为电梯才可移动,且为电梯的格和其相邻的所有格都可以忽略高度差限制。思路: 从花费只有0和1可以知道,可以使用双端队列解决此题,因为队列具有二段的性质,先出队列的元素的花费一定小于等于后面出队的元素,因为为电梯的格子移动到其他格子也可以忽略高度差,所以需要将存入队列的元素标记一下原创 2021-04-28 15:40:00 · 193 阅读 · 0 评论