其他分享
首页 > 其他分享> > Subset Equality S

Subset Equality S

作者:互联网

[USACO22OPEN]

题目描述

奶牛们正在尝试一种相互交换编码信息的新方法,她们在相关的字母中混入不相关的字母,使信息难以解码。

奶牛们传输两个字符串 \(s\) 和 \(t\),每个字符串的长度不超过 \(10^5\),仅由小写字母 'a' 到 'r' 组成。为了尝试理解这条编码消息,你将被给定 \(Q\) 个询问(\(1 \leq Q \leq 10^5\))。

每个询问给定小写字母 'a' 到 'r' 的一个子集。你需要对每个询问判断 \(s\) 和 \(t\) 在仅包含询问中给定的字母时是否相等。

输入格式

输入的第一行包含 \(s\)。

第二行包含 \(t\)。

第三行包含 \(Q\)。

以下 \(Q\) 行每行包含一个询问字符串。在一个询问字符串中,所有字母均不相同。此外,所有询问字符串均已排序,且没有一个询问字符串出现超过一次。

输出格式

对每个询问,如果 \(s\) 和 \(t\) 在仅包含询问中给定的字母时相等则输出 'Y',否则输出 'N'。

样例 #1

样例输入 #1

aabcd
caabd
4
a
ac
abd
abcd

样例输出 #1

YNYN

提示

【样例解释】

对于第一个询问,当仅包含字符 'a' 时,两个字符串均变为 "aa"。

对于第二个询问,第一个字符串变为 "aac" 而第二个字符串变为 "caa"。

【测试点性质】

如果询问字符串只有一个字符,我们比较一下这种字符在两个串中的数量是否相等即可。

如果有两个字符呢这时于超时。那就暴力吧。

但是字符一多起来怎么办?发现如果s,t在仅包含有ab时相等,仅包含bc时相等,仅包含ac时相等,那么他在仅包含abc时也相等。因为两两字符的位置关系都一样,那么整个取出来也一样。这里可以感性理解一下。

字符最多26个。我们可以预处理出在每两个字符时s和t相不相等,然后对于每个询问,枚举字符串中每两个字符,按照预处理看他们相不相等。如果都相等那么整个都相等。

#include<cstdio>
#include<cstring>
const int N=1e5+5;
int n,s[20],t[20],m,q,f[20][20],k;
char a[N],b[N],x[20];
int solve(char x,char y)
{
	char s[N],t[N];
    int p=0,q=0;
	for(int i=1;i<=n;i++)
		if(a[i]==x||a[i]==y)
			s[++p]=a[i];
	for(int i=1;i<=m;i++)
		if(b[i]==x||b[i]==y)
			t[++q]=b[i];
	if(p!=q)
		return 0;
	for(int i=1;i<=p;i++)
		if(s[i]!=t[i])
			return 0;
	return 1;
}
int main()
{
	scanf("%s%s%d",a+1,b+1,&q);
	n=strlen(a+1),m=strlen(b+1);
	for(int i=1;i<=n;i++)
		s[a[i]-'a']++;
	for(int i=1;i<=m;i++)
		t[b[i]-'a']++;
	for(char i='a';i<='r';i++)
		for(char j='a';j<='r';j++)
			f[i-'a'][j-'a']=solve(i,j);
	while(q--)
	{
		scanf(" %s",x+1);
		k=strlen(x+1);
		if(k==1)
		{
			if(s[x[1]-'a']!=t[x[1]-'a'])
				putchar('N');
			else
				putchar('Y');
		}
		else
		{
			for(int i=1;i<=k;i++)
			{
				for(int j=1;j<=k;j++)
				{
					if(!f[x[i]-'a'][x[j]-'a'])
						putchar('N'),k=0;
				}
			}
			if(k)
				putchar('Y');
		}
	}
}

标签:Subset,字符,相等,Equality,包含,询问,字符串,20
来源: https://www.cnblogs.com/mekoszc/p/16465438.html