AcWing 1118. 分成互质组
题意:
给定 n
个正整数,将它们分组,使得每组中任意两个数互质。
问:至少要分成多少个组?
思路:
dfs
,对每一个元素,我们有两种操作:
- ①:放到现有组中的最后一组中(依次枚举最后一组的所有元素,判断新加的元素是否与它们全部互质,如果是的则加入)
- ②:新开一个组并放入
用p[N]
存放n
个元素
二维数组group[N][N]
存放每个组
我们从第一个组 g=1
,组内没有数 gc=0
,当前用掉了 cnt=0
个元素,当前组还未开始遍历数 start=0
的初始状态开始搜索。
每次搜索的时候判断是否可以将元素放到现有组中的最后一组(用标记变量ok
),如果不行再新开一组。
空白代码:
#include<bits/stdc++.h>using namespace std;
const int N = 15;
int group[N][N], p[N];
bool st[N];
int n;
int ans;int gcd(int a, int b)
{return b ? gcd(b, a%b) : a;
}bool check(int g[], int gc, int a){for(int i=0;i<gc;++i){if(gcd(g[i], a)!=1) return false;}return true;
}void dfs(int g, int gc, int cnt, int start)
{if(g>=ans) return ;if(cnt==n) {ans = g; return ;}bool ok = false;for(int i=start; i<n; ++i){if(!st[i]&&check(group[g], gc, p[i])){st[i] = true;group[g][gc] = p[i];dfs(g, gc+1, cnt+1, i+1);st[i] = false;ok = true;}}if(!ok) dfs(g+1, 0, cnt, 0);
}int main()
{cin>>n;for(int i=0;i<n;++i) cin>>p[i];ans = n;dfs(1, 0, 0, 0);cout<<ans<<endl;return 0;
}
代码 + 注释:
#include<bits/stdc++.h>
using namespace std;const int N = 15;int n;
int p[N];//存放n个元素
int group[N][N];//存放每个组
bool st[N];
int ans;int gcd(int a, int b)
{return b ? gcd(b, a % b) : a;
}bool check(int g[], int gc, int a){//判断当前组中的数是否和该数都互质(即该数能否放进该组)for(int i=0;i<gc;++i)//枚举此组组内每个数{if(gcd(g[i], a)!=1) return false;//只要组内有数和该数不互质了就return false}return true;//否则return true
}void dfs(int g, int gc, int cnt, int start)
{//g为当前的最后一组的组的序号,gc为当前组内 搜索到的 数的序号//cnt为当前 搜索过的 元素数量,start为当前组 开始搜索的 数(p数组中的元素)的序号if (g >= ans) return;//如果有比当前最优解所需的组数更多的解法说明此解不为最优解-->直接return即可if (cnt == n) {ans = g; return ;}//如果搜完了所有点了,说明此解为当前的最优解,更新最优解bool ok = false;//flag标记是否能新开一组for (int i = start; i < n; ++i)//枚举每个数if (!st[i] && check(group[g], gc, p[i]))//如果当前数还未被放进组里 且 与当前的组中的数都互质{st[i] = true;group[g][gc] = p[i];//分支一:继续搜索该组,组内数的数量gc + 1,总的数的数量cnt + 1,搜索的数的序号i + 1(组合型枚举,人为规定一个递增的顺序)dfs(g, gc + 1, cnt + 1, i + 1);st[i] = false;ok = true;//如果能放进当前最后一组,则不用新开一组,ok标记为true}//分支二 经过for的枚举后发现无法放进最后一组,ok没有发生什么变化,还是false,则新开一组来搜索if (!ok) dfs(g + 1, 0, cnt, 0);//当前最后一组的组的序号g + 1, 组内搜索的数的序号gc为0//搜索到的数cnt未变, 当前组内开始搜索的数的序号start为0(仍重新从0开始搜,放不放入新开的组内就看是否满足条件了)
}int main()
{cin >> n;ans = n;//还未搜索时,假定最优解为最坏的情况每个数都分一组for (int i = 0; i < n; ++i) cin >> p[i];dfs(1, 0, 0, 0);//从第一个组 g=1, 组内没有数 gc=0//当前用掉了 cnt=0 个元素, 当前组还未开始遍历数 start=0 的初始状态开始搜索cout << ans << endl;return 0;
}
AcWing 1118. 分成互质组相关推荐
- 1118. 分成互质组
给定 n 个正整数,将它们分组,使得每组中任意两个数互质. 至少要分成多少个组? 输入格式 第一行是一个正整数 n. 第二行是 n 个不大于10000的正整数. 输出格式 一个正整数,即最少需要的组数 ...
- 小学奥数 7834 分成互质组 python
http://noi.openjudge.cn/math/7834/ 参考: 信息学奥赛一本通(1221:分成互质组) https://blog.csdn.net/lvcheng0309/articl ...
- 信息学奥赛一本通(1221:分成互质组)
1221:分成互质组 时间限制: 1000 ms 内存限制: 65536 KB 提交数: 7405 通过数: 3453 [题目描述] 给定n个正整数,将它们分组,使得每组中任意 ...
- C++递归算法之分成互质组
分成互质组 Description 给定n个正整数,将它们分组,使得每组中任意两个数互质.至少要分成多少个组? Input 第一行是一个正整数n.1 <= n <= 10. 第二行是n个不 ...
- POJ 7834:分成互质组
" Ctrl AC!一起 AC!" 原题:忘题戳这 分析:对于一个数,遍历所有的互质组,如果可以进入一个组,并保持组内互质,则总组数不变.否则总组数加一. AC代码: #inclu ...
- 分成互质组 (信息学奥赛一本通-T1221)
[题目描述] 给定n个正整数,将它们分组,使得每组中任意两个数互质.至少要分成多少个组? [输入] 第一行是一个正整数n.1 ≤ n ≤ 10. 第二行是n个不大于10000的正整数. [输出] 一个 ...
- 1221:分成互质组
[题目描述] 给定n个正整数,将它们分组,使得每组中任意两个数互质.至少要分成多少个组? [输入] 第一行是一个正整数n.1 ≤ n ≤ 10. 第二行是n个不大于10000的正整数. [输出] 一个 ...
- 【noi 2.5_7834】分成互质组(dfs)
有2种dfs的方法: 1.存下每个组的各个数和其质因数,每次对于新的一个数,与各组比对是否互质,再添加或不添加入该组. 2.不存质因数了,直接用gcd,更加快.P.S.然而我不知道为什么RE,若有好心 ...
- OpenJudge 7384(分成互质组)
应hfu要求,近几日整理搜索专题的内容,无意中翻出了一年前死活A不掉的一道不可做题(当时觉得).看着自己的代码风格变化天翻地覆,无奈感叹时间飞逝...算了少矫情管他的先A了再说(ง •̀_•́)ง 先 ...
最新文章
- MATLAB 循环子字符串
- oracle实例是否有dbid,Oracle如何获得数据库的DBID
- oracle mysql 数据类型对比_Oracle、SQL Server、MySQL数据类型对比
- 项目经理的软技能提升——知行合一
- 设计模式13_享元模式
- 杭州师范大学计算机考研难度,杭州师范大学网络空间安全考研难吗
- 玩html5游戏用什么浏览器,玩HTML5游戏测浏览器傲游3最新版给力
- EXCEL VBA连接SQL数据库
- 第1篇:熊猫烧香之手动查杀
- 数电实验(二)利用8选1数据选择器74LS151设计四舍五入判别电路
- c语言编程学习入门指南
- 去除html中的font标签的正则表达式
- 《跑步人生》 作者:村上春树
- allt什么意思_all是什么意思_all怎么读_all翻译_用法_发音_词组_同反义词_全部的-新东方在线英语词典...
- 个人微信公众号申请流程
- Java生成ics文件
- 减半技术实现求a的n次幂
- 英语学习/词典app——top5
- Swiperjs插件轮播滑动卡顿优化
- Android中集成支付宝