题目链接:http://codeforces.com/contest/1295/problem/C
题目:给定字符串s,t. 给定一个空串z,需要按照规则把z构造成
string z == string t 的字符串。
规则:有限次从s中任取子序列p,然后进行 string z += string p的操作,
s不变。
问能不能构造出p,不能输出-1,可以得话最少几次可以构造出。
大致的想法就是n倍的s字符串串联,然后剔除不必要的字符,就可以得出z,
求最少的倍数n是多少。
主要思路就是用二分去减少时间复杂度,应该是n = 1e5,
<O(n*log(n))。特判-1很简单。然后把s中‘a‘~‘z‘存在的字符下标都统计出来,
然后有一个flag表示当前位于s的哪一个位置,我们要充分利用s,所以二分出当前字符最接近flag的位置,
当然要>flag,如果找到了,那就更新flag的位置。如果找不到位置了,说明当前的s已经无用了,需要从新的s中找,
那么ans就要加1,flag就是第一个当前字符出现的位置,然后继续。
1 #include <iostream> 2 #include <algorithm> 3 #include <string> 4 #include <cstring> 5 #include <cstdio> 6 #include <vector> 7 using namespace std; 8 9 const int INF = (int)1e9; 10 11 struct info{ 12 vector<int> loc[30]; 13 string s; 14 int cnt,flag; 15 void init(){ 16 for(int i = 0; i < 26; ++i) loc[i].clear(); 17 cnt = 1; flag = -1; 18 } 19 //统计‘a‘~‘z‘的下标 20 void count(){ 21 int index,l = s.length(); 22 for(int i = 0; i < l; ++i){ 23 index = s[i]-‘a‘; 24 loc[index].push_back(i); 25 } 26 } 27 //特判 28 bool error(string& x){ 29 int index,l = x.length(); 30 for(int i = 0; i < l; ++i){ 31 index = x[i]-‘a‘; 32 if(loc[index].size()) continue; 33 return true; 34 } 35 return false; 36 } 37 void show(){ 38 39 for(int i = 0; i < 26; ++i){ 40 if(!loc[i].size()) continue; 41 cout << char(‘a‘+i) << endl; 42 for(int j = 0; j < loc[i].size(); ++j){ 43 cout << loc[i][j] << ‘ ‘; 44 }cout << endl; 45 } 46 } 47 void work(string& x){ 48 49 int index,l,r,mid,now; 50 int len = x.length(); 51 52 53 for(int i = 0; i < len; ++i){ 54 index = x[i]-‘a‘; 55 l = 0; r = loc[index].size()-1; 56 now = INF; 57 //二分找答案 58 while(l <= r){ 59 mid = (l+r) >> 1; 60 if(loc[index][mid] > flag){ 61 now = loc[index][mid]; 62 r = mid - 1; 63 }else l = mid + 1; 64 } 65 //找到答案,更新flag 66 if(now != INF) flag = now; 67 else{//没找到答案,答案加一 68 //flag为下一个s的该字符出现的第一个位置 69 flag = loc[index][0]; 70 ++cnt; 71 } 72 } 73 } 74 }S; 75 76 int main(){ 77 78 int T; 79 cin >> T; 80 while(T--){ 81 string t; 82 cin >> S.s >> t; 83 S.init(); 84 S.count(); 85 //S.show(); 86 if(S.error(t)){ 87 cout << -1 << endl; 88 }else{ 89 S.work(t); 90 cout << S.cnt << endl; 91 } 92 } 93 } 94 95 /* 96 99 97 aabce 98 ace 99 abacaba 100 aax 101 ty 102 yyt 103 aceaceace 104 aceaceaceace 105 aceaceace 106 acceae 107 108 */
原文地址:https://www.cnblogs.com/SSummerZzz/p/12246920.html
时间: 2024-11-10 01:09:59