Description:
题目大意:你站在 X 轴上,你想去 x 点。你有两种跳法,假设你在 y 点,跳第 k 次:
- 可以跳到 y+k 点
- 可以跳到 y-1 点
你跳到 x 点需要最少多少次?
解题思路:
算法标签:构造,math
当 x 点大于当前点 pos,选择 +k 操作,直到 pos = 1 + 2 + 3 + … + steps =
s
t
e
p
s
(
1
+
s
t
e
p
s
)
2
≥
x
\frac{steps(1 + steps)}{2} \geq x
2steps(1+steps)≥x,显然
0
≤
p
o
s
−
x
<
s
t
e
p
0 \leq pos-x < step
0≤pos−x<step,否则我们不可能操作上一步,相当于循环条件。
如果 pos = x,显然我们已经找到了答案。
如果 pos
≠
\neq
= x。设 k
∈
\in
∈ [1,steps],pos’
∈
\in
∈ [pos - steps - 1,pos - 2],当用 -1 代替 +k,pos’ = pos - k - 1
由上可知,pos - x < steps,所以如果 x < pos - 1 ,可以使用相应的 k =pos - x - 1,用 -1 代替它,便可以得到 x。如果 x + 1 = pos,再需要操作 -1 即可,因为 k
≠
\neq
= 0。
所以,我们主要任务就是找到 steps, 由$\frac{steps(1 + steps)}{2} \geq x可知,steps(steps+1)
≤
\leq
≤(step+1)2
≤
\leq
≤ 2x,即可求得 steps。
代码:
// freopen("Data_in.txt","r",stdin);
// freopen("Data_out.txt","w",stdout);
// int 10^9
// long 10^18
// next_permutation(number,number+length)
//#include <bits/stdc++.h>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
#include <map>
#include <stack>
#include <cmath>
#include <queue>
using namespace std;
#define LL long long
const int N = 200005;
int main()
{
int T = 0;
int x = 0;
int steps = 0;
//freopen("Data_in.txt","r",stdin);
cin>>T;
while(T--) {
scanf("%d",&x);
steps = 0;
while(steps * (steps + 1) < 2 * x)
steps++;
if((steps * (steps+1) / 2) == x + 1)
steps++;
cout<<steps<<endl;
}
return 0;
}