1. 程式人生 > 實用技巧 >Educational Codeforces Round 99 (Rated for Div. 2) B

Educational Codeforces Round 99 (Rated for Div. 2) B

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;
}