思路:
这题很明显就是二分,感觉自己对二分的理解不够,导致比赛时调了一个小时还没有出来。这里我们把整个2*k-1行字符的前缀和当做一个单调递增的序列,这样就符合了二分的性质,然后先判断2*k-1行的和是否超过x,没有就直接输出2*k-1,否则二分计算答案,对于每一个mid,我们判断是否超过k,没超过的部分和超过的部分分别进行等差数列求和,加起来就是从第一行到这行的总数。
代码:
#include <bits/stdc++.h> #define ll long long using namespace std; typedef pair<int, int> PII; const int N = 1000, mod = 998244353; ll k, x; int n; int a[N]; //记得开long long ll cal(ll mid) { ll res = 0; if(mid <= k) return (1 + mid) * mid / 2; else { ll sum = (1 + k) * k / 2; res = sum; mid -= k; return res + (k - 1 + k - mid) * mid / 2; } } void solve() { cin >> k >> x; if(cal(2 * k - 1) > x) { ll l = 1, r = 2 * k - 1; while (l < r) { int mid = l + r >> 1; if (cal(mid) >= x) r = mid; else l = mid + 1; } cout << r << endl; return; } cout << 2 * k - 1 << endl; } int main() { ios::sync_with_stdio(0); int T; cin >> T; while(T --) { solve(); } return 0; }