
算法题解
算法
我不会c语言
这个作者很懒,什么都没留下…
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
Codeforces Round #703 (Div. 2) D. Max Median
题意:给一个长度为n的序列,对于一个区间长度不小于k的子区间,中位数为这个区间排序后的第(k+1)/2个数字。现在求所有的长度不小于k的子区间,中位数的最大值是多少。思路:首先要想到,对于一个中位数,在这题中,对于偶数长度,取的中位数是靠左边的那个,那么大于等于中位数的就有一半以上。所以大于等于中位数的个数要比小于中位数的个数多。利用这点,那么其实我们可以在On复杂度判断出来一个数字是不是 ≤中位数。可以判断一个数是不是≤中位数?那么我们是不是可以去二分?其实这是有单调性的。判断一个数字是不是原创 2021-02-19 02:44:45 · 1362 阅读 · 4 评论 -
Codeforces Round #702 (Div. 3) G. Old Floppy Drive
题意:给了n个数字,成一个环,最开始在第一个数字的位置上,每次移动就是向下移动一格。m次询问,每次询问给出一个x,求最少要移动多少次,经过的数值之和≥x?思路:询问次数,显然,每次询问需要一个log的做法。我们维护一个前缀和sum,维护一个前缀和的最大值ma.对于x,如果小于等于ma[n],也就是不用完整移动一轮就能找到答案,容易知道ma是单调不降的,可以二分快速找到。对于剩下的,就说明ma[n]<x,那么我们要看每经过一轮大小会不会增加,因为x是正的。如果sum[n]<=0,经原创 2021-02-18 19:38:31 · 108 阅读 · 0 评论 -
2020上海ICPC B.Mine Sweeper II
思路:考虑一个二元关系(点,雷),要想到我们把整张图取反后,这个二元关系的个数是不变的想到这点这题其实就已经过了。我们计算一下图A和图B两张图不同的个数有多少个,如果少于一半,那么B可以变成A,所以输出A即可。如果大于一半呢?我们知道取反后二元组个数是不变的。所以我们对A进行取反,这样子,现在不同的个数就是没取反时候相同的个数,是小于一半的,并且满足要求,因此只需要输出A的补图即可。#include<bits/stdc++.h>using namespace std;char s[原创 2021-01-15 22:49:15 · 139 阅读 · 0 评论 -
2020济南ICPC D.Fight against involution
题意:给了n个人,每个人的写的单词个数在一个区间,最开始每个人都选择区间最右端点为自己写的单词个数,每个人的得分为n - 写的单词数大于他的人数现在让你给每个人选择写的单词数,要求得分不低于他们自己选的。思路:以右端点为第一优先级,左端点为第二优先级,从小到大排序。对于右端点一样的,我们让他们的选择都一样,并且左端点尽量小,但是要大于等于上一个人的分数这里要注意是可以取等号的因为排名与写的单词数大于他的有关,所以可以取到一样,这样每个人的得分都不低于自己的最开始希望。#include<bit原创 2021-01-07 22:51:25 · 292 阅读 · 0 评论 -
2020济南ICPC G.Xor Transformation
题意:给了一个X和Y,让每次选择一个A(0<=A<X)与X异或,让构造不超过5步使X变成Y,注意X异或后会变化思路:利用异或的性质 一个异或自己等于0所以考虑X ^ X ^ Y =Y令Z = X ^ Y如果Z<X 直接一步到位否则,先X = X ^ Y X变成了Z(Z>X) 然后X ^ Y=Y#include<bits/stdc++.h>using namespace std;#define int long long signed main(){原创 2021-01-07 01:13:23 · 261 阅读 · 0 评论 -
最优包含 第十届蓝桥杯国赛C/C++ B组
我们称一个字符串 S 包含字符串 T 是指 T 是 S 的一个子序列,即可以从字符串 S 中抽出若干个字符,它们按原来的顺序组合成一个新的字符串与 T 完全一样。给定两个字符串 S 和 T,请问最少修改 S 中的多少个字符,能使 S 包含 T?输入格式输入两行,每行一个字符串。第一行的字符串为 S,第二行的字符串为 T。两个字符串均非空而且只包含大写英文字母。输出格式输出一个整数,表示答案。数据范围1≤|T|≤|S|≤1000输入样例:ABCDEABCDXAABZ输出样例:3思原创 2020-12-28 19:09:07 · 998 阅读 · 0 评论 -
2019上海ICPC H.Tree Partition
题意:给定一棵树,每个点有自己的权值,让你把这棵树分成k棵树,求每棵树的节点权值和的最大值最小是多少。思路:最大值最小化。容易想到二分答案。然后我们考虑如何check。分成k棵树,相当于要砍k-1刀。我们进行dfs,对于把一棵树的所有结点和加起来,如果这颗子树的节点权值和大于二分的答案mid,我们就砍一刀,为了保证砍的次数尽可能少,我们用一个大顶堆存每棵子树的权值和,优先砍掉权值较大的。如果砍的次数小于等于k,那么说明答案可以更小一点,即r=mid否则l=mid#include<bits/s原创 2020-12-25 18:10:37 · 207 阅读 · 0 评论 -
2020南京ICPC F.Fireworks
题意:制作一个烟花需要n分钟,制作完一个烟花后,可以选择要释放前面所有烟花,或者继续制作下一个烟花,释放烟花需要m分钟,烟花能成功释放的概率是p,问能最少成功释放一个烟花的最小期望时间。思路:假设每做k个烟花释放一次。那么每轮制作加释放的时间就是k × n + m。有p的概率成功,那么k次都不成功的概率就是 (1-p) ^ k那么至少有一个烟花释放成功的概率就是 1- (1-p) ^ k那么需要进行的轮数期望就是1 /(1- (1-p) ^ k)不理解的话 可以考虑一下投掷硬币,正面概率是0.5,那原创 2020-12-23 23:36:43 · 241 阅读 · 0 评论 -
Codeforces Round #690 (Div. 3) E2 Close Tuples (hard version)
题意:给了n个数字,范围是1~n,数字可能存在重复的。现在给你一个k和m,问你有多少可以选择方案,选择m个不同下标的元素,让他们最大值减去最小值的差小于等于kE1与E2的区别在于,E1 k=2,m=3 并且不需要取模思路:① 考虑一下,我们只需要枚举最大值,然后计算出第一个满足的最小值,看这个区间有多少个数字,然后选择m个即可。所以我们对序列进行从小到大排序,从第m个数到第n个数遍历一下,都作为序列的最大值。② 我们可以通过二分计算出第一个大于等于a[i]-k的位置pos,然后我们原创 2020-12-16 18:01:33 · 181 阅读 · 0 评论 -
Codeforces Round #689 (Div. 2) A、B、C、D
A题意:用a、b、c三种字母,构造一个长度为n,且回文串长度最大为k的字符串。思路:前k个输出a,后面就按照cba输出就好了#include<bits/stdc++.h>using namespace std;const int N=505;int main(){ int T;cin>>T; while(T--){ int n,k;cin>>n>>k; for(int i=1;i<=k;i++)原创 2020-12-12 01:51:53 · 400 阅读 · 0 评论 -
Codeforces Round #686 (Div. 3) E. Number of Simple Paths 拓扑排序+组合数学
题意:给一个有n个点,n条边的联通图。问有多少条简单路径。简单路径是指:一条边最多经过一次的路径。思路:首先,这个联通图,可以看成是一棵树,然后再加上一条边。对于一棵树的话,任意两点都可到达,简单路径就是N * (N-1) / 2然后考虑加上一条边之后,很容易知道,一棵树,加上一条边,必形成一个环。然后我们考虑多的这条边会带来的贡献即可。如上图所示,把环上每个点作为根,会分成三颗树。对于在同一颗子树中的点,每个点到自己所在子树内任意一点的简单路径只有一条,而到达不同子树的路径则有两条。所以d原创 2020-12-02 19:03:38 · 302 阅读 · 0 评论 -
leetcode 第40场双周赛 题解
最大重复子字符串思路:计算一下长度比值,然后从大到小枚举,用c++的find函数即可class Solution {public: int maxRepeating(string a, string b) { int ma=a.size()/b.size(); for(int i=ma;i;i--){ string z=""; for(int j=1;j<=i;j++) z+=b; i原创 2020-11-28 23:52:41 · 225 阅读 · 0 评论 -
Codeforces Round #686 (Div. 3) F. Array Partition
题意:找到三个正整数x、y、z满足下面两个条件思路:首先我们很容易处理得到前后缀的最大值。前缀最大值直接遍历过去就好,后缀最大值开个数组suf维护后缀最大值即可。对于中间那部分,因为不存在修改操作,是个静态的区间问题,预处理打个st表即可。然后我们难点在于如何找到x+y的位置,满足等式首先,我们要知道这么两个常识。区间最小值会随着区间长度增大而保持不变或者减小区间最大值会随着区间长度增大而保持不变或者增大那么这里就有了单调性。所以我们枚举每个位置作为x,然后通过二分得到x+y的位置。1、如原创 2020-11-25 12:04:12 · 2385 阅读 · 7 评论 -
第十一届蓝桥杯 网络分析 带权并查集
思路:要么合并两个集合,要么给集合所有数字加数字,我们直接用一个d数组表示当前结点和根节点的差,b数组表示根结点所在集合里面所有数字要增加的数字。注意合并的时候,作为儿子结点的点的d数组要更新为原来两个集合之前的差值最后每个数字答案就是块的值加上自身与块所在集合的差值#include<bits/stdc++.h>using namespace std;const int N=1e5+50;int f[N],d[N],b[N];int find(int x){ if(f[x]!=x原创 2020-11-23 10:35:01 · 295 阅读 · 1 评论 -
C语言获取系统时间
#include<time.h>void gettime(){ time_t timep; struct tm *p; time(&timep); p = localtime(&timep); printf("%d-%d-%d %d:%d:%d", (1900 + p->tm_year), (1 + p->tm_mon), p->tm_mday,p->tm_hour,p->tm_min,p->tm原创 2020-11-22 01:46:46 · 229 阅读 · 0 评论 -
芭芭拉冲鸭~(续) LCA+树上前缀和
https://ac.nowcoder.com/acm/contest/8755/J思路:首先预处理一下树上前缀和,即从树根到当前节点,每种字母的个数有多少。那么对于每次询问,我们只需要求出LCA,然后对于两点之间每种类型字母的个数就是sum(x)+sum(y)-sum(LCA)-sum(FA[LCA])然后每种类型字母都取偶数加起来,在看看有没有奇数就好了。关于树上前缀和式子计算右转https://blog.youkuaiyun.com/qq_43563669/article/details/1099028原创 2020-11-21 17:21:53 · 420 阅读 · 0 评论 -
树上前缀和
点权公式:sum(x)+sum(y)-sum(LCA)-sum(FA[LCA])sum(x) 表示从根节点到x上所有点统计了一遍sum(y)表示从根节点到y上所有点统计了一遍这样的话,从根节点到LCA上每个点都计算了两次,而从LCA到x,LCA到y上的点都计算了一次那么我们要的结果是从x到y上所有点都计算了一次。所以减去sum(LCA) ,操作之后从根节点到LCA上的点(不包括LCA)计算了两次,所以减去sum(FA[LCA])即可边权公式:sum(x)+sum(y)-2*sum(LCA)原创 2020-11-21 17:21:05 · 485 阅读 · 0 评论 -
芭芭拉冲鸭~ 树的直径
https://ac.nowcoder.com/acm/contest/8755/H思路:不同类型的点对他进行建边,等于是将原来的一棵树断开了一些边,成了一片森林,那么对每棵树求一下直径,维护max即可。可以用并查集维护每棵树内的结点。#include<bits/stdc++.h>using namespace std;typedef long long ll;const ll mod=1e9+7;const int N=1e6+50;int f[N];int find(int原创 2020-11-21 17:09:21 · 443 阅读 · 0 评论 -
Educational Codeforces Round 98 (Rated for Div. 2) A、B、C、D
A初始位置在(0,0),问走到(x,y)最少要多长时间,如果连续走两步一样的话,中间需要休息一秒。思路首先肯定x+y秒是需要的,因为走一步都需要花时间。然后我们去计算停留的时间是多少就好了,很容易算出停留时间是max-min-1,但是这里要注意这是差值大于等于1的时候,如果相等的话,就不需要减1,所以答案就是x+y+max(max(x,y)-min(x,y),0)#include<bits/stdc++.h>using namespace std;typedef long lon原创 2020-11-20 16:11:30 · 166 阅读 · 0 评论 -
第十一届蓝桥杯C/C++ B组决赛题目
原创 2020-11-14 18:34:32 · 406 阅读 · 0 评论 -
试题 E: 玩具蛇
【问题描述】小蓝有一条玩具蛇,一共有 16 节,上面标着数字 1 至 16。每一节都是一个正方形的形状。相邻的两节可以成直线或者成 90 度角。小蓝还有一个 4 × 4 的方格盒子,用于存放玩具蛇,盒子的方格上依次标着字母 A 到 P 共 16 个字母。小蓝可以折叠自己的玩具蛇放到盒子里面。他发现,有很多种方案可以将玩具蛇放进去。下图给出了两种方案:请帮小蓝计算一下,总共有多少种不同的方案。如果两个方案中,存在玩具蛇的某一节放在了盒子的不同格子里,则认为是不同的方案。思路:刚开始nt了原创 2020-11-14 18:20:40 · 493 阅读 · 0 评论 -
试题 D: 本质上升序列
【问题描述】小蓝特别喜欢单调递增的事物。在一个字符串中,如果取出若干个字符,将这些字符按照在字符串中的顺序排列后是单调递增的,则成为这个字符串中的一个单调递增子序列。例如,在字符串 lanqiao 中,如果取出字符 n 和 q,则 nq 组成一个单调递增子序列。类似的单调递增子序列还有 lnq、i、ano 等等。小蓝发现,有些子序列虽然位置不同,但是字符序列是一样的,例如取第二个字符和最后一个字符可以取到 ao,取最后两个字符也可以取到 ao。小蓝认为他们并没有本质不同。对于一个字符串,小原创 2020-11-14 18:17:42 · 1675 阅读 · 2 评论 -
试题 C: 阶乘约数
【问题描述】定义阶乘 n! = 1 × 2 × 3 × · · · × n。请问 100! (100 的阶乘)有多少个约数。思路:约数个数定理。就是把质因子都搞出来,对于质因子ai,有cnt个,那么他的选择方案有(cnt+1)种,根据乘法原理。累乘即可。//39001250856960000#include<bits/stdc++.h>using namespace std;const int N=10500;const int Q=5000;int mp[N][N];in原创 2020-11-14 18:14:39 · 2085 阅读 · 0 评论 -
试题 B: 扩散
【问题描述】小蓝在一张无限大的特殊画布上作画。这张画布可以看成一个方格图,每个格子可以用一个二维的整数坐标表示。小蓝在画布上首先点了一下几个点:(0, 0), (2020, 11), (11, 14), (2000, 2000)。只有这几个格子上有黑色,其它位置都是白色的。每过一分钟,黑色就会扩散一点。具体的,如果一个格子里面是黑色,它就会扩散到上、下、左、右四个相邻的格子中,使得这四个格子也变成黑色(如果原来就是黑色,则还是黑色)。请问,经过 2020 分钟后,画布上有多少个格子是黑色的。原创 2020-11-14 18:12:16 · 1530 阅读 · 2 评论 -
试题 A: 美丽的 2
【问题描述】小蓝特别喜欢 2,今年是公元 2020 年,他特别高兴。他很好奇,在公元 1 年到公元 2020 年(包含)中,有多少个年份的数位中包含数字 2?思路:直接for暴力就好#include<bits/stdc++.h>using namespace std;int main(){ int ans=0; for(int i=1;i<=2020;i++){ int flag=0; int x=i; while(x){ flag |= x%10==2原创 2020-11-14 18:10:58 · 690 阅读 · 5 评论 -
CCFCSP 201809-2 买菜
思路:范围小可以直接暴力。如果n的范围很大,那么可以考虑直接差分,然后前缀和一下。#include<bits/stdc++.h>using namespace std;typedef long long ll;const int N=1e6+5;int a[N],b[N];signed main(){ int n;cin>>n; for(int i=1;i<=n;i++){ int x,y;cin>>x>>原创 2020-11-03 10:56:15 · 145 阅读 · 0 评论 -
CCFCSP 201809-1 卖菜
思路:模拟过程#include<bits/stdc++.h>using namespace std;typedef long long ll;signed main(){ int n;cin>>n; vector<int> a; a.resize(n+1); for(int i=1;i<=n;i++) cin>>a[i]; for(int i=1;i<=n;i++){ if(i==1原创 2020-11-03 10:47:19 · 105 阅读 · 0 评论 -
CCFCSP 201812-4 数据中心
思路:其实就是找到图中的一颗最小生成树,求出最小生成树中的最大边权即可#include<bits/stdc++.h>using namespace std;typedef long long ll;const int N=5e5+5;int f[N];struct node{ int a,b; ll v; friend bool operator<(node a,node b){ return a.v<b.v; };}a原创 2020-11-03 10:41:30 · 152 阅读 · 0 评论 -
2020CCPC绵阳 K- Knowledge is Power
题意:给你一个数字x,把x至少拆分为两个数的和,并且这些数字互质,问所有拆分方案中,在每个方案中最大值减去最小值的最小值是多少思路:算是一个构造题吧。①如果x是奇数,那么拆分为x/2和x-x/2,答案是1②如果x是偶数并且x/2是偶数,,那么可以分成x/2+1,x/2-1这是分成了两个奇数,一定互质,答案是2③如果x是偶数并且x/2是奇数,那么我们对x取余3进行判断。如果是3的倍数,比如42,可以拆成13 14 15.那么答案是2如果取模3后余1,比如70 可以分成22 23 25 答案是3原创 2020-11-02 10:23:22 · 2506 阅读 · 6 评论 -
2020绵阳CCPC J-Joy of Handcraft
题意:给了n个灯泡,每个灯泡有自己的亮的时间长度和灯泡亮度。一段固定的时间是亮的,一段固定的时间是灭的,是一个周期性变化,问在1~m的时间中,每个时间内的最大亮度是多少。写在前面:第一眼就是线段树但是,当时没有具体去算有多少种区间,默认为由n^2个区间暴力区间赋值会T掉,这里奠定了这题GG的后果 所以立刻hack了正解做法。然后后面我算了一下区间的个数只有mlogm个 并且这句话我跟队友重复说了好几遍了 能不能只处理区间端点 这样一定不会T。 可惜在一开始就把线段树做法否决了。后面也没去想线段树原创 2020-11-01 21:13:24 · 473 阅读 · 0 评论 -
2017杭州CCPC J - Master of GCD
思路:容易知道2和3是互质的,而gcd的话,就是出现次数最小的那个数值。所以我们开两个数组差分后,一次前缀和,然后算出2出现的最小次数,3出现的最小次数。快速幂算一下相乘即可。#include<bits/stdc++.h>using namespace std;typedef long long ll;const int N=1E5+50;ll a[N],b[N];const ll mod=998244353;ll qpow(ll a,ll b){ ll ans=1;原创 2020-10-24 18:02:16 · 157 阅读 · 0 评论 -
2017杭州CCPC A - Super-palindrome
思路:要所有长度为奇数的子串满足。那么其实就是奇数位置的字符要都一样,偶数位置的字符要都一样。所以维护出奇数和偶数出现最多的次数,总长度减去即可。#include<bits/stdc++.h>using namespace std;typedef long long ll;const int N=1E5+50;int main(){ int T;cin>>T; while(T--){ string s;cin>>s;原创 2020-10-24 17:59:55 · 129 阅读 · 0 评论 -
CCFCSP 201903-1 小中大
思路:排序一下可以得到最大值和最小值。对于中位数,看n的奇偶,如果是奇数,那么中位数只有一个直接输出。如果n是偶数,看两个中位数和是奇数还是偶数,偶数的话,输出和除以2奇数的话,除以2保留一位小数即可(其实小数位肯定是5)。#include<bits/stdc++.h>using namespace std;const int N=1e5+5;int a[N];int main(){ int n;cin>>n; for(int i=1;i<=n;i++)原创 2020-10-22 20:17:13 · 145 阅读 · 0 评论 -
CCFCSP 201712-2 游戏
思路:直接模拟过程,用vis[i]表示第i个人是不是被淘汰了。用now表示当前的报数。如果当前vis[i]==0 说明没被淘汰,然后判断是否要被淘汰,报数值now要加1#include<bits/stdc++.h>using namespace std;const int N=1<<10;bool vis[N];int main(){ int n,k;cin>>n>>k; int num=n,now=1; while(num>1)原创 2020-10-22 20:07:19 · 97 阅读 · 0 评论 -
CCFCSP 202009-1 称检测点查询
思路:用结构体存起来每个点和(X,Y)的距离平方和(不需要开根号 防止精度丢失)以及当前点的id,排序一下即可。#include<bits/stdc++.h>using namespace std;const int N=205;struct node{ int dis,id;}a[N];bool cmp(node a,node b){ if(a.dis==b.dis) return a.id<b.id; return a.dis<b.dis;}int m原创 2020-10-22 19:50:21 · 332 阅读 · 1 评论 -
2019秦皇岛CCPC J - MUV LUV EXTRA
题意:从一个小数的小数部分,计算下面式子的最大值其中a和b是给定的参数,p是循环结已知的长度,l是循环结的长度例如对于abab,p是4,l就是2思路:贪心的来说我们要让p更大,l尽可能小,所以我们从给的小数的最后一位开始枚举,遍历的小数为作为p,那么l就是循环结的长度,对于循环结长度,我们可以用kmp求得。#include<bits/stdc++.h>using namespace std;const int N=1e7+5;int ne[N];char s[N];void原创 2020-10-21 17:48:10 · 187 阅读 · 0 评论 -
CCFCSP 201503-2 数字排序
思路:数组标记存每个数出现的次数,遍历一下这个桶,用结构体存数字和出现的次数,排序一下即可#include<bits/stdc++.h>using namespace std;int a[1005];struct node{ int x; int num;}q[1005];bool cmp(node a,node b){ if(a.num==b.num) return a.x<b.x; return a.num>b.num;}int m原创 2020-10-16 16:33:28 · 270 阅读 · 1 评论 -
CCFCSP 201612-1 中间数
思路:两个for,第一个for枚举中间数,第二个去统计大于和小于这个数的个数,相同的话直接输出,枚举一遍后都没有就输出-1#include<bits/stdc++.h>using namespace std;int main(){ int n;cin>>n; vector<int> a; a.resize(n); for(int i=0;i<n;i++) cin>>a[i]; for(int i=0;i<原创 2020-10-16 16:26:56 · 104 阅读 · 0 评论 -
CCFCSP 201412-1 门禁系统
思路:用数组标记每个数字之前出现的次数即可。#include<bits/stdc++.h>using namespace std;int main(){ int n;cin>>n; vector<int> a(n+1,0); for(int i=1;i<=n;i++){ int x;cin>>x; cout<<++a[x]<<" "; } return原创 2020-10-16 16:21:32 · 121 阅读 · 0 评论 -
2017秦皇岛CCPC M - Safest Buildings
题意:给了n个点,一个R和一个r,R的圆心在坐标原点,现在让你在以R为半径的大圆内,随便划半径为r的小圆,小圆内含在大圆中,问哪些点被覆盖的概率最多,输出这些点的编号。思路:几何题。考虑边界情况如下图。这样的概率是最大的,即A点在一个以r为半径的圆上,并且这个小圆包含于大圆中。容易知道存在这么一些点,满足OA+AB<=R ,我们知道AB=2r所以OA+2r<=ROA<=R-2r满足这样的点的概率最大,并且都一样。如果不存在的话,那么就是离圆心最近的点概率最大。#inclu原创 2020-10-11 22:24:49 · 171 阅读 · 0 评论