03 2021 档案
摘要:水题~。 注意权值和可能会爆int。 const int N=1e5+10; int val[N]; LL sum[N]; int n; int maxd; void dfs(int u,int d) { if(u > n) return; maxd=max(maxd,d); sum[d]+=val
阅读全文
摘要:贪心思路:每次将第个位置上的数,与数字所处的位置进行交换。重复这个操作,每次至少会将一个数字通过交换至归位,直到序列变为有序。 const int N=1e5+10; int a[N]; int n; int main() { cin>>n; for(int i=1;i<=n;i++)
阅读全文
摘要:通过双指针维护这段时间窗口内,每个日志出现的次数。 const int N=1e5+10; PII a[N]; int cnt[N]; int n,d,k; int main() { cin>>n>>d>>k; for(int i=0;i<n;i++) cin>>a[i].
阅读全文
摘要:只通过比较和交换相邻两个数值的排序方法,实际上就是冒泡排序。在排序过程中每找到一对大小颠倒的相邻数值,把它们交换,就会使整个序列的逆序对个数减少。最终排好序后的逆序对个数显然为,所以对序列进行冒泡排序需要的最少交换次数就是序列中逆序对的个数。 本题要求计算出所有小朋友的不高兴程度之和,所
阅读全文
摘要:从样例可看出同一外卖店某一时刻可能会有多个订单。 我们先将订单按时间排序,再按外卖店编号排序,这样同一时刻若存在多个订单,外卖店编号相等的一定相邻。 对某一时刻的订单来说,我们累加该时刻同一外卖店编号的所有订单产生的优先级。 在累加优先级前,先计算出外卖店距离上次产生订单的时刻至时刻
阅读全文
摘要:水题~。 const int N=1e5+10; struct Node { int yy,mm,dd; bool operator<(const Node &W) const { if(yy != W.yy) return yy < W.yy; if(mm != W.mm) return mm <
阅读全文
摘要:暴力做法 时间复杂度:。 int n; int main() { cin>>n; for(int i=0;i*i<=n;i++) for(int j=i;i*i+j*j<=n;j++) for(int k=j;i*i+j*j+k*k<=n;k++) { int t=n-i*i-j
阅读全文
摘要:二维偏序问题,用树状数组解决。 本题看似二维,但给出的数据就是已经按照y从小到大排好序的,也就是说,当前读到一个点的时候,当前点的y坐标肯定比已经读入的大,或者等于。就算是等于的话,也是x坐标比我当前点的x坐标小。这样一来,我们如果按照读入顺序来处理,则保证了后面点的y坐标一定大于前面的点,所以我们
阅读全文
摘要:水题~。 int w; int n,m; PII posn,posm; PII solve(int n) { n--; int row=n/w; int col; if(row % 2) col=w-1-n%w; else col=n%w; return {row,col}; } int main(
阅读全文
摘要:枚举年份,从枚举到,构造回文日期,判断是否在给定日期范围内,以及判断日期是否合法。 int month[2][13]={ {0,31,28,31,30,31,30,31,31,30,31,30,31}, {0,31,29,31,30,31,30,31,31,30,31,30,
阅读全文
摘要:水题。 const int N=1e5+10; int vis[N]; int n; int main() { cin>>n; string line; getline(cin,line);//忽略第一行空格、回车 int minv=INF,maxv=0; for(int i=0;i<n;i++)
阅读全文
摘要:水题。 const int N=10010; int n; bool check(int x) { bool ok=false; while(x) { int t=x%10; if(t == 2 || t == 0 || t == 1 || t == 9) ok=true; x/=10; } ret
阅读全文
摘要:哈希表中 的计数加一, 同时将指针 向后移一位 不断向后移动 ,直至区间 中 的个数等于1为止; class Solution { public: int lengthOfLongestSubstring(string
阅读全文
摘要:连号区间的性质是。 const int N=10010; int a[N]; int n; int main() { cin>>n; for(int i=0;i<n;i++) cin>>a[i]; int res
阅读全文
摘要:分情况讨论即可。 以感染蚂蚁向右走为例,对每一个蚂蚁的走向: 右边向左走,必然被感染 右边向右走,必然不会被感染 左边向左走,必然不会被感染 左边向右走: 右边存在向左走,则必然被感染 右边不存在向左走,则必然不会被感染 const int N=55; int d[N]; int n; int ma
阅读全文
摘要:水题。 int n; int main() { cin>>n; int res=n; int carry=0; while(n) { n+=carry; carry=n%3; n/=3; res+=n; } cout<<res<<endl; //system("pause"); return 0;
阅读全文
摘要:注意只有连续个或更多坐标均位于矩形内(含边界),则认为该居民曾在高危区域逗留。 const int N=25; int n,k,t,xld,yld,xru,yru; int pass,stay; bool check(int x,int y) { return x>=xld && x<=xru
阅读全文
摘要:水题。 const int N=210; PII dist[N]; int n,x,y; int get(int a,int b,int c,int d) { return (a-c)*(a-c)+(b-d)*(b-d); } int main() { cin>>n>>x>>y; for(int i
阅读全文
摘要:和122. 买卖股票的最佳时机 II状态定义一模一样。 转移方程如下: class Solutio
阅读全文
摘要:一种常用的方法是将「买入」和「卖出」分开进行考虑:「买入」为负收益,而「卖出」为正收益。在初入股市时,你只有「买入」的权利,只能获得负收益。而当你「买入」之后,你就有了「卖出」的权利,可以获得正收益。显然,我们需要尽可能地降低负收益而提高正收益,因此我们的目标总是将收益值最大化。因此,我们可以使用动
阅读全文
摘要:和123. 买卖股票的最佳时机 III一样的DP解法。 注意对的特判。 class Solution { public: int f[1010][2][110]; int maxProfit(int k, vector<int>& prices) { int n=prices.size();
阅读全文
摘要:状态表示: :表示当前为第天,手里没有股票,交易次数不超过次的最大利润; :表示当前为第天,手里有股票,交易次数不超过次的最大利润。 状态转移: 第天手里没有股票有两种情况: 第天手里没有股票; 第天手
阅读全文
摘要:题意 给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。 你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。 返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回
阅读全文
摘要:摘花生+LIS(要取得当前格子的物品,这个物品必须比当前所拥有的物品都大,所以物品的重量严格递增)的结合题。 状态表示::当前到达位置,已经取了件物品,且最后一件物品的重量为。 状态转移:$(i,j)(i-1,j)\(抵达,也可以从
阅读全文
摘要:暴力思路为枚举每个人的分数,将当前分数作为阈值,统计预测正确的个数,取预测正确个数最大的作为最终的阈值,复杂度为:。 我们可以先将所有人的分数排个序,这样在枚举第个人的分数作为阈值时,的分数都小于,的分数都大于。
阅读全文
摘要:暴力的做法是,枚举左右端点和,通过前缀和计算出,但不足以通过此题。 题意可转化为:找两个端点和,使得$sum[l \sim r]%k = (sum[r] - sum[l-1])%k == 0
阅读全文
摘要:直接暴力枚举所有状态,时间复杂度: const int N=5; bool g[N][N],tmp[N][N]; int n=4,m=4; bool check(int x,int y) { return x>=0 && x<n && y>=0 &&
阅读全文
摘要:和95. 费解的开关同题。 暴力总共有种翻转的方法。 先确定第一行的翻转方式,然后可以很容易判断这样是否存在解以及解的最小步数是多少,最上面一行的翻转方式共有种,复杂度为。 const int N=20; bool g[N][N],tmp[N][N]; int
阅读全文
摘要:首先我们需要枚举,对每个我们都要从最左端开始来考虑头牛的情况,此时最坏情况下需要进行次反转操作,而每次操作又要反转头牛,于是总的复杂度为。 对区间反转的部分考虑使用差分,每次只修改,通过前缀和求解每一位是否反转。 反转
阅读全文
摘要:二分 问题显然具有二段性。 每一步过程中,的范围为,中间过程可能溢出。 观察到如果中间某步满足,则之后过程的值一定非负,可以抵达终点。 const int N=1e5+10; int h[N],maxh; int n; bool
阅读全文
摘要:签到题。 int n; int main() { cin>>n; int res=0; for(int i=0;i<n;i++) { int score,w; cin>>w>>score; res+=w*score; } cout<<max(res,0)<<endl; //system("pause
阅读全文
摘要:思路 枚举的全排序 枚举分界处的位置 时间复杂度: int path[10]; bool vis[10]; int n; int ans; void dfs(int u) { if(u == 9) { int a=0;
阅读全文
摘要:题意 给出两个序列作为二叉树的先序序列和后序序列,序列内数字各不相同,判断是否能唯一确定一棵二叉树。输出任意一棵符合的二叉树的中序序列。 思路 以上图为例进行说明,该图左的二叉树对应的先序序列和后序序列如该图右所示。 可以知道的一点是,先序序列的第一个结点和后序序列的最后一个结点都表示根结点,因此一
阅读全文
摘要:自测时间为2021年春季考试前一天下午。 7-1 The Closest Fibonacci Number (20 分) The Fibonacci sequence is defined by for
阅读全文
摘要:额,这不是和1143 Lowest Common Ancestor (30 分)一模一样吗。 const int N=10010; int fa[N]; unordered_map<int,int> pos; int pre[N],in[N]; bool vis[N]; int n,m; int b
阅读全文
摘要:好家伙,一直有一两个点超时,换成数组就过了,看来实现的哈希表还是没数组快啊。 向上标记法。 const int N=10010; int fa[N]; unordered_map<int,int> pos; int pre[N],in[N]; bool vis
阅读全文
摘要:数据范围小,用的暴力搜索法。 同步前进法。 const int N=110; int fa[N]; int dep[N],width[N]; int maxh,maxw; int n; int LCA(int u,int v) { if(dep[u] < dep[v]) swap(u,v); whi
阅读全文
摘要:水~,基于层序遍历。 树高最坏情况下为,即为一条链。 const int N=35; unordered_map<int,int> pos; unordered_map<int,PII> tree; unordered_map<int,int> dep; int in[N],post[N];
阅读全文
摘要:和1147 Heaps (30 分)类似,分水了。 const int N=1010; int heap[N]; bool minheap,maxheap; int n; void dfs(int u,vector<int> &path) { if(u*2 > n)//叶子结点 { for(
阅读全文
摘要:分水题~。 检查所有节点(除了根节点)和它的父节点的关系,判断是否破坏最大堆或者最小堆的性质。 const int N=1010; int heap[N]; bool maxheap,minheap; int n; void dfs(int u,vector<int> &post) { if
阅读全文
摘要:题意 给出一个初始序列,可以对它使用插入排序或堆排序法进行排序。现在给出一个序列,试判断它是由插入排序还是堆排序产生的,并输出下一步将会产生的序列。 思路 本题与A1089非常类似,需要直接模拟插入排序和堆排序的每一步过程。 具体做法为:先进行插入排序,如果执行过程中发现与给定序列吻合,那么说明是插
阅读全文
摘要:手写堆排序。 const int N=1e5+10; int heap[N],cnt; int n,m; void down(int u) { int j=u*2; while(j <= n) { if(j < n && heap[j] > heap[j+1]) j++; if(heap[u] >
阅读全文
摘要:手写堆。 const int N=1e6+10; int heap[N]; int n,m; void up(int u) { while(u/2 && heap[u] < heap[u/2]) { swap(heap[u],heap[u/2]); u/=2; } } void down(int u
阅读全文
摘要:如果查找了 TSize 次,每次查找的位置上均有数,但都不等于要查找的数,则认为查找时间是 TSize+1。 const int N=1e4+10; int Tsize,n,m; int h[N]; int cnt; bool isprime(int x) { if(x < 2) return fa
阅读全文
摘要:用存图。 注意点 A在寻找同性朋友时,需要避免找到他想要的伴侣B,所以当当前朋友就是B或者B的同性朋友就是A时舍弃该结果。 负号标记的是女生。如果用int接收,-0000和0000对于int来说都是0,无法判断出0000的性别,所以考虑用字符串接收。 const int N=1e4+10;
阅读全文
摘要:染色法判断是否为染色图,需要一个数组防止走环路。 const int N=10010; vector<int> g[N]; bool vis[N]; int color[N]; int n,m,q; bool dfs(int u) { vis[u]=true; for(int i=0
阅读全文
摘要:每个位置至多只会被点击一次 若固定了第一行,则满足题意的点击方案至多只有一种。原因:当第i行某一位为1时,若前i行已被固定,只能点击第i+1行该位置上的数字才能使第i行的这一位变成0,从上到下使用归纳法可得上述结论。 点击的先后顺序不影响最终结果。 于是,我们不妨先考虑第一行如何点击。在枚举第一行的
阅读全文
摘要:考察并查集的熟练使用。 const int N=10010; struct Node { int id; int father,mother; int k; int child[6]; }a[1010]; struct Answer { int id; int cnt; double sets; d
阅读全文
摘要:最长回文子串。 动态规划解法,时间复杂度:。 const int N=1010; bool f[N][N]; string s; int main() { getline(cin,s); int res=0; for(int i=s.size()-1;i>=0;i--) for(
阅读全文
摘要:暴力做法:。 const int N=1010; int a[N]; int l[N],r[N]; int n; int main() { cin>>n; for(int i=0;i<n;i++) cin>>a[i]; int res=0; for(int i=0;i<n;i++
阅读全文
摘要:注意'X'的处理。 string s; int main() { cin>>s; int res=0,w=1; for(int i=0;i<s.size()-1;i++) if(isdigit(s[i])) res+=(s[i]-'0')*w++; if((s[s.size()-1] == 'X'
阅读全文
摘要:水~。 int cnt[10010]; int n; int main() { cin>>n; for(int i=0;i<n;i++) { int x; cin>>x; cnt[x]++; } int res=0; for(int i=0;i<10001;i++) if(cnt[res] < cn
阅读全文
摘要:并查集水题~。 const int N=10010; int p[N]; int n,m,q; int find(int x) { if(x != p[x]) p[x]=find(p[x]); return p[x]; } int main() { cin>>m; for(int i=1;i<N;i
阅读全文
摘要:注意括号序列的输出,首先叶子结点不需要括号,其次最外层也不需要括号。 const int N=25; PII tree[N]; string a[N]; int fa[N]; bool leaf[N]; int n; int root=1; void inorder(int u) { if(u ==
阅读全文
摘要:考察点:试除法求约数、方向数组。 类似题:756. 蛇形矩阵。 const int N=10010; int a[N]; int dx[]={0,1,0,-1},dy[]={1,0,-1,0}; int k,n,m; int cnt; bool check(int x,int y) { return
阅读全文
摘要:注意图不一定连通!。 const int N=510; bool g[N][N]; int d[N]; bool vis[N]; int n,m; int cnt; void dfs(int u) { vis[u]=true; cnt++; for(int i=1;i<=n;i++) if(g[u]
阅读全文
摘要:注意结果向下取整。 因为所有长度都要串在一起,每次都等于(旧的绳子长度+新的绳子长度)/2,所以越是早加入绳子长度中的段,越要对折的次数多,所以既然希望绳子长度是最长的,就必须让长的段对折次数尽可能的短。 将所有段从小到大排序,然后从头到尾从小到大分别将每一段依次加入结绳的绳子中,最后得到的结果才会
阅读全文
摘要:水~。 const int N=1010; string a[N]; unordered_set<string> S; int n,step,idx; int main() { cin>>n>>step>>idx; for(int i=1;i<=n;i++) cin>>a[i]; for(int i
阅读全文
摘要:参考柳神代码,考察的自定义排序。 const int N=50010; struct Node { int item; int times; bool operator<(const Node &W) const { if(times != W.times) return times >
阅读全文
摘要:水~。 const int N=1010; int row[N]; int n; bool check(int x,int y) { for(int i=1;i<y;i++) if(row[i] == x || abs(x-row[i]) == y-i) return false; return t
阅读全文
摘要:水~。 const int N=210; int g[N][N]; int n,m,q; int main() { cin>>n>>m; memset(g,0x3f,sizeof g); while(m--) { int a,b,c; cin>>a>>b>>c; g[a][b]=g[b][a]=c;
阅读全文
摘要:直接暴力枚举。 bool check(int a,int b) { set<int> wolfs; wolfs.insert(a),wolfs.insert(b); int liar_human=0,liar_wolf=0; for(int i=1;i<=n;i++) { int t=state[i
阅读全文
摘要:sb题,不想过多描述==。 struct Node { string id; int score; bool operator<(const Node &W) const { if(score != W.score) return score > W.score; return id < W.id;
阅读全文
摘要:水~。 int n,k; bool isprime(int x) { for(int i=2;i*i<=x;i++) if(x % i == 0) return false; return true; } int main() { cin>>n>>k; string s; cin>>s; strin
阅读全文
摘要:乱搞过去的。 map<int,set<int>> mp; int n,m; int main() { cin>>n>>m; for(int i=0;i<n;i++) { int a,b; cin>>a>>b; mp[a].insert(b); mp[b].insert(a); } whil
阅读全文
摘要:题意 塔都市的警察局决定治理混乱,从城市中的两个帮派开始行动,Gang Dragon和Gang Snake。但是,警方首先需要确定犯罪分子属于哪个团伙。目前的问题是,两名罪犯,他们属于同一个帮派吗?您必须根据不完整的信息做出判断。(因为歹徒总是暗中行动。) 假设罪犯目前在塔都
阅读全文
摘要:判断是否是合法拓扑序,水~。 const int N=1010; vector<int> g[N]; int din[N],tdin[N]; int n,m,q; int main() { cin>>n>>m; while(m--) { int a,b; cin>>a>>b; g[a].pb(b);
阅读全文
摘要:水~。 set<int> S; int n; int main() { cin>>n; for(int i=0;i<n;i++) { int x; cin>>x; if(x > 0) S.insert(x); } int res=1; while(S.count(res)) res++; cout<
阅读全文
摘要:水~,依旧是喜闻乐见的链表题。 题意 给出N个结点的地址address、数据域data以及指针域next,然后给出链表的首地址,要求去除链表上权值的绝对值相同的结点(只保留第-一个),之后把未删除的结点按链表连接顺序输出,接着把被删除的结点也按在原链表中的顺序输出。 const int N=1e5+
阅读全文
摘要:先判断是否是clique,即判断是否任意两边都相连;之后判断是否是maximal,即遍历所有不在集合中的剩余的点,看是否存在一个点满足和集合中所有的结点相连,最后如果都满足,那就输出Yes表示是Maximal clique。 const int N=210; bool g[N][N]; int v[
阅读全文
摘要:双指针写法,秒啊。 int n; int main() { string s; cin>>s>>n; for(int k=0;k<n-1;k++) { string res; for(int i=0;i<s.size();) { int j=i+1; while(j<s.size() && s[j]
阅读全文
摘要:水~。 const int N=1e5+10; struct Node { int scoreb,scorea,scoret; int score; int cnt; int rank; string school; bool operator<(const Node &W) const { if(
阅读全文
摘要:水~。 const int N=50010; int pre[N],in[N]; unordered_map<int,int> pos; int ans=-1; int n; void build(int prel,int prer,int inl,int inr) { if(prel > prer
阅读全文
摘要:水~。 struct Node { string id; int gp,gm,gf,g; Node() { gp=gm=gf=g=-1; } bool operator<(const Node &W) const { if(g == W.g) return id < W.id; return g >
阅读全文
摘要:要上高精度。 const int N=10010; struct bignum { int m[N]; int len; bignum() { memset(m,0,sizeof m); len=0; } }; int n; bool check(string s) { for(int i=0;i<
阅读全文
摘要:分的题目果然顶啊。 思路 根据先序中序建立一棵树 判断根结点是否是黑色。 根据建立的树,从根结点开始遍历,如果当前结点是红色,判断它的孩子节点是否为黑色。 从根节点开始,递归遍历,检查每个结点的左子树的高度和右子树的黑色结点的个数,比较个数集合大小是否为。 const int N=35
阅读全文
摘要:判断点覆盖,用前向星直接切。 idx存储边的下标,idx^1为反向边,注意边数组开两倍,因为存的双边。 const int N=1e4+10; int h[N],e[N<<1],ne[N<<1],idx; bool vis[N<<1]; int n,m,q; void add(int a,int b
阅读全文
摘要:水~。 const int N=1e5+10; struct Node { int addr,data,nxt; }a[N]; int head,n,k; void add(vector<Node> &res,vector<Node> &v) { for(int i=0;i<v.size();i++
阅读全文
摘要:水~。 注意点 要考虑可能存在无效结点的情况,即不是由题目给出的头结点引出的单链表上的结点,这些结点是要去掉的,最终不予输出。 反转链表只改变结点的next地址,而不会改变本身的地址,因此address和data可以视为绑定的。 const int N=1e5+10; struct Node { i
阅读全文
摘要:水~。 注意右半部为的情况。 int main() { int T; cin>>T; while(T--) { string s; cin>>s; string a=s.substr(0,s.size()/2),b=s.substr(s.size()/2); int ts=stoi(s),ta
阅读全文
摘要:有向图判环。 拓扑排序 判断拓扑排序的结果是否包含个点。 const int N=110; vector<int> g[N]; int din[N]; int n,m; bool topo() { queue<int> q; for(int i=0;i<n;i++) if(din[i] ==
阅读全文
摘要:拓扑排序水题~。 const int N=510; vector<int> g[N]; vector<int> ans; int din[N]; int n,m; void topo() { priority_queue<int,vector<int>,greater<int>> q; for(in
阅读全文
摘要:题意 给定n个点和n*(n-1)/2条边的无向图,求图的最小生成树,其中有些边已经确定(可能是最小生成树的一部分,也可能不是)。 思路 由于已经确定了部分边,在读入数据过程中,如果这条边已经被确定,那我们就用并查集将两点合并;如果这条边还未确定,那么我们将它放进边集数组等待Kruskal算法进行从小
阅读全文
摘要:裸题。 struct Node { int a,b,c; bool operator<(const Node &W) const { return c < W.c; } }e[80]; int p[30]; int n,m; int find(int x) { if(x != p[x])
阅读全文
摘要:这是真的水,就是写起来烦(摊手)。 题意 给定一个图、一个起点和一个终点,求一条距离最短的路径,如果有多条距离最短的路径,从中选择时间最短的一条,数据保证唯一性;再求一条时间最少的路径,如果有多条时间最少的路径,从中选择路径上顶点个数最少的一条,数据保证唯一性。如果距离最短和时间最少的是同一条路径,
阅读全文
摘要:水~。 题意 给定一个无向图和一.堆路径,判断每一条路径是否是这个无向图的哈密顿回路。所谓哈密顿回路是指首尾结点相同、经过且恰好经过图上所有结点各一次的路径。 思路 根据哈密顿回路的定义,一条路径是哈密顿回路需要满足3个条件: (1)首尾结点相同。 (2)路径的每条边必须都存在。 (3)不考虑首结点
阅读全文
摘要:裸题 const int N=110; struct Node { int a,b; double c; bool operator<(const Node &W) const { return c<W.c; } }e[N*N]; PDD a[N]; int p[N]; int n,m;
阅读全文
摘要:这题水的有点蛋疼。 题意 有N个城市,M条无向边。现在需要从某个给定的起始城市出发(除了起始城市外,其他每个城市都有一一个“幸福值”,前往名为“ROM”的城市。给出每条边所需要消耗的花费,求从起始城市出发,到达城市ROM所需要的最少花费,并输出最少花费的路径。如果这样的路径有多条,则选择路径上城市的
阅读全文
摘要:水~。 题意 有N所居民房、M个加油站待建点以及K条无向边。现在要从M个加油站待建点中选出一个来建造加油站,使得该加油站距离最近的居民房尽可能远,且必须保证所有房子与该加油站的距离都不超过给定的服务范围DS。现在给出N、M、K、DS,以及K条无向边的端点及边权,输出应当选择的加油站编号、与该加油站最
阅读全文
摘要:题意 城市里有一些公共自行车站,每个车站的自行车最大容量为一个偶数Cmax,且如果一个车站中自行车的数量恰好为Cmax/2,那么称该车站处于“完美状态”。而如果一个车站容量是满的或是空的,那么控制中心(PBMC)就会携带或从路上收集一定数量的自行车前往该车站,以使问题车站及沿途所有车站都达到“完美状
阅读全文
摘要:水~。 题意 有N个城市(编号为0~N-1)、M条道路(无向边),并给出M条道路的距离属性与花费属性。现在给定起点S与终点D,求从起点到终点的最短路径、最短距离及花费。注意:如果有多条最短路径,则选择花费最小的那条。 const int N=510; struct Node { int v,dis,
阅读全文