2019安徽省程序設計競賽 I.你的名字(序列自動機)


這題和今年南昌邀請網絡預選賽M題很像啊,不過主串數量不是一個了

都是在主串中判斷子串是不是屬於主串的一個子序列

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;

const int maxn = 1000 + 5;
const int maxm = 30 + 5;
char s1[maxn], s2[maxm];
int Next[maxn][maxn][26], last[26], ans[maxn];
int n, m;
int main(){
    // freopen("in.txt", "r", stdin);    //輸入文件里最后一行后要加回車,不然會死循環
    scanf("%d%d", &n, &m);
    getchar();
    memset( ans, 0, sizeof(ans) );
    memset( Next, -1, sizeof(Next) );
    for( int i=0; i<n; i++ ){
        char ch, tot = 0;
        while( (ch=getchar())!='\n' ){
            if( ch>='A' && ch<='Z' ) ch += 'a'-'A';
            s1[++tot] = ch;
        }
        s1[++tot] = 0;
        memset( last, 0, sizeof(last) );
        for( int j=1; j<tot; j++ ){
            int id = s1[j]-'a';    
            for( int k=j-1; k>=last[id]; k-- ) Next[i][k][id] = j;    //Next數組存第i個主串k位置后第一個id字符所在的位置
            last[id] = j;
        }
    }
    for( int i=0; i<m; i++ ){        //輸入進來每個模式串
        char ch, tot=0;
        while( (ch=getchar())!='\n' ){
            if( ch>='A' && ch<='Z' ) ch += 'a'-'A';
            s2[tot++] = ch;
        }
        s2[tot] = 0;
        for( int j=0; j<n; j++ ){    //對每個主串進行匹配
            int pos = 0;
            bool ok = 1;
            for( int k=0; k<tot; k++ ){
                int id = s2[k]-'a';
                if( Next[j][pos][id]!=-1 ) pos = Next[j][pos][id];    //如果成功繼續匹配下一字符
                else{            //匹配不成功,即該字符在pos后沒有出現,則break
                    ok = 0;    
                    break;
                }
            }
            if( ok ) ans[j] ++;    //每個主串成功匹配一個模式串后價值數+1
        }
    }
    for( int i=0; i<n; i++ ) printf("%d\n", ans[i]);    //逐個輸出

    return 0;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM