Codeforces 1295C - Obtain The String
Posted stelayuri
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces 1295C - Obtain The String相关的知识,希望对你有一定的参考价值。
题目大意:
给定两个字符串s和t,你有一个空字符串z
每次可以取s的任意一个子序列加到z后面
问至少要取多少次才能让z等价于t
解题思路:
vector存s中26个字母的位置
然后t字符串从前往后一个个查找
用变量p记录查到上一个字符时在字符串s中的位置(初始化为-1)
如果在t内碰到一个字符,没有在s中出现过,输出-1结束当次程序
否则,看当前的p是否大于等于这个字符在s中出现的最后一个位置
如果是,说明这一次子序列已经不能往后面取了,说明得另起一次从头取子序列
ans++,让p等于当前字符在s中出现的第一个位置
如果不是二分找大于p的第一个这个字符的位置,让p等于这个位置即可
注意,ans初始化为1,vector要清空……
思路用到了一点点贪心,就是每次都是取上一次的位置后出现的第一个指定字符的位置
反正正常模拟肯定超时要二分优化,嗯!
1 #include<bits/stdc++.h> 2 using namespace std; 3 string s,t; 4 vector<int> v[26]; 5 int siz[26]; 6 inline int gid(char s){ 7 return s-‘a‘; 8 } 9 void solve(){ 10 cin>>s>>t; 11 memset(siz,0,sizeof siz); 12 int lens=s.size(),lent=t.size(),i,j,d,p=-1,pd,ans=1; 13 for(i=0;i<26;i++) 14 v[i].clear(); 15 for(i=0;i<lens;i++){ 16 d=gid(s[i]); 17 v[d].emplace_back(i); 18 siz[d]++; 19 } 20 for(i=0;i<lent;i++){ 21 d=gid(t[i]); 22 if(siz[d]==0){//这个字符没有出现过 23 cout<<"-1 "; 24 return; 25 } 26 if(p>=v[d][siz[d]-1]){//如果已经没法在剩下的位置中取这个字符了,得另起一次从头开始取子序列 27 ans++; 28 p=v[d][0]; 29 } 30 else{//否则,二分找大于p的第一个这个字符的位置 31 pd=upper_bound(v[d].begin(),v[d].end(),p)-v[d].begin(); 32 p=v[d][pd]; 33 } 34 } 35 cout<<ans<<‘ ‘; 36 } 37 int main(){ 38 ios::sync_with_stdio(0); 39 cin.tie(0);cout.tie(0); 40 int T;cin>>T;while(T--) 41 solve(); 42 43 return 0; 44 }
以上是关于Codeforces 1295C - Obtain The String的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces 1295C - Obtain The String
Codeforces 1294E Obtain a Permutation
Codeforces 1294E - Obtain a Permutation
[Codeforces #615 div3]1294E Obtain a Permutation