Test 2022.10.08
今天是鸡杂专场
T1 跳楼
题意
就是给出每栋楼的高度,然后有两个约束条件,分别对应前一项、前两项的递推关系,然后从第一栋楼开始,求最后能否到达第n栋楼
分析
简简单单一个和前两项有关的递推,注意如果当一栋楼的前两栋楼都不能到达,那么后面的所有楼一定都是不能到达的,所以这个时候就直接可以break掉输出了,有一个小细节就是memset重置vis数组的时候可以改为在输入的时候用循环展开的原理去做,这样不会T掉后面三个点
Code
点击查看代码
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; template <typename T>inline void re(T &x) { x=0; int f=1; char c=getchar(); for(;!isdigit(c);c=getchar()) if(c=='-') f=-f; for(;isdigit(c);c=getchar()) x=(x<<3)+(x<<1)+(c^48); x*=f; return; } template <typename T>void wr(T x) { if(x<0) putchar('-'),x=-x; if(x>9) wr(x/10); putchar(x%10^'0'); return; } const int maxn=1e5+100; int t,n,d1,d2;int h[maxn]; int abs1(int x){return x>0?x:-x;} bool check1(int h1,int h2){return abs1(h1-h2)<=d1;} bool check2(int h1,int h2,int h3){return h1>h2&&h2<h3&&abs1(h1-h3)<=d2;} int vis[maxn]; int main() { re(t); while(t--) { re(n),re(d1),re(d2); for(register int i=1;i<=n;++i)re(h[i]),vis[i]=0; if(n==1){puts("Yes");continue;} vis[1]=1;if(check1(h[1],h[2]))vis[2]=1; for(register int i=3;i<=n;++i) { if(vis[i-1]==0&&vis[i-2]==0)break; if(vis[i-1]&&check1(h[i-1],h[i])){vis[i]=1;continue;} if(vis[i-2]&&check2(h[i-2],h[i-1],h[i]))vis[i]=1; } if(vis[n])puts("Yes"); else puts("No"); } return 0; } /* 5 1 5 19 10 14 18 5 13 3 8 16 12 4 17 18 20 13 5 14 13 8 8 3 1 12 11 13 7 9 9 16 17 3 17 5 20 20 6 4 1 12 11 9 13 9 */
T2 Control
题意
给出一个有向图,定义:如果一个点能掌控一个点,那么他的所有儿子都能掌控这个点(有点像递归的定义),换句话说,这个点所引出的所有路径都必须能到达要被掌控的点
分析
从上面的题意转化,我们很简单的就能想到一个暴力思路,
点击查看代码
bool dfs(int x,int t)//判断x是否能掌控t { if(x==t)return 1; for(register int i=head[x];i;i=E[i].nex)if(!dfs(E[i].v,t))return 0; if(!head[x])return 0;//这个点没有儿子了 else return 1; }
正解
我们思考能否简化这张图,建立一个树形的关系结构可以直接形容控制与否的关系(一个点的直接父亲就是他能够控制的点),来通过树上差分或者是
建图
首先对于我们要加入的点,给出他的儿子节点,在之前构建的图的基础上面,满足题意的点只有给出的所有儿子的
统计答案
所以有了这个图,我们很清楚的知道对于任意两个询问中给出的点,答案就是他们到根节点
我们假定A节点是0号节点,我们现在要求C到H的答案,首先C的深度是3,H的深度是4,用C+H会重复统计的答案就是:他们的
现在拓展到三个点的情况:
点击查看代码
scanf("%d",&k); for(register int i=1;i<=k;i++)scanf("%d",&s[++top]); sort(s+1,s+top+1,cmp); int ans=0; while(top)ans+=dep[s[top]]-dep[LCA(s[top],s[top-1])],top--;
显而易见的是,最后一行代码就是最核心的地方,当然,从左到右按照
按照从左到右的顺序:
首先考虑
再考虑
同理考虑
最后考虑
用一张图来描述我们统计答案的过程就是这样的:
Code
点击查看代码
本文来自博客园,作者:Hanggoash,转载请注明原文链接:https://www.cnblogs.com/Hanggoash/p/16770329.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效