题目
题目链接:
题意
从第一个字符串里面找子串拼成第二个字符串,求最少要多少个字串
思路
可以记录第一个式子的字母出现的字母,如果里面没有第二个式子里的字母即输出-1,后面求字串拼凑的时候,可以对s2求它在s1中的位置,如果他在s1中的位置都小于s2中的下标,就相当于从头开始重新找字符串。可以用upper_bound()查找第一个大于s2的坐标。
lower_bound(v.begin(),v.end(),a)找出vector里第一个大于等于a的值。
upper_bound(v.begin(),v.end(),a)找出vector里第一个大于a的值。
*此题不能用lower_bound ,否则a aaaa输出1
代码
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<cctype>
#include<ctime>
#include<iostream>
#include<string>
#include<map>
#include<queue>
#include<stack>
#include<set>
#include<vector>
#include<iomanip>
#include<list>
#include<bitset>
#include<sstream>
#include<fstream>
#include<complex>
#include<algorithm>
#if __cplusplus >= 201103L
#include <unordered_map>
#include <unordered_set>
#endif
#define ll long long
using namespace std;
const int INF = 0x3f3f3f3f;
vector<int> v[30];map<char,int> mp;
int main(){
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int t;
cin>>t;
while(t--){
string s1,s2;
cin>>s1>>s2;
for(int i=1;i<=26;i++) v[i].clear(),mp.clear();
int num=1;
for(int i=0;i<s1.size();i++){
if(mp[s1[i]]==0) {
mp[s1[i]]=num,num++;
}
v[mp[s1[i]]].push_back(i);
}
bool flag=0;
for(int i=0;i<s2.size();i++){
if(v[mp[s2[i]]].size()==0) {
flag=1;
}
}
if(flag) cout<<-1<<endl;
else{
int loc=-1,res=1;//注意loc从-1开始,不能从0开始
for(int i=0;i<s2.size();i++){
if(upper_bound(v[mp[s2[i]]].begin(),v[mp[s2[i]]].end(),loc)!=v[mp[s2[i]]].end()) loc=*upper_bound(v[mp[s2[i]]].begin(),v[mp[s2[i]]].end(),loc);
else{
loc=v[mp[s2[i]]][0];
if(i!=0) res++;
}
}
cout<<res<<endl;}
}
return 0;
}
来源:CSDN
作者:kosf_
链接:https://blog.csdn.net/kosf_/article/details/104136091