中国企业黄页企业名录大全网站seo博客
根据通过人数二分法练题,每日打卡。
1- 1427B
- 一组字符串 n n n个W x x x组连续W 得分 2 n − x 2n-x 2n−x
- 得分尽量高 就要增大 n n n 减小 x x x
- 所以要把W尽量连起来
老是wa2 202行错误 想不出来哪里没想到 决定先放一放
struct idx{int l,r;
};
void solve(){//1427Bint n,k;cin>>n>>k;string s;cin>>s;vector<idx>va;int w=0,wcnt=0,i=0,l=0;int fg=0;//去除开头的L 因为开头放W没有在后面放加的多while(i<n){if(s[i]=='W'){wcnt++;while(i<n&&s[i]=='W'){w++;i++;}fg=1;}if(!fg){i++;continue;}if(s[i]=='L'){l=i;while(i<n&&s[i]=='L')i++;if(i-l>0)va.push_back({l,i});}}// for(auto x:va){// cout<<x.l<<' '<<x.r<<endl;// }if(w+k>=n)return cout<<2*n-1<<endl,void();sort(va.begin(),va.end(),[&](idx x,idx y){return (x.r-x.l)<(y.r-y.l);});for(auto x:va){if(k<=0)break;int cg=x.r-x.l; if(x.r<n&&k>=cg)wcnt=max(wcnt-1,0ll);w+=min(k,cg);k-=cg;}if(k>0){if(w==0)wcnt++;w+=k;}cout<<2*w-wcnt<<endl;
}
2- 797B
水题
- 都是正的相加 和一定是子序列中最大的
- 如果这个最大的和是奇数 直接输出
- 不是奇数 看去除某个正数/加上某个负数 能不能成奇数 并找最大的和
void solve(){int n;cin>>n;vector<int>a(n+1);int sum=0;forr(i,1,n){cin>>a[i];if(a[i]>0)sum+=a[i];}if(sum%2)return cout<<sum<<endl,void();else{int ans=-1e4-10;forr(i,1,n){int ad=(a[i]>0?-a[i]:a[i]);if((ad+sum)%2){ans=max(ad+sum,ans);}}cout<<ans<<endl;}
}
3- 1103A
题很短 但愣是没看懂
意思是放长方形 0是竖的 1是横的
放满一行或一列就可以消除 然后空出来继续放
构造水题
- 尽量消除
- 竖的横的分着放 不会重叠
void solve(){string s;cin>>s;int r=0,c=0;for(auto i:s){if(i=='0'){cout<<"1 "<<(r+1)<<endl;r=(r+1)%4;}else {cout<<"4 "<<c+1<<endl;c=(c+2)%4;}}
}
4- 2045C 字符串处理
- ”有趣缩写“要求有来自s、t的非空子串两种组合,就说明要有一个字母c,s和t都有,这样要么是s提供c,要么是t提供c。
- 注意这个字母不能是s的开头或t的结尾,如果是的话不能保证 不提供c的 字符串 非空,那就只有一种组合,不有趣。
- 思路就是先找以每个字母结尾的s前缀、t后缀,再遍历每个字母,找能连接起的最短字符串。
一开始因为判定的时候,无穷大N选小了,一直wa16…蠢炸了
const int N=4e5+10;
void solve(){string s,t;vector<int>ss(27,N),tt(27,N);cin>>s>>t;int sl=s.size(),tl=t.size();forr(i,1,sl-1){if(ss[s[i]-'a']==N)ss[s[i]-'a']=i+1;}reforr(i,0,tl-2){// cout<<t[i]<<' ';if(tt[t[i]-'a']==N)tt[t[i]-'a']=tl-i;}int len=N;string ans="";for(int i=0;i<=25;i++){len=min(ss[i]+tt[i],len);}if(len==N)return cout<<-1<<endl,void();for(int i=0;i<=25;i++){if(len==ss[i]+tt[i]){string cp=s.substr(0,ss[i])+t.substr(tl-tt[i]+1);ans=cp;}}cout<<ans<<endl;
}
5- 297B 差分
水题
- 对称交换 所以只需要考虑一半
- 反转两次 就相当于没反转 不操作
- 反转单数次就要反转
- (别急 有反转
void solve(){string s;cin>>s;int len=s.size();s=" "+s;vector<int>cnt(len+2,0);int m;cin>>m;forr(i,1,m){int a;cin>>a;cnt[a]++;}int sum=0;//对称的 处理一半就行forr(i,1,len/2){sum+=cnt[i];// cout<<sum<<endl;if(sum%2==1){char tp=s[i];s[i]=s[len-i+1];s[len-i+1]=tp;// cout<<s<<endl;}}cout<<s<<endl;
}