Educational Codeforces Round 78 题解
A题
水题,但是我做麻烦了,因为我不知道字符串内部也可以排序,学到一招
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<algorithm> using namespace std; const int N=1e5+10; const int inf=0x3f3f3f3f; int a[27],b[27]; int main(){ int t; cin>>t; while(t--){ string p; string s; cin>>p>>s; int i; int l1=s.size(); int l2=p.size(); int flag=0; if(l1<l2){ cout<<"NO"<<endl; continue; } for(i=0;i<l1-l2+1;i++){ memset(a,0,sizeof a); memset(b,0,sizeof b); flag=0; string tmp=s.substr(i,l2); int j; for(j=0;j<p.size();j++){ int sign=p[j]-'a'; a[sign]++; } for(j=0;j<tmp.size();j++){ int sign=tmp[j]-'a'; b[sign]++;} for(j=0;j<26;j++){ if(a[j]!=b[j]){ flag=1; break; }} if(flag==0){ cout<<"YES"<<endl; break; } } if(flag==1) cout<<"NO"<<endl; }}
B题
数学题
首先肯定是对差值进行计算,我们自然想要对小的那个一直加逼近大的,所以我们要求取前缀和
我们可以知道,知道前缀和和差值的奇偶性相同就行
因为这样两者相减就是偶数,而我们知道,无论这个差值是多少,我们都可以把他表述为前面若干数的和
这样只需要把前面若干的数给大的,就能抵消,我们注意到变化的数一定是偶数,因为假设我把3给大的,那么小的减3,大的加3,相差是两倍
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<algorithm> using namespace std; const int N=1e5+10; const int inf=0x3f3f3f3f; int main(){ int t; cin>>t; while(t--){ int s[N]={0}; int a,b; cin>>a>>b; if(a>b) swap(a,b); int sum=b-a; int i; for(i=1;i<N;i++){ s[i]=s[i-1]+i; } if(sum==0) cout<<0<<endl; else{ for(i=1;i<N;i++){ if(s[i]-sum>=0&&(s[i]-sum)%2==0){ cout<<i<<endl; break; } } } } }
C题
本题只要求取前缀和后缀互为相反数的情况中的最小值即可
本题必须要将2转化成-1,因为要使得两个种类的贡献相等才行
tip:利用map
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<algorithm> #include<map> using namespace std; const int N=2e5+10; const int inf=0x3f3f3f3f; int main(){ int t; cin>>t; while(t--){ int s[N]={0}; map<int,int> pos; int i; int n; cin>>n; pos[0]=0; for(i=1;i<=2*n;i++){ int a; cin>>a; if(a==2) a=-1; s[i]=s[i-1]+a; if(i<=n) pos[s[i]]=i; } int res=2*n; for(i=n;i<=2*n;i++){ auto it=pos.find(s[i]-s[2*n]); if(it!=pos.end()) res=min(res,i-it->second); } cout<<res<<endl; } }
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<algorithm> #include<map> using namespace std; const int N=2e5+10; const int inf=0x3f3f3f3f; int main(){ int t; cin>>t; while(t--){ int s[N]={0}; map<int,int> pos; int i; int n; cin>>n; pos[0]=0;//一定要注意初始化,也就是左边全吃完的位置是0 for(i=1;i<=2*n;i++){ int a; cin>>a; if(a==2)//因为两个贡献度相等,所以要相反数 a=-1; s[i]=s[i-1]+a; if(i<=n) //只有小于等于n才会记录下来 pos[s[i]]=i;//即使有重复的s[i],我们记录位置靠后的是更好的,所以不用担心覆盖 } int res=2*n; for(i=n;i<=2*n;i++){ auto it=pos.find(s[i]-s[2*n]); if(it!=pos.end()) res=min(res,i-it->second); } cout<<res<<endl; } }
没有人不辛苦,只有人不喊疼