基本思路
确定一个点位置,在这道题中主要是采用了问答的形式,主要思想还是,在二维有界网格中,已知一个未知点距离一个角落点的距离,可以确定这个未知点所在的一条直线,同理,只需要询问两个角落点,即可通过两个直线的交叉点确定,这道题即是这个推论的拓展应用。
本题注意点
cout输出后如果要刷新缓冲区,应该使用endl或者cout.flush(),不能使用fflush(stdout)
而printf输出后如果要刷新缓冲区,应该使用fflush(stdout);
本题具体想法
询问(1,1),(1,m),(n,1)三个点,得到三个值,确定三条直线,两个可疑交点,然后询问其中一个可疑交点,得出结果。
#include "bits/stdc++.h"
using namespace std;
using ll = long long;
#define For for(int i=1;i<=n;i++)
#define rFor for(int i=n;i>0;i--)
#define Whole(x) for(auto item:x)
const int N = 2e5;
int row, col;
int query(int x, int y) {
::printf("? %d %d\n", x, y);
fflush(stdout);
int res;
cin >> res;
return res;
}
void output(int x, int y) {
::printf("! %d %d\n", x, y);
fflush(stdout);
}
void inline solve() {
cin >> row >> col;
int a = query(1, 1);
if (!a) {
output(1, 1);
return;
}
int b = query(1, col);
if (!b) {
output(1, col);
return;
}
int d = query(row, col);
if (!d) {
output(row, col);
return;
}
double x1 = (a + 3 - col + b) / 2.0, y1 = (a + 1 + col - b) / 2.0, x2 = (row + 1 + b - d) / 2.0, y2 = col + (row - 1 - b - d) / 2.0;
int ans = -1;
if (x1 == (int)x1 && y1 == (int)y1 && x1 >= 1 && y1 >= 1 && x1 <= row && y1 <= col) {
ans = query(x1, y1);
}
if (ans) {
output(x2, y2);
} else output(x1, y1);
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
int num = 1;
cin >> num;
while (num--) {
solve();
}
return 0;
}