解题报告(2)——动态分班
2016-11-04 23:54
176 查看
解题报告(2)——动态分班
动态分班
题目描述
某中学对班级实行动态管理,每学年结束后都要重新分配班级,但这所学校重新分配的方法和石室中学完全不同。
现在给出一些属于同一年级学生的连续编号,它们都是从 A 到 B 的整数。一开始每个编号都属于各自不同的班(即一个班只有一个学生),然后学校将进行以下的调整:每次选择两个属于不同班的编号,如果这两个编号拥有大于或等于 P 的公共质因数,那么就把她们所在的班合并成一个班。反复上述操作,直到没有可以合并的班为止。
现在请你求出最后这个年级有多少个班?
输入格式
一行,三个整数 A,B,P,其中 A≤B≤100000,2≤P≤B。
输出格式
一个数表示最终班的个数。
样例数据 1
输入
10 20 3
输出
7
备注
【样例说明】
样例解释:最后只有 7 个班:{10,20,12,15,18},{11},{13},{14},{16},{17},{19}
【数据规模】
有80% 的数据 B≤1000 , 100%的数据 B≤100000
算法分析:
方法一: 打表+并查集
1)打表找出2到100000的全部质数,定义在数组里。
2)找出a到b范围内的每一个质数的第一个倍数。
3)并查集合并该质数a到b范围内的全部倍数。
4)统计集合个数。
Source:
略
方法二:筛选法+并查集
1)用筛选法找出2到b的全部质数,收录在数组里。
2)找出a到b范围内的每一个质数的第一个倍数。
3)并查集合并该质数a到b范围内的全部倍数。
4)统计集合个数。
Source:
[align=left]
[/align]
Summary:
本题从难度上而言,并不算太难,但是涉及到的知识较多,并且处理起来也容易因找不到合适方法而做过多无用功增加复杂度。两种方法比较,显然后者是标准,但是有时若在重要考试中出现问题,也可以采取第一种打表方式,先编写程序求出相应的值,在做处理,可以节约时间,从而不影响后面的计算和考虑。当然,必要的算法积累也很重要。
[align=center]
[/align]
[align=center]
[/align]
动态分班
题目描述
某中学对班级实行动态管理,每学年结束后都要重新分配班级,但这所学校重新分配的方法和石室中学完全不同。
现在给出一些属于同一年级学生的连续编号,它们都是从 A 到 B 的整数。一开始每个编号都属于各自不同的班(即一个班只有一个学生),然后学校将进行以下的调整:每次选择两个属于不同班的编号,如果这两个编号拥有大于或等于 P 的公共质因数,那么就把她们所在的班合并成一个班。反复上述操作,直到没有可以合并的班为止。
现在请你求出最后这个年级有多少个班?
输入格式
一行,三个整数 A,B,P,其中 A≤B≤100000,2≤P≤B。
输出格式
一个数表示最终班的个数。
样例数据 1
输入
10 20 3
输出
7
备注
【样例说明】
样例解释:最后只有 7 个班:{10,20,12,15,18},{11},{13},{14},{16},{17},{19}
【数据规模】
有80% 的数据 B≤1000 , 100%的数据 B≤100000
算法分析:
方法一: 打表+并查集
1)打表找出2到100000的全部质数,定义在数组里。
2)找出a到b范围内的每一个质数的第一个倍数。
3)并查集合并该质数a到b范围内的全部倍数。
4)统计集合个数。
Source:
略
方法二:筛选法+并查集
1)用筛选法找出2到b的全部质数,收录在数组里。
2)找出a到b范围内的每一个质数的第一个倍数。
3)并查集合并该质数a到b范围内的全部倍数。
4)统计集合个数。
Source:
Source: #include #include #include #include #include #include using namespace std; int a,b,p,d[100001],father[100001],cnt; /*a,b:数据范围; p:质数范围*/ /*farher:并查集实现,当前所在集合; cnt:统计质数个数*/ bool f[100001],an[100001]; /*f[i]:筛选法应用,判断是否为质数; an[i]:判断该集合是否出现过*/ inline void R(int &v) /*读入优化*/ { v=0; char c=0; bool p=true; while(c>'9'||c<'0') { if(c=='-') { p=false; } c=getchar(); } while(c<='9'&&c>='0') { v=(v<<3)+(v<<1)+c-'0'; c=getchar(); } if(p==false) { v=-v; } } int getfather(int x) /*并查集核心代码*/ { if(father[x]==x) { return x; } else { father[x]=getfather(father[x]); /*路径压缩+答案查询*/ } return father[x]; } void unite(int x,int y) /*合并两个集合*/ { int fa1,fa2; fa1=getfather(x); fa2=getfather(y); if(fa1!=fa2) { father[fa2]=fa1; } } int main(void) { R(a); R(b); R(p); memset(f,true,sizeof(f)); /*初始化质数判断*/ f[1]=false; /*1不为质数,单独处理*/ for(int i=2;i<=b;++i) /*筛选法求质数*/ { if(f[i]==true) /*没有之前的因数,则为质数*/ { cnt++; /*个数统计加1*/ d[cnt]=i; /*记录*/ for(int j=2;j<=b/i;++j) /*将该数的倍数在b以内的筛掉*/ { f[i*j]=false; } } } for(int i=a;i<=b;++i) /*初始化父亲的值*/ { father[i]=i; } for(int i=1;i<=cnt;++i) /*枚举质数*/ { if(d[i]>=p) /*若出现在范围内*/ { int y; y=a/d[i]*d[i]; if(y
[align=left]
[/align]
Summary:
本题从难度上而言,并不算太难,但是涉及到的知识较多,并且处理起来也容易因找不到合适方法而做过多无用功增加复杂度。两种方法比较,显然后者是标准,但是有时若在重要考试中出现问题,也可以采取第一种打表方式,先编写程序求出相应的值,在做处理,可以节约时间,从而不影响后面的计算和考虑。当然,必要的算法积累也很重要。
[align=center]
[/align]
[align=center]
[/align]
相关文章推荐
- 动态规划求编辑距离——算法解题报告
- HDU-1078___FatMouse and Cheese —— 解题报告 dp动态数组
- hud 1467(动态规划。解题报告)
- 【算法学习笔记】27.动态规划 解题报告 SJTU OJ 1254 传手绢
- 动态规划求编辑距离——算法解题报告
- 动态规划 POJ1141 Brackets Sequence 解题报告
- 2014 UESTC暑前集训动态规划专题解题报告
- Leetcode 120. Triangle 三角形问题(动态规划经典) 解题报告
- 动态树 解题报告
- POJ 3784 对顶堆动态维护中位数 解题报告
- 【解题报告】HDU 4631 Sad Love Story 最短点距(动态)
- 【动态点分】绿老师 解题报告
- 【动态点分】绿老师 解题报告
- 最少拦截系统之动态规划解题报告
- 【算法学习笔记】23.动态规划 解题报告 SJTU OJ 1280 整装待发
- 【算法学习笔记】23.动态规划 解题报告 SJTU_OJ 1280 整装待发
- 动态规划解乘法表问题——算法解题报告
- 第一次动态规划..类解题报告..
- 动态规划解机器调度问题——算法解题报告
- acm动态规划之LCS最长公共子串uva10405Longest Common Subsequence解题报告