[题解]Refact.ai Match 1 (Codeforces Round 985) A~C
A - Set
显然答案是\(\max(\lfloor\frac{r}{k}\rfloor-l+1,0)\)。
点击查看代码
#include<bits/stdc++.h> #define int long long using namespace std; int t,l,r,k; signed main(){ cin>>t; while(t--){ cin>>l>>r>>k; cout<<max(0ll,r/k-l+1)<<"\n"; } return 0; }
B - Replacement
我们发现只要\(0\)和\(1\)各存在至少\(1\)个,操作就能进行下去。所以\(r_i=1\)的操作可以看做删掉一个\(0\),\(r_i=0\)的操作则可以看做删掉一个\(1\)。
这样模拟就可以了,每次操作前如果剩余\(0,1\)的个数存在\(0\)则答案是NO
。
点击查看代码
#include<bits/stdc++.h> using namespace std; int t,n; string s,r; int main(){ cin>>t; while(t--){ cin>>n>>s>>r; int cnt0=0,cnt1=0; bool f=1; for(char i:s) (i=='0'?cnt0:cnt1)++; for(char i:r){ if(!cnt0||!cnt1){ f=0; break; } (i=='0'?cnt1:cnt0)--; } cout<<(f?"YES\n":"NO\n"); } return 0; }
另一种做法很简单,如果\(s[1,n]\)中\(1\)的个数减去\(r[1,n-2]\)中\(0\)的个数为\(1\),答案就是YES
,否则NO
。原理差不多,目的是让执行最后一次操作前,序列中恰好有一个\(0\)和一个\(1\)。
点击查看代码
#include<bits/stdc++.h> using namespace std; int t,n; string s,r; int main(){ cin>>t; while(t--){ cin>>n>>s>>r; r.pop_back(); int cnts=0,cntr=0; for(int i:s) cnts+=(i=='1'); for(int i:r) cntr+=(i=='0'); if(cnts-cntr==1) cout<<"YES\n"; else cout<<"NO\n"; } return 0; }
C - New Rating
二分解法
考虑二分答案\(x\),转为判断“是否能让最终得分\(\ge x\)”。
用\(f[i]\)表示参加第\(i\)场比赛之后的得分;\(g[i]\)表示\(i\)这场比赛前可能的最小得分,使得最终得分\(\ge x\)。\(f\)可以通过模拟求出,\(g\)可以用下面的方法求得:
只要存在区间\(l\le r\),使得\(f[l-1]\ge g[r+1]\),则说明我们可以让最终得分\(\ge x\)。
时间复杂度\(O(n\log n)\)。
点击查看代码
#include<bits/stdc++.h> #define N 300010 using namespace std; int t,n,a[N],f[N]; bool check(int x){ int g=x; for(int i=n;i>=1;i--){ if(f[i-1]>=g) return 1; if(a[i]>=g) g--; else g++; } return 0; } int main(){ cin>>t; while(t--){ cin>>n; int cur=0; for(int i=1;i<=n;i++){ cin>>a[i]; if(a[i]>cur) cur++; else if(a[i]<cur) cur--; f[i]=max(f[i-1],cur); } int l=0,r=n; while(l<r){ int mid=(l+r+1)>>1; if(check(mid)) l=mid; else r=mid-1; } cout<<l<<"\n"; } }
DP解法
\(f[i][j\in[0,2]]\)来表示考虑前\(i\)个比赛,第\(i\)场的状态是\(j\)的答案。其中\(j=0,1,2\)分别表示在跳过的比赛之前、属于跳过的比赛、在跳过的比赛之后。则
转移可以滚掉第\(1\)维。最终答案就是\(\max(f[n][1],f[n][2])\)。
时间复杂度\(O(n)\)。
点击查看代码
#include<bits/stdc++.h> #define int long long #define N 300010 using namespace std; int t,n,a[N],f[3]; int g(int a,int b){return a+(b>a)-(b<a);} signed main(){ cin>>t; while(t--){ cin>>n; for(int i=1;i<=n;i++) cin>>a[i]; f[0]=0,f[1]=f[2]=INT_MIN; for(int i=1;i<=n;i++){ f[2]=max(g(f[1],a[i]),g(f[2],a[i])); f[1]=max(f[1],f[0]); f[0]=g(f[0],a[i]); } cout<<max(f[1],f[2])<<"\n"; } return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效