其他分享
首页 > 其他分享> > ZZULI (2022河南萌新联赛 四)

ZZULI (2022河南萌新联赛 四)

作者:互联网

题目描述

分析

读题不认真这个毛病什么时候能改? 我竟然看成最长上升子序列问题了, 而且还把代码写好.......(其实就算看出来是并查集, 我也不会写qwq)赛后借鉴大佬代码, 收获很大

以后看到连通块这个词, 就往并查集的方向想

AC代码

#include <iostream>
#include <cstring>

using namespace std;

const int N = 1000010;

int fa[N], sz[N], c[300];
char s[N];
int d[5];	// ***** 表示 Z, U, L, I所代表的连通块的祖宗节点 在 s 数组里的下标 

//  并查集 
int find(int x)
{
	if(fa[x] != x) fa[x] = find(fa[x]);
	return fa[x];
}
//  合并两个连通块 
void merge(int a, int b)
{
	int x = find(a), y = find(b);
	
	if(x == y) return ;
	
	sz[y] += sz[x];
	fa[x] = y;
}

int main()
{
	scanf("%s", s+1);
	
	//字符串长度 
	int L = strlen(s + 1);
	
	//  并查集初始化 
	for(int i = 1; i <= N; i ++) fa[i] = i, sz[i] = 1;
	
	//  **** 将字母和数字对应起来, 方便枚举 
	c['Z'] = 0;
	c['U'] = 1;
	c['L'] = 2;
	c['I'] = 3;
	//  变量全部字符串 
	for(int i = 1; i <= L; i ++)
	{
		if(s[i] == 'Z' || s[i] == 'U' || s[i] == 'L' || s[i] == 'I')
		{
			//  k 代表目前找到的字符串是哪一个 0, 1, 2, 3 
			int k = c[s[i]];
			//  如果前面已近已经有和s[i]相同的字符串, 则合并两个连通块 
			if(d[k])  merge(d[k], i); // d[k] 表示原先那个字符的下标 
			else d[k] = i;
			
			//  依次合并 连通块 
			for(int j = 0; j < k; j ++)
			{
				if(d[j]) merge(d[j], i);
			}
		}
	}
	
	int res = 0;
	for(int i = 1; i <= L; i ++) res = max(res, sz[i]);
	
	cout << res << endl;
	
	return 0;
	
	
}

标签:sz,连通,萌新,int,ZZULI,查集,fa,2022,find
来源: https://www.cnblogs.com/ding-yu/p/16538183.html