CF1295C Obtain The String+STL+二分+贪心

字符串长度最长1e5,暴力模拟N*M必T
中途还试了 string 类 find()函数,一样T
直接上思路:
预处理S字符串,将所有字母出现位置和次数记录下来,遍历T字符串,直接贪心二分查找,是否合法。懂了就挺简单
上代码

#include<bits/stdc++.h>
using namespace std;
vector<int > pos[30];//记录字母出现位置
int num[30];//记录字母出现次数
int main()
{
 int T;
 cin>>T;
   while(T--)
  {
  	memset(num,0,sizeof(num));
  	for(int i=0;i<26;i++)
  	pos[i].clear();//不要忘记清空vector和num
  	string s,t;
  	cin>>s>>t;
  	for(int i=0;i<s.size();i++)
  	{ 
   		pos[s[i]-'a'].push_back(i);//队列写多了用了一次push
   		num[s[i]-'a']++;
  	}
   	int ans=1;
        int p=-1;
    	for(int i=0;i<t.size();i++)
    	{
      		if(!num[t[i]-'a'])//不存在此字母 
      		{
        		ans=-1;
       	 		break;
        	 }
     		if(p>=pos[t[i]-'a'][num[t[i]-'a']-1])//如果当前指针大于或者等于字符 t[i]出现最大位置 重置p指针 ans++; 
     		{
    
      		 p=pos[t[i]-'a'][0];//p指针指向t[i]第一次出现的位置
       		 ans++; 
      		}
      		else//找到第一个比p指针大或者相等 的位置 
      		{
       		int temp=upper_bound(pos[t[i]-'a'].begin(),pos[t[i]-'a'].end(),p)-pos[t[i]-'a'].begin();
      		 p=pos[t[i]-'a'][temp];
      		}
  	}
  		cout<<ans<<endl;
   }
 return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值