這題和今年南昌邀請網絡預選賽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; }