CF1851 部分题解
2023-07-30 19:35:02
前言
因为我实在是太菜了,没时间也不会做最后两题,所以这里只有前
之后我有时间看了后两题的题解再来更新吧~
A
先不用看那么多七七八八的,搞清楚下面几点即可:
- 高度不能相同。
- 高度差得被整除。
- 高度差不能太大。
好了,然后就可以 了。
int T,n,m,k,H,tot; int main(){ T=read(); while(T--){ n=read(),m=read(),k=read(),H=read(),tot=0; for(int i=1;i<=n;i++){ int h=abs(H-read()); if(h!=0&&h%k==0&&h/k<m)tot++; } printf("%d\n",tot); } }
B
题意
给定序列,可以交换奇偶性相同的数字,问你最后可不可以交换成单调不降序列。
因为奇偶性不同是不可能换到位置相同的,即每个位置的奇偶性是固定的,只要在不改变位置奇偶性的状态下可以任意交换的,所以我们只需要保留序号排个序然后看排序之后自己原来位置填的是否是奇偶性相同的即可。
typedef pair<int,int> PII; int T,n,b[200005]; PII a[200005]; bool check(){ for(int i=1;i<=n;i++)if((a[i].first&1)^(b[i]&1))return 0; return 1; } int main(){ T=read(); while(T--){ n=read(); for(int i=1;i<=n;i++){ a[i].first=read(); a[i].second=i; b[i]=a[i].first; } sort(a+1,a+1+n); if(check())puts("YES"); else puts("NO"); } }
C
题意
你可以按顺序取出包含若干个色块的序列,序列必须包含第一块和最后一块,然后将其分割成若干个数量均为
我们从第一块和最后一块必须选入手,实际上我们也只需要考虑最前一段和最后一段是否能顺序凑到
因为无论中间如何选,最后选出的序列必然包含首尾段,所以我们实际上可以忽略中间的部分,用两个指针分别从前往后和从后往前扫一遍,判断前面和后面的段是否可以有超过
注意一些特判,比如当首尾颜色相同时只需要一段连起来即可。
int T,n,c[200005],k; bool check(){ int l,r,tl=0,tr=0; for(r=1;r<=n;r++){ if(c[r]==c[1])tr++; if(tr==k)break; } if(tr<k)return 0; for(l=n;l;--l){ if(c[l]==c[n])tl++; if(tl==k)break; } if(tl<k)return 0; if(c[1]==c[n])return 1; if(r>l)return 0; return 1; } int main(){ T=read(); while(T--){ n=read(),k=read(); for(int i=1;i<=n;i++){ c[i]=read(); } if(check())puts("YES"); else puts("NO"); } }
D
题意
给你一个前缀和数组,但是缺少了一个数值,问原数组能否是
思路
首先遇到前缀和数组当然得先给它差分一下得到一个序列了,我们看到样例
那其他情况呢?在差分之后我们会发现
相应的,当少的数超过两个或者不正常的数不止一个,那么就不可能组成一个排列。
细节很多,结合代码理解更佳。
int T,n; ll a[200005]; bool pd[200005]; bool check(){ ll los1=0,los2=0,mor=0;//los 少的数,mor是不正常的数 for(int i=n-1;i;--i){ a[i]-=a[i-1]; if(a[i]>n||pd[a[i]]){ if(mor)return 0;//不止一个不正常 mor=a[i]; continue; } pd[a[i]]=1; } for(int i=1;i<=n;i++){ if(!pd[i]){ if(!los1)los1=i; else if(!los2)los2=i; else return 0;//少的不止两个 } } if(!los2&&!mor)return 1;//少的是最后一个值的情况 if(los1+los2!=mor)return 0;//不相同也不行 return 1; } int main(){ T=read(); while(T--){ n=read(); for(int i=1;i<n;i++){ a[i]=read(); pd[i]=0; } pd[n]=0; if(check())puts("YES"); else puts("NO"); } }
E
第一眼以为是连边跑个最短路,没想到比跑最短路还简单。
由于一种魔药可以由其他的药合成,而且没有自己到的自己的方法,显然是个 DAG,可以用拓扑序一个个搞,但是我懒得打,直接跑个记搜即可。
关注到有无限的魔药,赋值为
int T,n,k,a[200005]; ll f[200005]; vector<int>F[200005]; ll dfs(int x){ if(f[x]!=-1)return f[x]; ll ans=0; for(int y:F[x]){ ans+=dfs(y); } return f[x]=min(ans,1ll*a[x]); } int main(){ T=read(); while(T--){ n=read(),k=read(); for(int i=1;i<=n;i++){ a[i]=read(); f[i]=-1; F[i].clear(); } for(int i=1;i<=k;i++){ int p=read(); a[p]=0; f[p]=0; } for(int i=1;i<=n;i++){ int m=read(); for(int j=1;j<=m;j++){ int u=read(); if(!a[i])continue; F[i].push_back(u); } if(!m)f[i]=a[i]; } for(int i=1;i<=n;i++){ printf("%lld ",dfs(i)); } puts(""); } }
本文作者:NBest
本文链接:https://www.cnblogs.com/NBest/p/17686898.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步