winter week3 day3
2024牛客寒假算法基础集训营3
A智乃与瞩目狸猫、幸运水母、月宫龙虾
查看代码
#include<bits/stdc++.h> using namespace std; #define int long long //#define int __int128 #define double long double typedef pair<int,int>PII; typedef pair<string,int>PSI; typedef pair<string,string>PSS; const int N=100+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353; const int MAXN=1e8+5; const double eps=1e-12; const int dx[4]={-1,1,0,0}; const int dy[4]={0,0,-1,1}; void solve() { string a,b; cin>>a>>b; int c='a'-'A'; if(a[0]>='A'&&a[0]<='Z')a[0]+=c; if(b[0]>='A'&&b[0]<='Z')b[0]+=c; if(a[0]==b[0])cout<<"Yes\n"; else cout<<"No\n"; } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int t=1; cin>>t; while(t--){ solve(); } return 0; }
B智乃的数字手串
思路:好像说是直接判n奇偶就行,刚开始有猜过但是没敢这样写hh。
要求相邻数和为偶数才能操作,那把所有数分两类奇和偶。当奇偶交替出现,且有偶数个数时是败局。那就要尽可能消除连续的奇偶性相同的数,记要消除的总个数为a。
交换的话,若两个数奇偶相同,交换的话没有意义。若不同,枚举所有情况可发现最后的可操作相邻对数只会偶数倍增减,增减偶数次操作相当于结果没变,那就没必要交换。
消除完后剩下的数,判断是否需要再操作一次使得个数为偶,需要的话消除总个数再加一
最后在判断a的奇偶性即可
(qwq奇是qcjj啦
-----------
看了题解,还是考虑败局的情况,当长度为奇数时,一定是存在两个相邻数和为偶数的,那就直接判长度奇偶就可以了
查看代码
#include<bits/stdc++.h> using namespace std; #define int long long //#define int __int128 #define double long double typedef pair<int,int>PII; typedef pair<string,int>PSI; typedef pair<string,string>PSS; const int N=100+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353; const int MAXN=1e8+5; const double eps=1e-12; const int dx[4]={-1,1,0,0}; const int dy[4]={0,0,-1,1}; void solve() { int n,c=0; cin>>n; vector<int>ve(n); for(int i=0;i<n;++i){ cin>>ve[i]; if(i&&ve[i]==ve[i-1])c++; } if((n-c)%2)c++; if(c%2)cout<<"qcjj\n"; else cout<<"zn\n"; } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int t=1; cin>>t; while(t--){ solve(); } return 0; }
C 智乃的前缀、后缀、回文
思路:回文串要满足翻转后和原串相等,且需pres=suft,pret=sufs,那就在前后缀相等的串中找出所有前缀回文串,然后要pres和sufs不覆盖的话可以二分/双指针去求答案都可以。用字符串哈希判断是否为回文串,暴力试了发也过了qwq
查看代码
#include<bits/stdc++.h> using namespace std; #define int long long //#define int __int128 #define double long double typedef pair<int,int>PII; typedef pair<string,int>PSI; typedef pair<string,string>PSS; const int N=5e5+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353; const int MAXN=1e8+5; const double eps=1e-12; const int dx[4]={-1,1,0,0}; const int dy[4]={0,0,-1,1}; void solve() { int n,m; cin>>n>>m; string x,y; cin>>x>>y; std::reverse(x.begin(), x.end()); vector<int>pre(min(n,m)+5),suf(min(n,m)+5); string xx,yy,z; for(int i=0;i<min(n,m);++i){ xx.push_back(x[i]); yy.push_back(y[i]); z.insert(z.begin(),x[i]); if(xx!=yy)break; // string t=xx; // std::reverse(t.begin(), t.end()); if(z==xx)pre[i]=i+1; } xx.clear(),yy.clear(),z.clear(); std::reverse(x.begin(), x.end()); std::reverse(y.begin(), y.end()); for(int i=0;i<min(n,m);++i){ xx.push_back(x[i]); yy.push_back(y[i]); if(xx!=yy)break; // string t=xx; // std::reverse(t.begin(), t.end()); z.insert(z.begin(),x[i]); if(z==xx)suf[min(n,m)-i-1]=i+1; } int ans=-1; for(int i=1;i<min(n,m);++i){ pre[i]=max(pre[i-1],pre[i]); } for(int i=min(n,m)-2;i>=0;--i){ suf[i]=max(suf[i+1],suf[i]); } for(int i=0;i<min(n,m)-1;++i){ if(pre[i]>0&&suf[i+1]>0)ans=max(ans,pre[i]+suf[i+1]); } if(ans>0)cout<<2*ans; else cout<<-1; } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int t=1; // cin>>t; // init(); while(t--){ solve(); } return 0; }
查看代码
#include<bits/stdc++.h> using namespace std; #define int long long typedef unsigned long long ull; //#define int __int128 #define double long double typedef pair<int,int>PII; typedef pair<string,int>PSI; typedef pair<string,string>PSS; const int N=5e5+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353; const int MAXN=1e8+5; const double eps=1e-12; const int dx[4]={-1,1,0,0}; const int dy[4]={0,0,-1,1}; vector<int>h1,h2,p; int base=233; int n; bool check(int l,int r){ if(h1[r]-h1[l-1]*p[r-l+1]==h2[n-l+1]-h2[n-r+1-1]*p[r-l+1])return true; return false; } void solve() { int x,y; string a,b; cin>>x>>y>>a>>b; std::reverse(a.begin(), a.end()); string s=" "; for(int i=0;i<min(x,y);++i){ if(a[i]!=b[i])break; s.push_back(a[i]); n++; } h1=h2=p=vector<int>(n+5),(n+5),(n+5); p[0]=1; for(int i=1;i<=n;++i){ h1[i]=h1[i-1]*base+(ull)s[i]; h2[i]=h2[i-1]*base+(ull)s[n-i+1]; p[i]=p[i-1]*base; } vector<int>ans1,ans2; for(int i=1;i<=n;++i){ if(check(1,i))ans1.push_back(i); } s=" "; n=0; std::reverse(a.begin(), a.end()); std::reverse(b.begin(), b.end()); for(int i=0;i<min(x,y);++i){ if(a[i]!=b[i])break; s.push_back(a[i]); n++; } p=h2=h1=vector<int>(n+5,0); p[0]=1; for(int i=1;i<=n;++i){ h1[i]=h1[i-1]*base+(ull)s[i]; h2[i]=h2[i-1]*base+(ull)s[n-i+1]; p[i]=p[i-1]*base; } for(int i=n;i>=1;--i){ if(check(1,i))ans2.push_back(i); } if(ans1.empty()||ans2.empty()){ cout<<-1; return ; } int ans=-1; for(auto l:ans1){ int r=min(x,y)-l; auto it= lower_bound(ans2.begin(),ans2.end(),r,greater<int>()); if(it!=ans2.end())ans=max(ans,l+*it); else break; } if(ans==-1)cout<<ans; else cout<<2*ans; } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int t=1; // cin>>t; // init(); while(t--){ solve(); } return 0; }
Dchino's bubble sort and maximum subarray sum(easy version)
思路:k最大为2,那就狠狠暴力啦
查看代码
#include<bits/stdc++.h> using namespace std; #define int long long //#define int __int128 #define double long double typedef pair<int,int>PII; typedef pair<string,int>PSI; typedef pair<string,string>PSS; const int N=100+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353; const int MAXN=1e8+5; const double eps=1e-12; const int dx[4]={-1,1,0,0}; const int dy[4]={0,0,-1,1}; void solve() { int n,k; cin>>n>>k; vector<int>ve(n),s; for(int i=0;i<n;++i)cin>>ve[i]; s=ve; int ans=0; if(k==1){ for(int i=0;i<n-1;++i){ swap(ve[i],ve[i+1]); int x=0; for(int j=0,c=0;j<n;++j){ if(c+ve[j]>0)c+=ve[j]; else c=0; x=max(x,c); } ans=max(ans,x); ve=s; } }else{ int x=0; for(int i=0,c=0;i<n;++i){ if(c+ve[i]>0)c+=ve[i]; else c=0; x=max(x,c); } ans=max(ans,x); } if(ans==0){ int x=ve[0]; for(int i=1;i<n;++i)x=max(x,ve[i]); ans=x; } cout<<ans; } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int t=1; // cin>>t; while(t--){ solve(); } return 0; }
G智乃的比较函数(easy version)
思路:n最大为2,直接判就可以。
判断下给定条件的相反条件是否成立即可。
若x<y成立,那x>=y和y<x就不能成立
若x>=y成立,那x<y就不能成立
查看代码
#include<bits/stdc++.h> using namespace std; #define int long long //#define int __int128 #define double long double typedef pair<int,int>PII; typedef pair<string,int>PSI; typedef pair<string,string>PSS; const int N=100+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353; const int MAXN=1e8+5; const double eps=1e-12; const int dx[4]={-1,1,0,0}; const int dy[4]={0,0,-1,1}; void solve() { int n; cin>>n; bool ok=true; vector<vector<int>>ve(4,vector<int>(4)); for(int i=0;i<n;++i){ int x,y,z; cin>>x>>y>>z; if(x==y&&z==1)ok=false; if(x==y)continue; if(z==0)z=-1; if(z==-1){ if(ve[x][y]!=0&&ve[x][y]==1)ok=false; }else{ if(ve[y][x]!=0&&ve[y][x]==1)ok=false; if(ve[x][y]!=0&&ve[x][y]==-1)ok=false; } ve[x][y]=z; } if(ok)cout<<"Yes\n"; else cout<<"No\n"; } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int t=1; cin>>t; while(t--){ solve(); } return 0; }
H智乃的比较函数(normal version)
思路:n最大为50,但是点数只有3,还是判断所有的相反条件是否成立
若x<y成立,那x>=y和y<x就不能成立;有另一点z,x>=z&&z>=y、y<z&&z<x不能成立
若x>=y成立,那x<y就不能成立;有另一点z,x<z&&z<y不能成立
查看代码
#include<bits/stdc++.h> using namespace std; #define int long long //#define int __int128 #define double long double typedef pair<int,int>PII; typedef pair<string,int>PSI; typedef pair<string,string>PSS; const int N=100+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353; const int MAXN=1e8+5; const double eps=1e-12; const int dx[4]={-1,1,0,0}; const int dy[4]={0,0,-1,1}; struct E{ int x,y,z; }; void solve() { int n; cin>>n; bool ok=true; vector<E>g(n); vector<vector<int>>ve(4,vector<int>(4)); for(int i=0;i<n;++i) { cin >> g[i].x >> g[i].y >> g[i].z; int x,y,z; x=g[i].x,y=g[i].y,z=g[i].z; if(z==0)z=-1; ve[x][y]=z; } for(int i=0;i<n;++i){ int x,y,z; x=g[i].x,y=g[i].y,z=g[i].z; if(x==y&&z==1)ok=false; if(x==y)continue; if(z==0)z=-1; int zz=6-x-y; if(z==-1){ if(ve[x][y]==1)ok=false; if(ve[x][zz]==1&&ve[zz][y]==1)ok=false; }else{ if(ve[y][x]==1)ok=false; if(ve[x][y]==-1)ok=false; if(ve[x][zz]==-1&&ve[zz][y]==-1)ok=false; if(ve[y][zz]==1&&ve[zz][x]==1)ok=false; } // ve[x][y]=z; } if(ok)cout<<"Yes\n"; else cout<<"No\n"; } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int t=1; cin>>t; while(t--){ solve(); } return 0; }
J智乃的相亲活动
思路:期望=第i个人被选上的概率*1=(1-第i个人没有被选上的概率pi)*1
记bij为第i个人的第j个心动对象(相互心动),第j个心动对象有cnt[bij]个心动对象,那么pij为第j个心动对象不选i的概率,pij=(cnt[bij]-1)/cnt[bij],那么pi=pi1*pi2*...*pij...
查看代码
#include<bits/stdc++.h> using namespace std; #define int long long //#define int __int128 #define double long double typedef pair<int,int>PII; typedef pair<string,int>PSI; typedef pair<string,string>PSS; const int N=100+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353; const int MAXN=1e8+5; const double eps=1e-12; const int dx[4]={-1,1,0,0}; const int dy[4]={0,0,-1,1}; void solve() { int n,m,k; cin>>n>>m>>k; vector<vector<int>>ve(n+m+1); for(int i=0;i<k;++i){ int u,v; cin>>u>>v; v+=n; ve[u].push_back(v); ve[v].push_back(u); } double ans1=0,ans2=0; for(int i=1;i<=n;++i){ double s=1; for(auto v:ve[i]){ double c=ve[v].size(); s*=(c-1)/c; } ans1+=1-s; } for(int i=n+1;i<=n+m;++i){ double s=1; for(auto v:ve[i]){ double c=ve[v].size(); s*=(c-1)/c; } ans2+=1-s; } cout<<"float\n"; cout<<fixed<<setprecision(8)<<ans1<<' '<<ans2; } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int t=1; // cin>>t; while(t--){ solve(); } return 0; }
K智乃的“黑红树”
思路:构造的树为满二叉树时可以黑红节点数可以相差最大,当最后一层为黑时,a=2b+1;当最后一层为红时,b=2a;由此判断不可能构成红黑树的条件有a>2b+1和b>2a,还有当a为偶数或b为奇数时也不能构成。
若能构成,直接模拟黑红节点生成的红黑节点即可
查看代码
#include<bits/stdc++.h> using namespace std; #define int long long typedef unsigned long long ull; //#define int __int128 #define double long double typedef pair<int,int>PII; typedef pair<string,int>PSI; typedef pair<string,string>PSS; const int N=5e5+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353; const int MAXN=1e8+5; const double eps=1e-12; const int dx[4]={-1,1,0,0}; const int dy[4]={0,0,-1,1}; void solve() { int a,b; cin>>a>>b; if(b%2||a%2==0||a>2*b+1||b>2*a){ cout<<"No\n"; return ; } cout<<"Yes\n"; int n=a+b; vector<PII>ve(n+1,{-1,-1}); a--; int l=1,r=1,now=2; while(a||b){ for(int i=l;i<=r;++i){ if(!b)break; ve[i]={now,now+1}; now+=2,b-=2; } l=r+1,r=now-1; for(int i=l;i<=r;++i){ if(!a)break; ve[i]={now,now+1}; now+=2,a-=2; } l=r+1,r=now-1; } for(int i=1;i<=n;++i)cout<<ve[i].first<<' '<<ve[i].second<<'\n'; } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int t=1; cin>>t; // init(); while(t--){ solve(); } return 0; }
L智乃的36倍数(easy version)
思路:这个数据范围,当然先暴力
查看代码
#include<bits/stdc++.h> using namespace std; #define int long long //#define int __int128 #define double long double typedef pair<int,int>PII; typedef pair<string,int>PSI; typedef pair<string,string>PSS; const int N=100+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353; const int MAXN=1e8+5; const double eps=1e-12; const int dx[4]={-1,1,0,0}; const int dy[4]={0,0,-1,1}; void solve() { int n; cin>>n; vector<string>ve(n); int ans=0; for(int i=0;i<n;++i)cin>>ve[i]; for(int i=0;i<n;++i){ for(int j=0;j<n;++j){ if(i==j)continue; string c=ve[i]+ve[j]; int cc= stoi(c); if(cc%36==0)ans++; } } cout<<ans; } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int t=1; // cin>>t; while(t--){ solve(); } return 0; }
M 智乃的36倍数(normal version)
思路:
酱酱,看完这些公式应该就比较好想了,记cnt[v]为v的位数,要找到f(x,y)%36==0,其实就是(x*10cnt[y]+y)%36==0,由上面的公式推得(x*10cnt[y]%36+y%36)%36==0,简化为(a+b)%36==0
可以预处理出f[i][j]表示乘上10j后对36取模为i的数的个数,那么对于每个y,可以直接求出b和a的个数,统计总的a的个数即为答案
查看代码
#include<bits/stdc++.h> using namespace std; #define int long long //#define int __int128 #define double long double typedef pair<int,int>PII; typedef pair<string,int>PSI; typedef pair<string,string>PSS; const int N=100+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353; const int MAXN=1e8+5; const double eps=1e-12; const int dx[4]={-1,1,0,0}; const int dy[4]={0,0,-1,1}; void solve() { int n; cin>>n; vector<int>ve(n); for(int i=0;i<n;++i)cin>>ve[i]; vector<vector<int>>f(40,vector<int>(25)); vector<int>g(30); g[0]=1; for(int i=1;i<=20;++i)g[i]=g[i-1]*10%36; for(int j=0;j<n;++j){ for(int i=0;i<=19;++i){ int x=((ve[j]%36)*g[i])%36; f[x][i]++; } } int ans=0; auto P=[](int x){ int c=0; while(x){ c++,x/=10; } return c; }; for(int i=0;i<n;++i){ int c=(36-ve[i]%36)%36; int cnt=P(ve[i]); int x=(((ve[i]%36)*g[cnt])%36+ve[i]%36)%36; if(x==0)ans--; ans+=f[c][cnt]; } cout<<ans; } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int t=1; // cin>>t; while(t--){ solve(); } return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现