分成互质组

分成互质组

DFS 做法

1.跳出条件

(1). 当当前遍历数字越界时,跳出

(2). 当当前答案比原答案大于等于时,跳出

2.DFS 递归

将这一个数放到每一组里去判断是否与里面的数字两两互质,如果行,就放入该组里。

​ 然后递归 ——> 回溯

如果全部都不行就新开一个组

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>

using namespace std;
const int N = 15;

int n, a[N], cnt, ans = N;
vector<int> p[N], aw[N];

// 计算a, b的最大公约数
int gcd(int a, int b)
{
    return b ? gcd(b, a % b) : a;
}

// 判断x是否与里面的数字两两互质
bool check(int x, int i)
{
    for(int j = 0; j < p[i].size(); j ++ )
        if(gcd(x, p[i][j]) > 1)
            return false;
    return true;
}

// 对n个数据进行搜索
void dfs(int u)
{
    if(cnt >= ans)
        return;
    if(u > n)
    {
        for(int i = 0; i < n; i ++ )
            vector<int>().swap(aw[i]);
        for(int i = 0; i < cnt; i ++ )
            for(int j = 0; j < p[i].size(); j ++ )
                aw[i].push_back(p[i][j]);
        ans = cnt;
        
        return;
    }
    
    // 遍历cnt个数据
    for(int i = 0; i < cnt; i ++ )
    {
        // 将a[u]放到每一组里去判断是否与里面的数字两两互质
        if(check(a[u], i))
        {
            // 将a[u]添加到p[i]中
            p[i].push_back(a[u]);
            // 递归搜索
            dfs(u + 1);
            // 回溯 将a[u]从p[i]中移除
            p[i].pop_back();
        }
    }
    //如果与所有的都不能兼容
    // 将a[u]添加到p[cnt]中
    p[cnt ++ ].push_back(a[u]);
    // 递归搜索
    dfs(u + 1);
    // 回溯 将a[u]从p[cnt]中移除
    p[-- cnt].pop_back();
}

int main()
{
    cin >> n;
    for(int i = 1; i <= n; i ++ )
        cin >> a[i];
        
    // 对n个数据进行搜索
    dfs(1);
    
    cout << ans << endl;
    // 遍历ans个数据
    for(int i = 0; i < ans; i ++ )
    {
        // 遍历aw[i]中的每一个数据
        for(int j = 0; j < aw[i].size(); j ++ )
            cout << aw[i][j] << ' ';
            cout << aw[i][j] <<'';
        cout << endl;
    }
    return 0;
}
posted @ 2023-06-23 16:50  ljfyyds  阅读(97)  评论(0)    收藏  举报