Educational Codeforces Round 99 (Rated for Div. 2) B
大意
初始位于0,假设第 (i) 次操作时在点 (p) ,那么可以向后变为 (p-1) 或向前 (p+i) 。
问:
到点 (x) 最少需要多少次操作。
思路
30min。
假设第 (k) 次操作时在位置 (p) ,此时我们首次向后到 (p-1) ,考虑后续位置的变化。
显然,第 (k+1) 次操作如果向前会让我们到 (p) ,第 (k+2) 次操作如果向前我们会到 (p+k+2) 。
如果我们在第 (k) , (k+1) , (k+2) 次向前的话,我们会到 (p+k) , (p+k+1) , (p+k+2+k+1) 。
对比第 (k) 次操作的两种选择,可以发现,如果我们在第 (k) 次向后,在其他的选择都相同的情况下,会比在第 (k) 次向前损失 (k+1) 步。
因为向后损失 (1) ,向前增加 (k) ,所以总差距 (k+1) 。
考虑一直向前走,直到位置大于等于 (x) ,假设此时为第 (k) 次操作完后,位置为 (r) 。
如果 (x = r) ,我们幸运地找到了最小次数。
否则,首先考虑 (r-x = 1) ,此时不存在 (e) ,让我们在将第 (e) 次操作由向前修改为向后之后能让 (r=x) ,所以只能向后再走一步。
对于剩下的情况,存在 (e = r-x-1) ,我们将第 (e) 次由向前修改为向后,位置会减少 (r-x) 。
代码
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std;
#define ll long long
#define ull unsigned long long
#define cint const int&
#define Pi acos(-1)
const int mod = 998244353;
const int inf_int = 0x7fffffff;
const ll inf_ll = 0x7fffffffffffffff;
const double ept = 1e-9;
int t;
int main() {
cin >> t;
int x;
while(t--) {
int i, b=0;
cin >> x;
for(i=1; b<x; i++) {b+=i;}
if(x == b) cout << i-1 << endl;
else {
if(b-x > 1) cout << i-1 << endl;
else cout << i << endl;
}
}
return 0;
}