题目链接
这是一道搜索题:分为互质组。
题目:
蒜头君给定 n 个正整数,将它们分组,使得每组中任意两个数互质。至少要分成多少个组?
输入格式
第一行是一个正整数 n。1≤n≤10。
第二行是 n 个不大于 10000 的正整数。
输出格式
一个正整数,即最少需要的组数。
Sample Input
6
14 20 33 117 143 175
Sample Output
3
刚看到这个题很头疼,因为不会用编程判断两个数字是不是互质的,后来在网站查了查怎么判断两个数字是否互质,将两个数字连续互相取余,如果余数为0则不互质,如果不为0则将其中一个数字与余数继续取余。
这个题中,我用a数组储存需要分组的数字,b数组存储各个数字被分到的组数,一开始就默认第一个数字在第一组,我们进入分组循环,将数字一个一个分入对应的组,一开始都是从第一组开始判断,并且默认flag=1(即可以分入组内),从第一个数字开始查找,如果它的组数是我们当前要判断是否能进的组就进行判断这两个数字是否互质,只要组内有一个数字不互质,则就跳出循环,进行下一组数字的判断,看它能不能被分入下一组,并且这里注意要将flag在此设置为1(我就在这里卡了好久,用了逐语句找出的错误),因为一开始我们都是默认它可以分进的,然后再次判断,如果我们当前的几组数据都查找过了这个数字都不能进入,则我们新设立一个组给这个数字,icount++(这个变量就是总组数),将这个数字设置为第icount组,即b[j]=icount,如果这个数字与某组数字都互质,即可以进入该组,则将b[j]设置为该组数。
一维数组代码如下:
#include<iostream>
using namespace std;
int a[15];//存储数字
int b[15]; //存储数字在第几组
int icount=0;
int judge(int a,int b)
{
if(a==1||b==1)//如果a或b为1则两个数字一定互质
return 1;
int t;
while(1)
{
t=a%b;
if(t==0)
{
break;
}
else
{
a=b;
b=t;
}
}
if(b>1)
return 0;
else
return 1;
}
int main()
{
int m;
cin>>m;
for(int i=0;i<m;i++)
cin>>a[i];
icount=1;
b[0]=1;
int flag;//用来判断是否能在这组
int q;
for(int j=1;j<m;j++)//给第j个数字分组
{
q=1;//从第一组开始判断
flag=1;
while(1)
{
for(int i=0;i<j;i++)//寻找第j个数字之前的第q组的数字
{
if(b[i]==q)
{
if(judge(a[i],a[j])==0)
{
flag=0;
break;
}
}
}
if(flag==0)//如果与改组数字不互质
{
if(q!=icount)
{
q++;
flag=1;//注意这里,我们一开始都是默认能够进入这组的
}
else//如果这是最后一组了
{
icount++;
b[j]=icount;
break;
}
}
else if(flag==1)//如果能够进入这组
{
b[j]=q;//将该数字组数设置
break;
}
}
}
cout<<icount<<endl;
return 0;
}
二维数组代码如下:
#include<bits/stdc++.h>
using namespace std;
int judge(int a,int b)
{
int r=a%b;
while(r)
{
a=b;
b=r;
r=a%b;
}
if(b==1)
return 1;
else
return 0;
}
int main()
{
int n,m;
cin>>n;
int a[10][11]={
0};
cin>>m;
a[1][1]=m;
int count=1;
for(int i=0;i<n-1;i++)
{
cin>>m;
int untidy=0;//这个标记为有无安置
for(int j=1;j<=count;j++)
{
int u;
int flag=0;//默认能存放在这个组
for(u=1;a[j][u]!=0;u++)
{
if(judge(a[j][u],m)==0)
{
flag=1;//标记位不能存放
break;
}
}
if(flag==0)
{
a[j][u]=m;
untidy=1;//标记为已安置
break;
}
}
if(untidy==0)
{
count++;
a[count][1]=m;
}
}
cout<<count<<endl;
return 0;
}