1. 程式人生 > >[2018.10.15 T2] 字串

[2018.10.15 T2] 字串

暫無連線

字串

【題目描述】

小C學會了 S A SA S A M SAM

之後,非常激動。

他看見了兩個字串 s , t s,t ,其中 s s 只包含小寫字母以及

* t t 只包含小寫字母。

小C可以進行任意多次操作,每次選擇 s s 中的一個

* ,將它修改為任意多個(可以是 0 0 個)它的前一個字元。他想知道是否能將 s s 修改為 t t

請你幫小C求解這道簡單字串題。

有多組資料。

【輸入】

第一行一個整數 T T 表示資料組數。

每組資料兩行,第一行一個字串 s s ,第二行一個字串 t t

【輸出】

每組資料輸出一行,如果能將 s s 修改為 t t ,輸出 Y e s Yes ,否則輸出 N o No

【輸入樣例】

2
a*
aaaa
a*
ab

【輸出樣例】

Yes
No

【提示】
【資料規模及約定】

對於 20 % 20\% 的資料, s , t 7 |s|,|t|≤7
對於 60 % 60\% 的資料, s , t 300 |s|,|t|≤300
對於 100 % 100\% 的資料, T 100 s , t 30000 T≤100,|s|,|t|≤30000

題解

特殊情況大概長成這樣 a a a a a a*aaa***a ,這種情況跟 a a a a a aaaaa* 等價,我們讀入 s s 串的時候先把所有特殊情況處理掉,最後寫個無腦模擬即可。

程式碼
#include<bits/stdc++.h>
using namespace std;
const int M=3e4+5;
char ch[M],s[M],t[M];
int l1,l2,p1,p2,tot,T,flag;
void reset(){memset(s,tot=0,sizeof(s));}
void in(){scanf("%s%s",ch+1,t+1);}
void ac()
{
	l1=strlen(ch+1),l2=strlen(t+1);
	for(p1=1,p2,flag;p1<=l1;p1=p2+1)
	{
		p2=p1;flag=0;
		for(;(ch[p2]==ch[p1]||ch[p2]=='*')&&p2<=l1;++p2);
		p2-=1;
		for(int i=p1;i<=p2;++i)ch[i]!='*'?s[++tot]=ch[p1]:flag=1;
		if(flag)s[++tot]='*';
	}
	l1=tot;
	for(p1=1,p2=1;p1<=l1;++p1)
	{
		if(s[p1]==t[p2]){++p2;continue;}
		if(s[p1]!='*'){puts("No");return;}
		for(;s[p1-1]==t[p2];++p2);
	}
	(p2>l2&&p1>l1)?puts("Yes"):puts("No");
}
int main(){for(scanf("%d",&T);T--;)reset(),in(),ac();}