I.重生之zbk要拿回属于他的一切(签到,没啥好说的)
#include<bits/stdc++.h> #define int long long #define endl '\n' using namespace std; const int N=1e6+10,mod=998244353; int h[N],e[N],ne[N],idx; int a[N],b[N],w[N]; map<int,int>mp; int n,m,q; vector<pair<int,int> >v[N]; void add(int a,int b){e[idx]=b,ne[idx]=h[a],h[a]=idx++;} void solve(){ cin>>n; string s;cin>>s; int ans=0; for(int i=0;i<s.size();i++){ string ss=s.substr(i,5); if(ss=="chuan")ans++; } cout<<ans<<endl; } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int _; _=1; //cin>>_; while(_--)solve(); return 0; }
A.国际旅行(签到,但是被骗了一会儿想复杂了,无用代码已注释)
![]()
#include<bits/stdc++.h> #define int long long #define endl '\n' using namespace std; const int N=1e6+10,mod=998244353; int h[N],e[N],ne[N],idx; int a[N],b[N],w[N]; map<int,int>mp; int n,m,q; vector<pair<int,int> >v[N]; void add(int a,int b){e[idx]=b,ne[idx]=h[a],h[a]=idx++;} void solve(){ cin>>n>>m>>q; for(int i=1;i<=n;i++){ int x;cin>>x; //a[i]=x; b[i]=x; } sort(b+1,b+1+n); while(q--){ int k;cin>>k; cout<<b[k]<<endl; } } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int _; _=1; //cin>>_; while(_--)solve(); return 0; }
F. 水灵灵的小学弟(签到,没啥含金量,要真是博弈论还算一个正常题)
#include<bits/stdc++.h> #define int long long #define endl '\n' using namespace std; const int N=1e6+10,mod=998244353; int h[N],e[N],ne[N],idx; int a[N],b[N],w[N]; map<int,int>mp; int n,m,q; vector<pair<int,int> >v[N]; void add(int a,int b){e[idx]=b,ne[idx]=h[a],h[a]=idx++;} void solve(){ cin>>n>>m; cout<<"DHY"<<endl; } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int _; //_=1; cin>>_; while(_--)solve(); return 0; }
J.这是签到(简单,打表暴力或硬推到5阶行列式计算都行,我直接套板子了)
#include<bits/stdc++.h> #define int long long #define endl '\n' using namespace std; const int N=1e6+10,mod=998244353; int h[N],e[N],ne[N],idx; int n,m,q; map<string,set<string> >mp;//名字 set<string>se,temp; map<string,int>mp1; int g[10][10],a[10][10]; void add(int a,int b){e[idx]=b,ne[idx]=h[a],h[a]=idx++;} int det(int nn) { int res = 1; for (int i = 1; i <= nn; ++i) { for (int j = i + 1; j <= nn; ++j) { while (g[j][i]) { int div = g[i][i] / g[j][i]; for (int k = i; k <= nn ; ++k) { g[i][k] = (g[i][k] - div * g[j][k] ); swap(g[i][k], g[j][k]); } res*=-1; } } res = res * g[i][i]; } return res; } void solve(){ cin>>n>>m; for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)cin>>a[i][j]; int ans=0x3f3f3f3f; if(m!=n)ans=0; for(int k=1;k<=min(n,m);k++){ for(int i=1;i<=k;i++){ for(int j=1;j<=k;j++){ g[i][j]=a[i][j]; } } ans=min(ans,det(k)); } cout<<ans<<endl; } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int _; _=1; while(_--)solve(); return 0; }
H.狼狼的备忘录(简单,stl应用,嵌套常数太大平时用的不太多,但赛时这么写一大堆出来ac还是很有成就感的,数据范围很小,所以可以随便瞎搞)
#include<bits/stdc++.h> #define int long long #define endl '\n' using namespace std; const int N=1e6+10,mod=998244353; int h[N],e[N],ne[N],idx; int n,m,q; map<string,set<string> >mp;//名字 set<string>se,temp; map<string,int>mp1; int g[10][10]; void add(int a,int b){e[idx]=b,ne[idx]=h[a],h[a]=idx++;} void solve(){ cin>>n; while(n--){ string s;cin>>s; se.insert(s); int cnt;cin>>cnt; for(int i=0;i<cnt;i++){ string ss;cin>>ss; mp[s].insert(ss); } } for(auto it=se.begin();it!=se.end();it++){ for(auto itt=mp[*it].begin();itt!=mp[*it].end();itt++){ for(auto ittt=mp[*it].begin();ittt!=mp[*it].end();ittt++){ string ss=*itt,sss=*ittt; if(ss!=sss){ if(sss.size()>ss.size()){ string ssss=sss.substr(sss.size()-ss.size()); if(ssss==ss){ mp1[ss]=1; } } } } } temp.clear(); for(auto itt=mp[*it].begin();itt!=mp[*it].end();itt++){ if(!mp1[*itt])temp.insert(*itt); } mp[*it]=temp; mp1.clear(); } int ans=0; for(auto it=se.begin();it!=se.end();it++)ans++; cout<<ans<<endl; for(auto it=se.begin();it!=se.end();it++){ cout<<*it<<' '; cout<<mp[*it].size()<<' '; for(auto itt=mp[*it].begin();itt!=mp[*it].end();itt++){ cout<<*itt<<' '; } cout<<endl; } } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int _; _=1; //cin>>_; while(_--)solve(); return 0; }
E.好字符(中等,找循环同构把一个字符串复制加到原来的后面循环遍历长度即可,本题关键在26个字母,在a中出现过的可以标记一下,然后遍历这些标记的字符,每次遍历时,把字符串a和b除这个字符外其他无关字符统一标记为一个特殊字符,再判断b是否能成为a的子串,用kmp即可,ps:题解中提到的字符串最小表示法没听说过,但朋友赛时就是用这个方法做出来了,我到洛谷一看是道蓝题板子,学会了再来分享给大家)
#include<bits/stdc++.h> #define int long long #define endl '\n' using namespace std; const int N=1e6+10,mod=998244353; int n,m,q; int ans=0; map<char,int>mp,mp1,mp2; int ne[2*N]; void solve(){ cin>>n; string aa,bb;cin>>aa>>bb; for(int i=0;i<n;i++)if(!mp[aa[i]])mp[aa[i]]=1; aa=" "+aa+aa,bb=" "+bb; string a,b; for(int i=0;i<26;i++){ if(mp[char('a'+i)]){ a=aa; b=bb; for(int j=1;j<=2*n;j++)if(a[j]!=char('a'+i))a[j]='.'; for(int j=1;j<=n;j++)if(b[j]!=char('a'+i))b[j]='.'; for(int j=2,k=0;j<=n;j++){//i指针遍历模式串,j指针指向待匹配串 while(k&&b[k+1]!=b[j])k=ne[k];//匹配失败,j指针回退 if(b[j]==b[k+1])k++;//如果匹配成功,j指针后移一位,此时i与j指针指向的字符相同 ne[j]=k;//那么此时在匹配串中,模式串中以i为下标的字符最长前缀最后一位下标为j } for(int j=1,k=0;j<=2*n;j++){ while(k&&b[k+1]!=a[j])k=ne[k];//回退 if(b[k+1]==a[j])k++; if(k==n){ ans++; break; } } } } cout<<ans<<endl; } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int _; _=1; while(_--)solve(); return 0; }
D.A*BBBB(中等,题目都说了有特殊性质&python高精都过不了当然不可能套c++高精的板子啦!yysy赛时我开的第一道题就是这个想用高精&int128混过去首wa一发,看到某队1min过这题直到比赛结束后我都仍在怀疑人生,很明显有我不知道的科技or板子能把这题水过去(FFT),言归正传,注意到b的每一位都相同,假设xx=b[0]-'0',b长度为m,xx与a的每一位相乘得到的结果相同记为C,最终答案是C向前偏移m位相加的结果,手动模拟一下即可知道,用前缀和维护每一位相加的结果)
#include<bits/stdc++.h> #define int long long #define ll long long #define endl '\n' #define pb push_back using namespace std; const ll N=2e6+10; int s[N]; ll n,m; vector<int> mul(vector<int> &A, int b) { vector<int> C; int t = 0; for (int i = 0; i < A.size() || t; i ++ ) { if (i < A.size()) t += A[i] * b; C.push_back(t % 10); t /= 10; } while (C.size() > 1 && C.back() == 0) C.pop_back(); return C; } void solve(){ string a,b;cin>>a>>b; if(a[0]=='0'||b[0]=='0'){ cout<<0<<endl; return; } vector<int>A; for(int i=a.size()-1;i>=0;i--)A.pb(a[i]-'0'); int xx=b[0]-'0'; auto C=mul(A,xx); vector<int>ans; reverse(C.begin(),C.end()); C.pb(0); reverse(C.begin(),C.end()); int rem=0; n=C.size()-1,m=b.size(); for(int i=1;i<=n;i++)s[i]=s[i-1]+C[i]; for(int i=1;i<n+m;i++){ int l=max(0ll,i-m),r=min(n,i); int x=rem+s[r]-s[l]; ans.pb(x%10); rem=x/10; } while(rem){ ans.pb(rem%10); rem/=10; } for(int i=ans.size()-1;i>=0;i--)cout<<ans[i]; cout<<endl; } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); ll _; _=1; cin>>_; while(_--)solve(); return 0; }
C.小w和大W的决斗(中等,算是博弈论板子题吧,sg函数基本上差不多)
#include<bits/stdc++.h> using namespace std; const int N=110; int n,f[N]; int sg(int x){ if(f[x]!=-1)return f[x]; unordered_set<int> S; for(int i=1;i<=x;i++)S.insert(sg(x-i)); for(int i=1;i<=x;i++){ for(int j=1;j<=x;j++){ if(i+j<x){ S.insert(sg(i)^sg(j)^sg(x-i-j)); } } } for(int i=0;;i++){ if(!S.count(i)){ return f[x]=i; } } } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); cin>>n; int res=0; memset(f,-1,sizeof f); for(int i=0;i<n;i++){ int x;cin>>x; res^=sg(x); } if(res)cout<<"w win\n"; else cout<<"W win\n"; return 0; }
总结:感觉还是有进步,这篇题解拖了比较久是因为补题时自己独立做的,遇到很多坑点,中途还补足了很多缺少的前置知识,题目难度适中,本蒟蒻每场大概出5~6题,赛后可以补1~3题,继续加油,没补完的后续会加上题解