ybt 1221:分成互质组
OpenJudge NOI 小学奥数 7834:分成互质组
OpenJudge NOI 2.5 7834:分成互质组
先设函数isHuzhi
判断两个数是否互质
这里用vector保存一个互质组,可能有多个互质组,所以设vector数组。
再设函数canEnterGroup
判断能否将一个数字加入到互质组中。如果这个数字与组中每个数都互质,则可加入。否则无法加入。
遍历所有数字,对每个数字先看将其加入已有互质组的情况,再看让其单独成为一个互质组的情况。接着搜索下一个数字的情况。如果已经搜索完所有数字,看当前互质组的数量,与gmin
比较,取最小值。最后输出gmin
,即为最小的互质组数量。
#include
using namespace std;
int n, a[15], gn, gmin = 15;//a[i]:第i个数 ct:组计数 gmin:最小组数
bool vis[15];//vis[i]:第i个数字是否已经分配到一个组中
vector<int> g[15];//g[i]:第i组,gn:最后一个组的下标
bool isHuzhi(int a, int b)//判断a,b两数是否互质
{
for(int i = 2; i <= a && i <= b; ++i)
if(b%i == 0 && a%i == 0)//若a,b存在大于1的公约数
return false;//那么二者不互质
return true;//二者互质
}
bool canEnterGroup(vector<int> gp, int num)//num能否加入组gp
{
for(int i = 0; i < gp.size(); ++i)
if(isHuzhi(gp[i], num) == false)//如果num与gp中的某个数不互质,那么不能加到这个组中
return false;
return true;
}
void dfs(int k)//看数字a[k]的情况
{
if(k > n)//如果已经看完所有数字
{
gmin = min(gn, gmin);//取组数gn的最小值
return;
}
for(int i = 1; i <= gn; ++i)//数字a[k]能加入某一已存在的互质组的情况
{
if(canEnterGroup(g[i], a[k]))
{
g[i].push_back(a[k]);
dfs(k+1);
g[i].pop_back();//状态还原
}
}
g[++gn] = vector<int>();//数字a[k]单独成为一组
g[gn].push_back(a[k]);
dfs(k+1);
gn--;//状态还原
}
int main()
{
cin >> n;
for(int i = 1; i <= n; ++i)
cin >> a[i];
dfs(1);
cout << gmin << endl;
return 0;
}