• 【题解】一本通1221:分成互质组


    分成互质组

    时间限制: 1000 ms 内存限制: 65536 KB
    提交数: 4518 通过数: 2079

    【题目描述】

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

    【输入】

    第一行是一个正整数n。1 ≤ n ≤ 10。

    第二行是n个不大于10000的正整数。

    【输出】

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

    【输入样例】

    6
    14 20 33 117 143 175

    【输出样例】

    3

    分析

    对于第x+1个数,要么把它塞进前面的组里,要么自成一组。
    枚举所有已存在的组,如果可以加入,就加入,更新所加入组的元素个数和元素。
    递归。。回来
    退出这个组,还原这个组的元素个数和元素
    判断能否加入下一个组
    重复操作
    判断完所有已知组
    自成一组,组数加一,更新新组元素个数和元素
    递归。。

    #include <cmath>
    #include <cstdio>
    #include <string>
    #include <cstring>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    #define F(i,a,b) for(int i=a;i<=b;i++)
    #define UF(i,a,b) for(int i=a;i>=b;i--)
    using namespace std;
    typedef long long ll;
    const int N = 15;
    int ans = 20, n, a[N], gro[N][N] , tot[N];
    int t;
    int gcd(int a, int b){//通过找gcd判断互质
    	if(b==0){
    		return a;
    	}	
    	else return gcd(b, a%b);
    }
    bool huzhi(int a[], int b, int tot){//判断b能否加入a组
    	if(b == 1)	return 1;
    	for(int i = 1; i <= tot ; i++){
    		if(gcd(a[i],b) != 1)	return 0;
    	}
    	return 1;
    }
    void divi(int x, int zu){//a[x]是当前
    //这一堆是用来调试的,可忽略
    //	if (t == 1)		return;
    //	cout <<"a   x+1   zu   tot       gro"<<endl;
    //	cout <<a[x + 1]<<"   "<<x + 1<<"      "<<zu<<"   ";
    //	F(i,1,zu)
    //			cout << tot[i] <<",";
    //	cout << "      ";		
    //	F(i,1,zu){
    //			F(j,1,tot[i]){
    //				cout << gro[i][j] <<",";
    //			}
    //			cout <<"..";
    //		}
    //	cout << endl ;		
    	if(x == n){
    	    if(zu < ans){
    		ans = zu;//更新答案
    	    }
    //加入了同样的调试
    //		cout <<"a   x+1   zu   tot      gro"<<endl; 
    //		cout <<a[x]<<"   "<<x + 1<<"   "<<zu<<"   ";
    //		F(i,1,zu){
    //			cout << tot[i] <<",";
    //		}
    //		cout << "   ";
    //		F(i,1,zu){
    //			F(j,1,tot[i]){
    //				cout << gro[i][tot[j]] <<",";
    //			}
    //			cout <<"..";
    //		}
    //		cout << endl ;
    //		t = 1;
    		return;
    	}
    	F(i,1,zu){
    		if(huzhi(gro[i], a[x + 1], tot[i])){//我们是为a[x+1]找归宿
    			tot[i]++;
    			gro[i][tot[i]] = a[x + 1];
    			divi(x + 1, zu);
    			tot[i]--;
    		}
    	}
    	tot[zu + 1] ++;
    	gro[zu + 1][1] = a[x + 1];
    	divi(x + 1, zu + 1);
    	tot[zu + 1]--;
    }
    int main()
    {
    	std::cin >> n;
    	F(i,1,n)	std::cin>>a[i];
    	tot[1] = 1;
    	gro[1][1] = a[1];
    	divi(1,1);
    	cout << ans <<endl;
    	return 0;
    }
    
    /*10
    1024 13 169 97 4 5 6  25 30 729
    */ 
    
  • 相关阅读:
    LeetCode 152. 乘积最大子数组 | Python
    LeetCode 31. 下一个排列 | Python
    LeetCode 136. 只出现一次的数字 | Python
    LeetCode 102. 二叉树的层序遍历 | Python
    LeetCode 155. 最小栈 | Python
    LeetCode 69. x 的平方根 | Python
    Python3 高阶函数
    Python3 装饰器
    Python3 递归函数
    Python3 函数
  • 原文地址:https://www.cnblogs.com/ZhengkunJia/p/12296529.html
Copyright © 2020-2023  润新知