Tokitsukaze 想知道棋盘的边长
第一行包含一个整数(
) --- 测试数据的组数。
对于每组测试数据:
第一行包含两个整数,
(
,
) --- 两种颜色的棋子数。
对于每组测试数据,输出一行,每行包含一个整数表示答案。
2 4 5 0 6
3 4
第一组测试数据,我们只能这样摆:第二组测试数据,我们可以这样摆:
int n = (int)Math.ceil(Math.sqrt(Math.max(a, b) * 2 - 1)); if (a + b > n * n) n++;如果只想要AC,到此就可以结束了,但是……如果想要快呢?
#include <bits/stdc++.h>
using namespace std;
#define int long long
using PII = pair<int, int>;
void solve() {
int a, b;
cin >> a >> b;
if (a < b) swap(a, b);
int l = 1, r = 1e5;
while (l < r) {
int mid = (l + r) >> 1;
int all = mid * mid;
int t1 = all / 2, t2 = all / 2 + (all & 1);
if (t2 >= a && t1 >= b) r = mid;
else l = mid + 1;
}
cout << l << '\n';
}
int32_t main() {
ios::sync_with_stdio(0);
cin.tie(0);
int T = 1;
cin >> T;
while (T--) {
solve();
}
} 1.最简单的二分想法,复杂度TlogA
2.其实可以TlogT离线,预处理1e5以内的答案然后双指针
3.也可以T,注意到只需要大的放下就行,算一下sqrt(2a)然后O(1)调一下就行
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define ld long double
#define debug(x) cerr << #x << ": " << x << '\n';
const int INF = 0x3f3f3f3f3f3f3f3f;
//倒序不要忘记是--不是++
const int N=505050;
int fac[N];
void solve(){
int a,b;cin>>a>>b;
int mx=max(a,b);
auto it=lower_bound(fac,fac+N,mx)-fac;
if((it&1)&&(a==b)&&mx==fac[it]){
cout<<it+1<<"\n";
}
else cout<<it<<"\n";
}
signed main(){
std::ios_base::sync_with_stdio(false);
std::cin.tie(nullptr);
int t = 1;
cin>>t;
for(int i=1;i<=N-1;i++) fac[i]=(i*i+1)/2;
while(t--){
solve();
}return 0;
}