【并查集】识别水果

在山的那边、海的那边,Viking岛岛主holy_one因财政危机,派遣三大护法前往移花岛探险。经过249天的海上漂泊,他们最终到达移花岛,遇到了三位女神。岛上水果丰富,但部分水果有毒且通过特定标记识别。通过翻译字典,三人得知如何辨别水果的毒性,最终帮助他们找到了无毒的水果。
摘要由CSDN通过智能技术生成


背景 Background  
    在山的那边、海的那边,有一座自由之岛viking岛,岛主正是鼎鼎有名的holy_one。由于持续多年的石油泄漏,岛上的渔业受到了严重打击,眼看着岛上的财政已是入不敷出,holy_one心急如焚。无奈之下,他决定重新干起老本行,探险,用探险得来的金子充实岛库。但由于holy_one年事已高,无法再像年轻时那样走南闯北了。于是他便让自己最信任的三大护法:残雪、水手2011和夏夜替他担负起前往lcyz岛的重大任务。在紧张的筹备了一个月后,三大护法率领着Viking岛有史以来规模最大的船队满载着全岛人的希望启航了。
     
     
  描述 Description  
  在海上漂泊了249天后,由于食物和水都已消耗光了,三人已是筋疲力尽。终于,在第250天的早晨,一个隐隐约约的黑点在远处出现了,是一个小岛,三大护法高兴的几乎要跳起来。于是下令舰队全速前进,驶向小岛。
  在登陆后,他们才知道,这就是著名的移花岛,岛上有三位女神:dp女神、涓涓女神和紫晶女神。由于三大女神与holy_one的关系不错,因此高兴地接待了他们三人。由于看到三人饥渴难耐,负责岛上水果的涓涓女神便带他们去了果园。
  果园里水果丰富,共有n个,它们的标号为1~n,但有些水果是有毒,而且水果与水果之间有藤蔓相连,如果一个水果有毒,那么所有与它相连的所有水果都是有毒的。其中m个水果上面会贴着一个标签,从标签上可以看出这个水果是否有毒。当然,如果这个水果的标签显示无毒,但它与有毒的水果相连,那它也是有毒的。
  为帮助三人尽快吃到水果,涓涓女神给了他们一张毒物字典,只有通过字典上的对应关系翻译后,才能知道水果是否有毒。转化后的名称中包含'poison',即表示这个水果有毒。
     
     
  输入格式 Input Format  
  第一行,字符串a
第二行,字符串b
a串和b串长度都是26,a[i]到b[i]表示两个字母的对应关系。注意,对应关系是单向的。
两个整数n和m。
以下m行,
每行第一个数是水果的标号k,后面是第k个水果的标签s
k和s之间有空格分隔开
一个整数p。
以下p行,每行两个整数x,y表示第x个水果和第y个水果之间有藤蔓相连。
     
     
  输出格式 Output Format  
  无毒的水果的个数。

题很简单,只是字符串处理稍微麻烦了一点。主要理清思路就好了。


写错的地方:

1、算成了有毒的水果

2、hash[a[0]-'a']=a[0];写成了hash[a[0]-'a']=a[0]-'a';。这实际上是映射到某一个位置,所以错了。


#include <cstdio>
#include <string>
long hash[110];
long fa[10010];
char a[110];
char b[110];
char name[10010][110];
long len[10010];
bool poison[10010];
char poi[] = "poison";
long getint()
{
	long rs=0;char tmp;bool sgn=1;
	do tmp = getchar();
	while (!isdigit(tmp)&&tmp-'-');
	if (tmp=='-'){sgn=0;tmp=getchar();}
	do rs=(rs<<3)+(rs<<1)+tmp-'0';
	while (isdigit(tmp=getchar()));
	return sgn?rs:-rs;
}
long getroot(long x)
{
	if (fa[x] == x)return x;
	return fa[x] = getroot(fa[x]);
}
int main()
{
	freopen("fruit.in","r",stdin);
	freopen("fruit.out","w",stdout);
	scanf("%s",a+1);
	while (a[++a[0]])
	{
		hash[a[a[0]]-'a'] = a[0]; 
	}
	scanf("%s",b+1);
	while (b[++b[0]])
	{
		b[b[0]]-='a';
	}

	long n = getint();
	long m = getint();
	for (long i=1;i<n+1;i++)
		fa[i] = i;
	for (long i=1;i<m+1;i++)
	{
		long k = getint();
		scanf("%s",name[k]+1);
		long cnt = 0;
		len[k] = 0;
		while (name[k][++len[k]])
		{
			long tmp = name[k][len[k]]-'a';
			name[k][len[k]] = b[hash[tmp]];
			if (name[k][len[k]] == poi[cnt]-'a')
			{
				 cnt ++;
				 if (cnt == 6)
					 poison[k] = true;
			}
			else
				cnt = 0;
		}
	}
	long p = getint();
	for (long i=1;i<p+1;i++)
	{
		long x = getint();
		long y = getint();
		fa[getroot(x)] = getroot(y);
	}
	for (long i=1;i<n+1;i++)
		if (poison[i])
			poison[getroot(i)]=true;
	long ans = n;
	for (long i=1;i<n+1;i++)
		if (poison[getroot(i)])
			ans --;
	printf("%ld\n",ans);
	return 0;
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值