描述

国王将金币作为工资,发放给忠诚的骑士。第一天,骑士收到一枚金币;之后两天(第二天和第三天),每天收到两枚金币;之后三天(第四、五、六天),每天收到三枚金币;之后四天(第七、八、九、十天),每天收到四枚金币……;这种工资发放模式会一直这样延续下去:当连续N天每天收到N枚金币后,骑士会在之后的连续N+1天里,每天收到N+1枚金币。

请计算在前K天里,骑士一共获得了多少金币。

#include <stdio.h>
int main()
{
int i=0,t=1,n,sum; //i金币数,t真实天数,j假设天数,n为结束天数
scanf("%d",&n);
for(i=1;t<=n;i++) //循环条件并不是i;
{
int j = 0;
for(j=1;j<=i;j++)
{
if(t>n) //此处只能是t>n,否则死循环;
break;
sum+=i;
t++; //天数++
}
}
printf("%d",sum);
return 0;
}


解题思路就是一个真实天数t在每一次假设天数j循环都要++一次,而假设天数j不会大于应发金币数i,且j每一次循环完都要让金币i++,这是找规律的方法,感觉上还是数学比较重要,完全可以套用公式,一步到位。

1.天数(正好以k个金币结束的那一天n):

1+2+3+...+k=(k+1)k/2=n;      

2.金币数(正好以k个金币结束的那一天n):

1²+2²+3²+...+k²=k(k+1)(2k+1)/6;

//注意到

(1+k)k/2=n;

所以

k=sqrt(8n+1)/2-1/2=(sqrt(8n+1)-1)/2;

此时           

sqrt(1+8*n)==1.0*int(sqrt(1+8*n)
int k=(sqrt(1+8*n)-1)/2;

所以直接输出

sum=k(k+1)(2k+1)/6;

3.不满足刚好结束的那一天:

               

sqrt(1+8*n)!=1.0*int(sqrt(1+8*n)

那就输出

                   int k=(sqrt(1+8*n)-1)/2;
sum+=(k*(k+1)*(2*k+1))/6;
sum+=(n-(k*(k+1)/2))*(k+1);

输出sum;

数学需要推导和逻辑,越大的项目逻辑越缜密,前期注重语法,越到后面越要主义逻辑和数学能力的培养。