[Luogu P2536] [BZOJ 1966] [AHOI2005]病毒檢測
洛谷傳送門
BZOJ傳送門
題目描述
科學家們在Samuel星球上的探險仍在繼續。非常幸運的,在Samuel星球的南極附近,探險機器人發現了一個巨大的冰湖!機器人在這個冰湖中搜集到了許多RNA片段運回了實驗基地。
科學家們經過幾個晝夜的研究,發現這些RNA片段中有許多是未知的病毒!
每個RNA片段都是由A
、C
、T
、G
組成的序列。科學家們也總結出了Samuel星球上的“病毒模版片段”。一個模版片段是由A、C、T、G的序列加上萬用字元 *
和 ?
來表示。其中 *
的意思是可以匹配上
個或任意多個字元,而 ?
的意思是匹配上任意一個字母。
如果一個RNA片段能夠和“病毒模版片段”相匹配,那麼這個RNA片段就是未知的病毒。
例如,假設“病毒模版片段”為A*G?C
。RNA片段:AGTC
,AGTGTC
都是未知的病毒,而RNA片段AGTGC
則不是病毒。
由於,機器人蒐集的這些RNA片段中除去病毒的其他部分都具有非常高的研究價值。所以科學家們希望能夠分辨出其中哪些RNA片段不是病毒,並將不是病毒的RNA片段運回宇宙空間站繼續進行研究。
科學家將這項任務交給了小聯。現在請你為小聯編寫程式統計哪些RNA片段不是病毒。
輸入輸出格式
輸入格式:
第一行有一個字串,由A
、C
、T
、G
、*
、?
組成。表示“病毒模版片段”。“病毒模版片段”的長度不超過
。第二行有一個整數
(
),表示機器人蒐集到的RNA片段的數目。隨後的
行,每一行有一個字串,由A
、C
、T
、G
組成,表示一個RNA片段。每個RNA片段的長度不超過
。注意:“病毒模版片段”和RNA片段的長度都至少為
。
輸出格式:
只有一行輸出,為整數 ,即不是病毒的RNA片段的數目。
輸入輸出樣例
輸入樣例#1:
A*G?C
3
AGTC
AGTGTC
AGTGC
輸出樣例#1:
1
說明
輸入中的RNA片段AGTGC
不是病毒。
解題分析
資料範圍小, 直接 記憶化 回答每組詢問即可。
不過如果最後一位是萬用字元的話可能比較麻煩, 需要特判, 直接在模板串和匹配串後面都加一個$
即可。
程式碼如下:
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <algorithm>
#define R register
#define IN inline
#define W while
#define gc getchar()
#define MX 505
bool vis[MX][MX];
char mod[MX << 1], buf[MX];
int lena, lenb, num;
bool DFS(R int pa, R int pb)
{
if (vis[pa][pb]) return false;
if (pa == lena + 1 && pb == lenb + 1) return true;
if (pa == lena + 1) return vis[pa][pb] = true, false;
if (pb == lenb + 1) return vis[pa][pb] = true, false;
if (isalpha(mod[pa]) || mod[pa] == '$')
{
if (mod[pa] == buf[pb]) return DFS(pa + 1, pb + 1);
return vis[pa][pb] = true, false;
}
else
{
if (mod[pa] == '*')
{
for (R int i = pb; i <= lenb + 1; ++i)
if (DFS(pa + 1, i)) return true;
return vis[pa][pb] = true, false;
}
else
{
if (DFS(pa + 1, pb + 1)) return true;
return vis[pa][pb] = true, false;
}
}
}
int main(void)
{
scanf("%s", mod + 1); lena = std::strlen(mod + 1); ++lena; mod[lena] = '$';
scanf("%d", &num);
int ans = 0;
W (num--)
{
scanf("%s", buf + 1);
lenb = std::strlen(buf + 1);
++lenb; buf[lenb] = '$';
std::memset(vis, false, sizeof(vis));
if (!DFS(1, 1)) ++ans;
}
printf("%d", ans);
}