G2. Ruler (hard version)
思路:
hard和easy版的区别就是从10次查询变成7次。如果是10次,那么可以每次查询一个正方形用二分的方法容易的做出来。 如果是7次,可以用类似于三分的方法,查询
l
×
r
l\times r
l×r的矩形的结果q:
若
q
=
l
m
∗
r
q= lm*r
q=lm∗r 则
x
>
r
m
x>rm
x>rm
若
q
=
l
m
∗
(
r
m
+
1
)
q=lm*(rm+1)
q=lm∗(rm+1) 则
l
m
<
x
<
=
r
m
lm<x<=rm
lm<x<=rm
若
q
=
(
l
m
+
1
)
∗
(
r
m
+
1
)
q=(lm+1)*(rm+1)
q=(lm+1)∗(rm+1) 则
x
>
=
l
m
x>=lm
x>=lm
log 2 1000 ≈ 9.966 , log 3 1000 ≈ 6.288 \log_2 1000 \approx 9.966,\log_3 1000 \approx 6.288 log21000≈9.966,log31000≈6.288 次数满足题目要求。
代码:
//三分(hard version)
#include <bits/stdc++.h>
#define endl '\n'
typedef long long ll;
using namespace std;
void solve();
signed main() {
cin.tie(0)->ios::sync_with_stdio(0);
int T = 1;
cin >> T;
while (T--) {
solve();
}
return 0;
}
int query(int a, int b) {
printf("? %d %d\n", a, b);
fflush(stdout);
int response;
cin >> response;
return response;
}
//bool check(int mid) {
// if (query(mid, mid) != mid * mid) {
// return true;
// }
// return false;
//}
void solve() {
int l = 2, r = 999;
while (l < r) {
int lm = l+(r-l) / 3 ,rm = l+(r-l)*2/3;
int q =query(lm,rm);
if (q==lm*rm) {
l = rm + 1;
} else if(q==(lm+1)*(rm+1)){
r = lm;
} else{
l=lm+1;
r=rm;
}
}
printf("! %d\n", l);
fflush(stdout);
}