目录
一、题目介绍
二、题目要求
三、解题思路
四、代码演示
一、题目介绍
国王将金币作为工资,发放给忠诚的骑士。
第一天,骑士收到一枚金币;之后两天(第二天和第三天),每天收到两枚金币;之后三天(第四、五、六天),每天收到三枚金币;之后四天(第七、八、九、十天),每天收到四枚金币……;这种工资发放模式会一直这样延续下去。
当连续N天每天收到N枚金币后,骑士会在之后的连续N+1天里,每天收到N+1枚金币。
请计算在前K天里,骑士一共获得了多少金币。
题目来源 :牛客 BC96
二、题目要求
输入描述:
输入只有1行,包含一个正整数K,表示发放金币的天数。
输出描述:
输出只有1行,包含一个正整数,即骑士收到的金币数。
三、解题思路
如上图所示,类似于一个三角形的尖塔,每一行的项数和行数一致,每一行项数所代表的金币数量和行数一致。
因此,可以借着衍射出是一种 行数×项数 的问题,即可 i * j 或者 i * i
也因此,我们可以把行数设置为金币数,当一行的项数全部走完时,才能进入下一行,金币数才能增加,而项数则设置为天数,每走完一项,便走过一天。
而且随着向规定的天数不断靠近,可走的项数是不断地在减少的,所以需要进行天数的判断,判断剩余的天数是否能走完这一行的所有项。
转化为数学模型:
设 k 为天数。
设 i 为项数,同时 i 也表示行数 ,表示金币数。
i * i 是一个完整走完一行所有项的一个金币数,表示一行的金币数总量。
sum = 1 * 1 + 2 * 2 + 3 * 3 + 4 * 4 +…………+i * i (k>=i)——表示一行的项数能够走完
sum = 1 * 1 + 2 * 2 + 3 * 3 + 4 * 4 +…………+ k * i (k<i) ——表示一行走不完,有剩余的天数
四、代码演示
int main()
{
int k;
int i = 1;
int result = 0;
scanf("%d", &k);
while (k > 0)
{
if (k >= i)
result += i * i;
else
result += k * i;
k -= i; //天数在不断的减少
i++; //完成 一行后 金币数需要加1
}
printf("%d\n", result);
return 0;
}
//k > = i 表示当天数大于等于项数时,可以走完一行,所以使用 i * i ,行数(金币数) × 项数
//k < i 表示当天数小于项数时,则要求该项所在的行数(金币数) * 天数 得到剩余天数的所有金币