【MX-J1】梦熊周赛 · 入门组 1 & Flanksy Round III(同步赛) A题
【MX-J1-T1】『FLA - III』Spectral
题目背景
没有看到昂星团。
题目描述
有一团火,最开始它的温度是 0 0 0,火焰旁边有 n n n 个炭块,每块炭都有 k k k 点能量。
使用 T i T_i Ti 表示烧掉 i i i 块炭后火焰的温度,有:
T i = { 0 i = 0 k + T i − 1 i i ≠ 0 T_i = \begin{cases} 0 & i = 0 \\ k+ \dfrac{T_{i-1}}{i} & i \neq 0 \end{cases} Ti=⎩ ⎨ ⎧0k+iTi−1i=0i=0
火焰能够达到的最高温度是多少?
输入格式
本题有多组测试数据。
第一行输入一个正整数 T T T,表示测试数据组数。
对于每组测试数据,输入一行两个正整数 n , k n,k n,k。
输出格式
对于每组测试数据,输出一行一个实数表示火焰能达到的最高温度,四舍五入到小数点后 1 1 1 位。
样例 #1
样例输入 #1
2
1 6
2 7
样例输出 #1
6.0
10.5
提示
「样例解释 #1」
对于第一组测试数据,有 1 1 1 块炭,未烧炭时火焰温度为 0 0 0,烧掉 1 1 1 块炭后火焰温度为 6 6 6,答案为 6.0 6.0 6.0。对于第二组测试数据,有 2 2 2 块炭,未烧炭时火焰温度为 0 0 0,烧掉 1 1 1 块炭后火焰温度为 7 7 7,烧掉 2 2 2 块炭后火焰温度为 10.5 10.5 10.5,答案为 10.5 10.5 10.5。
「数据范围」
测试点编号 | T ≤ T \leq T≤ | $n \leq $ | k ≤ k \leq k≤ |
---|---|---|---|
1 ∼ 2 1 \sim 2 1∼2 | 5 5 5 | 2 2 2 | 10 10 10 |
3 ∼ 4 3 \sim 4 3∼4 | 5 5 5 | 1 0 7 10^7 107 | 1 0 9 10^9 109 |
5 5 5 | 1 0 5 10^5 105 | 1 0 9 10^9 109 | 1 0 9 10^9 109 |
对于 100 % 100\% 100% 的数据, 1 ≤ T ≤ 1 0 5 1 \leq T \leq 10^5 1≤T≤105, 1 ≤ n , k ≤ 1 0 9 1 \leq n,k \leq 10^9 1≤n,k≤109。
做题思路
首先看测试数据,最大的
n
n
n为
1
0
9
10^9
109,而最多有
1
0
5
10^5
105组测试。
所以这题直接通过式子递推出答案在时间上是不允许的,所以大概率是数学/规律题。
那么观察式子
T
i
=
{
0
i
=
0
k
+
T
i
−
1
i
i
≠
0
T_i = \begin{cases} 0 & i = 0 \\ k+ \dfrac{T_{i-1}}{i} & i \neq 0 \end{cases}
Ti=⎩
⎨
⎧0k+iTi−1i=0i=0
T
0
=
0
T_0 = 0
T0=0
T
1
=
k
+
T
0
=
k
T_1 = k + T_{0} = k
T1=k+T0=k
T 2 = k + 0.5 k = 1.5 k T_2 = k + 0.5k = 1.5k T2=k+0.5k=1.5k
T 3 = k + T 2 3 = k + 1.5 k 3 = 1.5 k T_3 = k + \dfrac{T_{2}}{3} = k + \dfrac{1.5k}{3} = 1.5k T3=k+3T2=k+31.5k=1.5k
T 4 = k + 1.5 k 4 = 1.375 k T_4 = k + \dfrac{1.5k}{4} = 1.375k T4=k+41.5k=1.375k
T
5
=
k
+
1.375
k
5
=
1.275
k
T_5 = k + \dfrac{1.375k}{5} = 1.275k
T5=k+51.375k=1.275k
…
依次类推发现规律当
n
n
n能取到2时候有最大值
1.5
k
1.5k
1.5k,否则为
k
k
k
利用matlab进行模拟式子
y = [1];
x = 1:1e5;
for i = 2:1e5
ty = 1 + y(i-1)/i;
y = [y,ty];
end
plot(x,y);
得出结果和分析的一样
并且观察到越往后越趋近于 k k k
时间复杂度分析
每组测试时间复杂度为
O
(
1
)
O(1)
O(1)
总时间复杂度为
O
(
T
)
O(T)
O(T)
伪代码
代码
#include<iostream>
using namespace std;
int _, n, k;
int main() {
cin >> _;
while (_--) {
cin >> n >> k;
if(n==1)
printf("%.1f\n",k*1.0);
else
printf("%.1f\n",k*1.5);
}
return 0;
}