C. Li Hua and Chess(交互 + 思维)

Problem - C - Codeforces

这是一个互动的问题。李明和李华在玩游戏。李华有一个大小为n × m的棋盘,用(r, c) (1 S r S n, 1≤c≤m)表示上的单元格上面的第r行左边的第c列。李明在棋盘上放了一个王,李华需要猜它的位置。李华最多只能问李明3个问题。在每个问题中,他可以选择一个单元格,并询问移动该单元格所需的最小步骤国王到选定的牢房。每个问题都是独立的,这意味着国王实际上不会动。国王可以从(z,y)移动到(æ',y')当且仅当max{lz-x'l, ly-y'l} = 1(如下图所示)。

国王的位置是在互动之前选定的。假设你是李华,请解决这个问题。交互第一行包含测试用例的数量t(1≤t≤103)。每个测试用例的第一行包含两个整数n, m (1 < n, m < 10°)——棋盘的大小,然后交互开始。要问问题,请打印“?”r c”(不带引号,1 <r n,1 < c m),然后输入标准输入的响应- king移动到所选单元格所需的最小步长。如果你的程序问了一个无效的问题,或者已经没有问题了,交互器将立即终止,你的程序将得到一个错误答案。要给出最终答案,请打印“!”C”(不带引号,(r, C)是国王的初始坐标)。请注意,给出这个答案不计入3个问题的限制。问完一个问题后,不要忘记输出行尾并刷新输出。否则,您将得到闲置限制超过。要做到这一点,请使用:fflush(stdout) 或 cout.flush() inC++;Java中的System.out.flush ();Pascal中的flush(输出);stdout。Python中的flush ();有关其他语言,请参阅文档。黑客要破解,请使用以下格式。第一行应该包含一个整数t (1 < t < 103)。每个测试用例的第一行和唯一一行应该包含四个整数n, m, r,c (1 <r < n < 10°,1≤c≤m < 10°)。

Example

input

Copy

2
3 4

1

2

5 3

3

1

2

output

Copy

? 2 3

? 2 4

! 2 2

? 2 2

? 5 2

? 5 3

! 5 1

题解:

我们可以首先取左上,与右下两个顶点,得到这两个点到目标点的距离a,b,由于是国王,所以八个方向均可走,所有点到这我们取两个点的的距离为a,b的,可以构成两个正方形

如果两个正方形有交边,那么目标点肯定在,那条边上,那我们就已经确定了x轴或y轴的坐标

再询问一下目标点到(x,1),或(1,y)的距离即可

当然还有两个正方形相交的情况,通过观察,我们发现,这样的目标点,只可能在左下,或右上这些部分

所以我们判断一下到底是在左下还是右上即可,限制一下左下的情况,如果目标点到,我们的所求的点距离为0,肯定是在左下,否则反转180度在右上

#include <cstdio>
#include <cstring>
#include <algorithm>
#include<iostream>
#include<vector>
#include<set>
#include<map>
using namespace std;
typedef long long ll;
//#define int long long
int ask(int x,int y)
{
	cout <<"? " << x <<" "<<y <<"\n";
	int ans;
	cin >>  ans;
	return ans;
}
void solve()
{
	int n,m;
	cin >> n >> m;
	int a = ask(1,1); 
	int b = ask(n,m);
	int x,y;
	if(a +b == n - 1)
	{
		x = 1 + a;
		y = 1 + ask(x,1);
	}
	else if(a + b == m - 1)
	{
		y = 1 + a;
		x = 1 + ask(1,y);
	}
	else
	{
		if(a + 1 <= n&&m - b >= 1&&ask(a + 1,m - b) == 0)
		{
			x = a + 1;
			y = m - b;
		}
		else
		{
			y = a + 1;
			x = n - b;
		}
	}
	cout << "! " << x <<" "<<y <<"\n";
}

signed main()
{
//	ios::sync_with_stdio(0);
//	cin.tie(0);cout.tie(0);
	int t = 1;
	cin >> t;
	while(t--)
	{
		solve(); 
	}
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值