[stl] cf div2 1295C

时光总嘲笑我的痴心妄想 提交于 2020-02-01 20:17:26

题目

题目链接:

题意

从第一个字符串里面找子串拼成第二个字符串,求最少要多少个字串

思路

可以记录第一个式子的字母出现的字母,如果里面没有第二个式子里的字母即输出-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;
}

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!