题目描述:
妈妈给小B买了N块糖!但是她不允许小B直接吃掉。
假设当前有M块糖,小B每次可以拿P块糖,其中P是M的一个不大于根号下M的质因数。这时,妈妈就会在小B拿了P块糖以后再从糖堆里拿走P块糖。然后小B就可以接着拿糖。
现在小B希望知道最多可以拿多少糖。
解题思路:
1、除了最后剩下的数目为质数的糖果,可获得其余糖果数的一半。所以剩下的越少,小B获得的越多。即目标为使剩余糖果书尽量少。
2、分两种情况:(1)糖果能分完,剩余0;(2)不能分完,剩余数目尽量少。
3、能分完的条件:
m=2*p
p<=sqrt(m),即p*p<=m
解得p = 2,m = 4
即某次剩余4个糖果时可以分完,小B获得n/2个。
进一步,某次糖果数m为4的倍数,每次都分2个,则必最终m=4。如m = a*4,让p=2,则下一次m=(a-1)*4。
再进一步,m如果能分解为m=2*a*b,即使m不是4的倍数,如a、b都是奇数,同样能分完。令p=a,下一个m1=2*a*b-2*a=2*a*(b-1),此时m1就成了4的倍数。
综上可得能分完时n的限制条件:n和n/2均不是质数。
4、不能分完如何处理:
不能分完时要使剩下的数量尽量少。
如n=3*5*7=105,此时每次取3个,即p=3,则最终必然剩余3个。当p=a时,总有m=a*(b-2),最后一次分完后只剩下a个,所以要尽量使每次分的个数p为最小质因数。
即不能分完时,应每次分m的最小质因数个糖。
如n=5*5时,p=5
m1=25-2*5=15=3*5,p1=3;
m2=15-2*3=9=3*3,p2=3;
m3=9-2*3=3
剩余3个,小B获得(25-3)/2=11个
参考代码:
1、判断 n 在 m 以内有没有质因数
int prime(int n,int m) {
int i;
int t = 0;
for (i=2;i<m;i++) {
if (n%i==0) {
t = i;
break;
}
}
return t;
}2、将 m=a*b 进行递归,每次取m的最小质因数a个糖
int f(int a, int b) {
if (b<2) {
return a*b; //返回最终剩余糖数
}
int t = prime(b,a); //如果m有比a小的质因数,a取最小质因数的值,继续递归
if (t) {
a = t;
b = a*b/t;
}
f(a,b-2);
}3、主程序
int main()
{
int n,m,i;
scanf("%d",&n);
m = n;
if (n%2==0 && prime(n/2,n/4+1)) { //判断能否分完,分完标志为其中一次m为4的倍数
m = 0;
}
else {
for (i=2;i<n/2;i++) { //分不完时,每次去最小质因数个糖
if (n%i==0) {
break;
}
}
m = f(i,n/i);
}
printf("%d",(n-m)/2);
return 0;
}0.0分
5 人评分
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程
发表评论 取消回复