openjudge_2.5基本算法之搜索_7834:分成互质组

题目

7834:分成互质组
总时间限制: 1000ms 内存限制: 65536kB
描述
给定n个正整数,将它们分组,使得每组中任意两个数互质。至少要分成多少个组?

输入
第一行是一个正整数n。1 <= n <= 10。
第二行是n个不大于10000的正整数。
输出
一个正整数,即最少需要的组数。
样例输入
6
14 20 33 117 143 175
样例输出
3
来源
2008年第十三届“华罗庚金杯”少年数学邀请赛 决赛第5题

理解

  1. 某数跟别的数都不互质,该数独立为一组。
  2. 某数跟别数互质,那共同是一组。
  3. (精髓)某两数互质,等到乘积跟另数互质,则该三数都互质。
  4. 宽搜是一个根节点遍历树。现在分组是分成多个数(树),不用宽搜。
  5. 每个没分组的数就是一个组,跟剩下没分组的数遍历,互质就变成同一组,用他们的乘积继续找下一个没分组的数。

代码

#include <bits/stdc++.h>
using namespace std;
int n,d[15],
ans,//几个组
k[15];//分到哪个组,也是宽搜标记
int gcd(int a,int b){
if(b==0)return a;
return gcd(b,a%b);
}
void view(){
cout<<“显示”<<endl;
for(int i=1;i<=n;i++)cout<<i<<“\t”;cout<<endl;
for(int i=1;i<=n;i++)cout<<d[i]<<“\t”;cout<<endl;
for(int i=1;i<=n;i++)cout<<k[i]<<“\t”;cout<<endl;
}
int main(){
//freopen(“data.cpp”,“r”,stdin);
cin>>n;
for(int i=1;i<=n;i++)cin>>d[i];
for(int i=1;i<=n;i++){
if(k[i])continue;//分过的就不管
k[i]=++ans;//分组
for(int j=i+1;j<=n;j++)//遍历剩余数
if(gcd(d[i],d[j])==1&&!k[j])//跟改组乘积是否为互质,而且没有分组过
d[i]*=d[j],k[j]=ans;//把该数乘到乘积中,并分到该组,
//view();
}
cout<<ans;
return 0;
}

互质数判断

根据百度查找——
根据互质数的定义,可总结出一些规律,利用这些规律能迅速判断一组数是否互质。
(1)两个不相同的质数一定是互质数。如:7和11、17和31是互质数。
(2)两个连续的自然数一定是互质数。如:4和5、13和14是互质数。
(3)相邻的两个奇数一定是互质数。如:5和7、75和77是互质数。
(4)1和其他所有的自然数一定是互质数。如:1和4、1和13是互质数。
(5)两个数中的较大一个是质数,这两个数一定是互质数。如:3和19、16和97是互质数。
(6)两个数中的较小一个是质数,而较大数是合数且不是较小数的倍数,这两个数一定是互质数。如:2和15、7和54是互质数。
(7)较大数比较小数的2倍多1或少1,这两个数一定是互质数。如:13和27、13和25是互质数。
当然互质判断本质上是公约数有且仅有1。

小结

还是要从分析数据开始。
把两质数的乘积作为新对象找别的互质数,这个是个大胆的举措。

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值