1. 程式人生 > 實用技巧 >2020.12.02 晚間訓練

2020.12.02 晚間訓練

Day -2

總得分:100/300

一、string

【題目描述】

給定兩個字串\(s\)\(t\),其中s只包含小寫字母以及\(*\)\(t\)只包含小寫字母。

你可以進行任意多次操作,每次選擇\(s\) 中的一個\(*\),將它修改為任意多個(可以是\(0\)個)它的前一個字元。問是否能將\(s\) 修改為\(t\)

多組資料。

【輸入資料】

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

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

【輸出資料】

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

【樣例輸入】

2
a*
aaaa
a*
ab

【樣例輸出】

Yes
No

【資料範圍】

對於\(20%\) 的資料,\(|s|\),\(|t|<=7\)

對於\(60%\) 的資料,\(|s|\),\(|t|<=300\)

對於\(100%\) 的資料,\(T<=100\)\(|s|\),\(|t|<=30000\)

Solution

沒什麼好說的,模擬。

把兩個字串連續相同的字母給合併為一個的形式,即建立結構體的桶用於存放。

對於出現了\(*\)的情況,在它前面的一個字母上打標,表示前面一個字母可以複製無限個。

注意:

很有可能出現以下情況:

a**ab
aab

因為兩個\(a\) 之間被\(*\) 斷開,導致錯開了\(2\) 個桶

所以遇到這種情況要合併掉

code:

#include <bits/stdc++.h>
#define REP(i, x, y) for(register int i = x; i < y; i++)
#define rep(i, x, y) for(register int i = x; i <= y; i++)
#define PER(i, x, y) for(register int i = x; i > y; i--)
#define per(i, x, y) for(register int i = x; i >= y; i--)
using namespace std;
const int N = 30005;
struct node{
	char ch;
	int sum;
}t1[N], t2[N];
string s1, s2;
int T, len1, len2, tag[N];
int main()
{
	freopen("string.in", "r", stdin);
	freopen("string.out", "w", stdout);
	scanf("%d", &T);
	while(T--)
	{
		int cnt1 = 0, cnt2 = 0;
		int temp = 1;
		memset(t1, 0, sizeof t1);
		memset(t2, 0, sizeof t2);
		memset(tag, 0, sizeof tag);
		cin >> s1 >> s2;
		len1 = s1.length();
		len2 = s2.length();
		rep(i, 1, len1)
		{
			t1[i].sum = 0;
		}
		rep(i, 1, len2)
		{
			t2[i].sum = 0;
		}
		rep(i, 0, len1 - 1)
		{
			if(s1[i] != '*')
			{
				if(t1[cnt1].ch != s1[i])
				{
					cnt1++;
				}
				t1[cnt1].ch = s1[i];	
				temp = t1[cnt1].sum + 1;
				while(s1[i + 1] == s1[i])
				{
					temp++;
					i++;
				}
				t1[cnt1].sum = temp;
				temp = 1;
			}	
			else
			{
				tag[cnt1] = 1;
			}
		}
		temp = 1;
		rep(i, 0, len2 - 1)
		{
			if(s2[i] != '*')
			{
				t2[++cnt2].ch = s2[i];	
			
				while(s2[i + 1] == s2[i])
				{
					temp++;
					i++;
				}
				t2[cnt2].sum = temp;
				temp = 1;
			}	
		}
		if(cnt1 != cnt2)
		{
			cout << "No" << endl;
			continue;
		}
		int f = 0;
		rep(i, 1, cnt1)
		{
			if(t1[i].ch != t2[i].ch)
			{
				cout << "No" << endl;
				f = 1;
				break;
			}
			else if((t1[i].sum > t2[i].sum) || (t1[i].sum < t2[i].sum && tag[i] == 0))
			{
				cout << "No" << endl;
				f = 1;
				break;				
			}
		}
		if(!f)
		{
			cout <<"Yes" << endl;
		}
	}
	return 0;
}