Codeforces 1367E. Necklace Assembly(并查集)

题目链接

题目大意:
现在你有n个珍珠,每个珍珠的颜色用字母a ~ z来描述。你可以从中选出任意个珍珠以任意顺序串成环,求最多能串成多长的环满足每个珍珠的颜色有k的循环周期。

解法:
枚举答案,对于当前长度用并查集check。

Code:

#include <bits/stdc++.h>
#define clr(a,b) memset(a,b,sizeof(a));
using namespace std;
const int MX = 2e3 + 7;

int n,k;
char s[MX];
int ch[30];
int fa[MX],siz[MX];
bool used[MX];

int find(int x){return fa[x] == x? x : fa[x] = find(fa[x]);}
void unionset(int x,int y){
	int f1 = find(x), f2 = find(y);
	if(f1 == f2) return ;
	if(f1 > f2) swap(f1,f2);
	fa[f2] = f1;
	siz[f1] += siz[f2];
}
bool judge(int d){
	for(int i = 0;i < d;++i) fa[i] = i,used[i] = false,siz[i] = 1;
	for(int i = 0;i < d;++i){
		unionset(i,(i + k) % d);
	}
	int a[MX], cnt = 0;
	for(int i = 0;i < d;++i){
		if(used[find(i)]) continue;
		used[find(i)] = true;
		a[cnt++] = siz[find(i)];
	}
	sort(a,a + cnt,greater<int>());
	int p = 0;
	for(int c = 0;c < 26;++c){
		int tot = ch[c];
		while(p < cnt){
			if(a[p] <= tot) tot -= a[p++];
			else break;
		}
	}
	return p == cnt;
}
int solve(){
	int res = 1;
	clr(ch,0);
	for(int i = 1;i <= n;++i){
		ch[s[i] - 'a']++;
	}
	sort(ch,ch + 26,greater<int>());
	for(int d = n;d >= 2;--d){
		if(d <= ch[0]) {res = d;break;}
		if(judge(d)){
			res = d;break;
		}
	}
	return res;
}
int main(){
	int T;scanf("%d",&T);
	while(T--){
		scanf("%d %d",&n,&k);
		scanf("%s",s+1);
		int res = solve();printf("%d\n", res);
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值