CF1808C Unlucky Numbers 题解
可以证明答案是 或 的一段前缀,拼上后面全部相同的一段字符 ,证明方式类似数位 dp。能够自由填的数字一定是相等的,这样不会影响幸运值。前面那些不能自由填写的,就是 或 的一段前缀。假如不是 或 的一段前缀,必然填写相等的更好,而这种情况已经被考虑到了。
枚举前缀长度,枚举修改成的字符 ,复杂度 ,字符集大小为 。
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<vector> #define siz(x) int((x).size()) #define all(x) std::begin(x),std::end(x) using std::cin;using std::cout; using std::max;using std::min; using loli=long long; int n; loli l,r; std::vector<int>b1,b2,t,ans; int calc(std::vector<int>b){ reverse(all(b)); while(!b.empty()&&!b.back())b.pop_back(); return *max_element(all(b))-*min_element(all(b)); } signed main(){ // freopen(".in","r",stdin); // freopen(".out","w",stdout); std::ios::sync_with_stdio(false);cin.tie(nullptr); int T;cin>>T;while(T--){ cin>>l>>r; b1.clear();b2.clear(); ans.clear(); for(;l;l/=10)b1.push_back(int(l%10)); for(;r;r/=10)b2.push_back(int(r%10)); n=max(siz(b1),siz(b2)); while(siz(b1)<n)b1.push_back(0); while(siz(b2)<n)b2.push_back(0); reverse(all(b1));reverse(all(b2)); for(int k=0;k<=n;k++)for(int d=0;d<=9;d++){ t=b1; for(int j=k;j<n;j++)t[j]=d; if(b1<=t&&t<=b2&&(ans.empty()||calc(t)<calc(ans))) ans=move(t); } for(int k=0;k<=n;k++)for(int d=0;d<=9;d++){ t=b2; for(int j=k;j<n;j++)t[j]=d; if(b1<=t&&t<=b2&&(ans.empty()||calc(t)<calc(ans))) ans=move(t); } reverse(all(ans)); while(!ans.empty()&&!ans.back())ans.pop_back(); reverse(all(ans)); for(int i:ans)cout<<i; cout<<'\n'; } return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】