传送门:codeforces 716C
题目大意:
游戏开始时你在第 1 级,有个数字为 2。当你在第 k 级时,你可以进行以下两种操作:数字+k,或者当数字可开平方时将其开平方。
当数字 +k 时,要求 +k 后的数字是当前级 k 的倍数,当数字开平方时,要求开平方后的数字是下一级 (k+1)的倍数,并且到达下一级。
问从第 1 级到第 n+1 级,每次进行的 +k 的次数为多少次。答案不要求是最优的。
思路:
由于不要求答案是最优解,所以我们只需要找到一个可行解即可。先来解决 +k 后的数要求是 k 的倍数的问题,既然到达第 k 级的数是上一层的数开平方得来的,并且是 k 的倍数,所以 +k 后也是 k 的倍数。
然后我们来求第 k 层的数进行几次 +k 后的结果是 (k+1)^2 的倍数呢?注意,我们不需要求最优解。答案是 lcm(k,k+1) 的平方,因为他既是 k 的倍数,又是 (k+1)^2 的倍数。lcm表示两数的最小公倍数。
然后求进行了多少次 +k 操作,答案为 ( lcm(k,k+1)^2 - 第 k 层第一个数 ) / (k).
注意:
1.因为 k 和 k+1 一定互素,所以他们的最小公倍数为 k*(k+1)。
2.得到的步数会超 long long,所以可以选择用 java 或者 python 解决大数问题。
代码:
//C语言版,会超时
#include<stdio.h>
typedef long long LL;
int main()
{
LL i,n,cc,tmp,ans;
while(~scanf("%lld",&n))
{
cc=2; //数字初始化为2
for(i=2;i<=n+1;i++)
{ //从第二级开始
tmp=i*(i-1);
tmp=tmp*tmp; //lcm(i,i-1)^2
ans=(tmp-cc)/(i-1); //计算 +k的次数
printf("%lld\n",ans);
cc=i*(i-1); //下一行的数
}
}
return 0;
}
n=input()
cc=2
for i in range(2,n+2):
tmp=i*(i-1)
tmp=tmp*tmp
ans=(tmp-cc)/(i-1)
print ans
cc=i*(i-1)