分成互质组

题目描述

给定n个正整数,将它们分组,使得每组中任意两个数互质。至少要分成多少个组?

输入

第一行是一个正整数n。1 <= n <= 10。
第二行是n个不大于10000的正整数。

输出

一个正整数,即最少需要的组数。

样例输入

6
14 20 33 117 143 175

样例输出

3

OpenJudge - 7834:分成互质组

题目解释

每次将当前组与其他数比较,是否被选过如果没选过,是否与当前组数是否都互质,如果互质就存下来并且进行下一层循环

如果找不到符合条件的就进行下一组并将当前数存入下一组

最后输出组数

程序实现

int gcd(int y,int x)
{
	int r=x%y;
	while(r)
	{
		x=y;
		y=r;
		r=x%y;
	}
	return y;
}

判断是否互质,图形证明欧几里得算法

对a,b两个数每次进行将b=a,a=b%a直到b%a==0这时就找到a,b最大公约数了

回归本题当a,b两个数的最大公约数为1时两个数就是互质

bool check(int x,int cnt)
{
	for(int i=0;i<g[cnt].size();i++)
	{
		if(gcd(x,g[cnt][i])!=1)return false;
	}
	return true;
}

将当前选到的数与当前的组中数每个判断是否互质,如果互质则回true否则false

void dfs(int cnt,int sum)
{
	if(cnt>=ans) return; 
	if(sum==n) ans=cnt;
	int f=0;
	for(int i=1;i<=n;i++)
	{
		if(flag[i]==0&&check(num[i],cnt))
		{
			flag[i]=1;
			g[cnt].push_back(num[i]);
			dfs(cnt,sum+1);
			g[cnt].pop_back();
			flag[i]=0;
			f=1;
		}
	}
	if(f==0) dfs(cnt+1,sum);
}

当cnt>=ans时就已经不是分组最少的分组互质数了就直接退出枚举

当sum==n时代表当前分的组数更小且已经分完就将更小值赋值给ans

f:存储是否有数与其互质的状态有则为1无则为0

cnt:存储当前的组数

sum:当前以分组的数的个数

遍历所有书判断是否已经取过并且是否与当前组中的所有数互质

如果满足条件则标记已经取过将当前数入组

后将继续搜索分组

分组后

为不影响其他分组需将其初始化将其踢出组去除标记

并且标记当前数已有能进组的数

全部遍历完判断当前数是否能有数与其进行继续分组

若没有数则就重开一组继续分组

main()
{
	cin>>n;
	ans=n; 
	for(int i=1;i<=n;i++)
	cin>>num[i];
	dfs(1,0);
	cout<<ans;
	return 0;
}

最后输出答案

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值