1.暴力 10/12
#include <bits/stdc++.h>
using namespace std;
int n;
string a[10005];
int main()
{cin >> n;for (int i = 0; i < n; i++)cin >> a[i];string ll;cin >> ll;for (int i = 0; i < n; i++){string u = a[i];int num = 0;int j = 0;for (int k = 0; k < ll.size(); k++){if (ll[k] == a[i][j]){num++;j++;}}if (num == a[i].size()){cout << "YES" << endl;}elsecout << "NO" << endl;}
}
2.记录每个字母(共26个)的位置下标,并分别存在各自的字母下标数组中(例:a数组:1 3 5;b数组:2 6)
找一个字母的位置,即在此字母的下标数组中找(靠近左边的)&&(>前一个字母下标的数字)
(即若单词为bab,则先找b数组中最左侧位置2,再找a数组中>2&&最左侧的数字3,再找b数组中>3&&最左侧的数字6。如果都能找到位置,则说明此单词在歌词中)
#include <bits/stdc++.h>
using namespace std;
const int N = 1e4 + 10;
int n, l, r, mid, ans;
string a[N], ll;
vector<int> abc[27]; // 字母下标数组
int main()
{cin >> n;for (int i = 1; i <= n; i++)cin >> a[i];string ll;cin >> ll;for (int i = 0; i < ll.size(); i++)abc[ll[i] - 'a'].push_back(i); // 在各字母表中记录位置下标for (int i = 1; i <= n; i++){int len = a[i].size(), now = -1; // now记录此时字母的位置应在now右侧int flag = 1;for (int j = 0; j < len; j++){l = 0, r = abc[a[i][j] - 'a'].size() - 1, ans = -1; // 二分字母下标数组。找字母下标while (l <= r){mid = (l + r) / 2;if (abc[a[i][j] - 'a'][mid] > now){r = mid - 1, ans = mid;}elsel = mid + 1;}if (ans == -1)//不能找到一个位置使此单词的某一字母在歌词中{flag = 0;break;}now = abc[a[i][j] - 'a'][ans];//now更新为此字母当前位置,下一字母的位置应在now之后}if (flag){cout << "YES" << endl;}elsecout << "NO" << endl;}
}