Loading

序列自动机两题 51Nod2504 是子序列的个数 CodeForcesEDU81 Obtain The String

序列自动机是用于处理子序列问题的一种工具。其实现类似KMP,大致操作是建立一个Next数组,用于各自操作。

1.

51Nod 2504

给定一个字符串和若干个word,问有多少个word是该字符串的子序列。

注意建立Next时从1开始。

#pragma warning(disable:4996)

#include<iostream>
#include<algorithm>
#include<bitset>
#include<tuple>
#include<unordered_map>
#include<fstream>
#include<iomanip>
#include<string>
#include<cmath>
#include<cstring>
#include<vector>
#include<map>
#include<set>
#include<list>
#include<queue>
#include<stack>
#include<sstream>
#include<cstdio>
#include<ctime>
#include<cstdlib>
#define INF 0x3f3f3f3f
#define inf 0x7FFFFFFF
#define MOD 998244353
#define moD 1000000003
#define pii pair<int,string>
#define eps 1e-8
#define equals(a,b) (fabs(a-b)<eps)
#define bug puts("bug")
#define re  register
#define fi first
#define se second
const int maxn = 5e4 + 5;
const double Inf = 10000.0;
const double PI = acos(-1.0);
typedef  long long ll;
typedef unsigned long long ull;
using namespace std;

int Next[maxn][30];
char s[maxn];
char word[55];

int main() {
    scanf("%s", s + 1);
    int T;
    scanf("%d", &T);
    int n = strlen(s + 1);
    for (int i = n ;i; i--) {
        for (int j = 0; j < 26; j++) Next[i - 1][j] = Next[i][j];
        Next[i- 1][s[i] - 'a'] = i;
    }
    int cnt = 0;
    while (T--) {
        scanf("%s", word);
        int l = strlen(word);
        int count = 0; 
        int j = 0;
        for (int i = 0; i < l; i++) if (Next[j][word[i] - 'a']) j = Next[j][word[i] - 'a'], count++;
        if (count == l) cnt++;
    }
    printf("%d", cnt);
}
View Code

 

2.

Obtain the String

从一个空串要求变到字符串 t 。 变换规则是从a串中每次找一个子串添加到“空串”的末尾。

问最少的操作次数。

贪心的匹配子串即可。

#pragma warning(disable:4996)

#include<iostream>
#include<algorithm>
#include<bitset>
#include<tuple>
#include<unordered_map>
#include<fstream>
#include<iomanip>
#include<string>
#include<cmath>
#include<cstring>
#include<vector>
#include<map>
#include<set>
#include<list>
#include<queue>
#include<stack>
#include<sstream>
#include<cstdio>
#include<ctime>
#include<cstdlib>
#define INF 0x3f3f3f3f
#define inf 0x7FFFFFFF
#define MOD 998244353
#define moD 1000000003
#define pii pair<int,string>
#define eps 1e-8
#define equals(a,b) (fabs(a-b)<eps)
#define bug puts("bug")
#define re  register
#define fi first
#define se second
const int maxn = 1e5 + 5;
const double Inf = 10000.0;
const double PI = acos(-1.0);
typedef  long long ll;
typedef unsigned long long ull;
using namespace std;

int Next[maxn][30];
char s[maxn];
char word[maxn];

int main() {
    int T;
    scanf("%d", &T);
    while (T--) {
        memset(Next, 0, sizeof Next);
        scanf("%s %s", s + 1, word);
        int n = strlen(s + 1);
        int len = strlen(word);
        for (int i = n; i; i--) {
            for (int j = 0; j < 26; j++) Next[i - 1][j] = Next[i][j];
            Next[i - 1][s[i] - 'a'] = i;
        }
        int res = 0;
        int cnt = len;
        int last = 0;
        int f = 1;
        while (cnt) {
            res++;
            int j = 0;
            int tmp = last;
            for (int i = last; i < len; i++) {
                if (Next[j][word[i] - 'a']) j = Next[j][word[i] - 'a'], tmp++, cnt--;
                else break;
            }
            if (tmp == last) {
                puts("-1");
                f = 0;
                break;
            }
            last = tmp;
        }
        if (f) printf("%d\n", res);
    }
}
View Code

 

posted @ 2020-07-22 14:19  MQFLLY  阅读(187)  评论(0编辑  收藏  举报