Loading

2021-2022 ICPC, NERC, Northern Eurasia Onsite I. Interactive Treasure Hunt(交互)

This is an interactive problem.*

There is a grid of 𝑛×𝑚n×m cells. Two treasure chests are buried in two different cells of the grid. Your task is to find both of them. You can make two types of operations:

  • DIG 𝑟r 𝑐c: try to find the treasure in the cell (𝑟,𝑐)(r,c). The interactor will tell you if you found the treasure or not.
  • SCAN 𝑟r 𝑐c: scan from the cell (𝑟,𝑐)(r,c). The result of this operation is the sum of Manhattan distances from the cell (𝑟,𝑐)(r,c) to the cells where the treasures are hidden. Manhattan distance from a cell (𝑟1,𝑐1)(r1,c1) to a cell (𝑟2,𝑐2)(r2,c2) is calculated as |𝑟1−𝑟2|+|𝑐1−𝑐2||r1−r2|+|c1−c2|.

You need to find the treasures in at most 7 operations. This includes both DIG and SCAN operations in total. To solve the test you need to call DIG operation at least once in both of the cells where the treasures are hidden.

Interaction

Your program has to process multiple test cases in a single run. First, the testing system writes 𝑡t — the number of test cases (1≤𝑡≤1001≤t≤100). Then, 𝑡t test cases should be processed one by one.

In each test case, your program should start by reading the integers 𝑛n and 𝑚m (2≤𝑛,𝑚≤162≤n,m≤16).

Then, your program can make queries of two types:

  • DIG 𝑟r 𝑐c (1≤𝑟≤𝑛1≤r≤n; 1≤𝑐≤𝑚1≤c≤m). The interactor responds with integer 11, if you found the treasure, and 00 if not. If you try to find the treasure in the same cell multiple times, the result will be 00 since the treasure is already found.
  • SCAN 𝑟r 𝑐c (1≤𝑟≤𝑛1≤r≤n; 1≤𝑐≤𝑚1≤c≤m). The interactor responds with an integer that is the sum of Manhattan distances from the cell (𝑟,𝑐)(r,c) to the cells where the treasures were hidden. The sum is calculated for both cells with treasures, even if you already found one of them.

After you found both treasures, i. e. you received 11 for two DIG operations, your program should continue to the next test case or exit if that test case was the last one.

交互题,首先查(1, 1)以及(1, m)两个点,计算一下可以得到x1+x2以及y1+y2,此时我们就能知道宝藏的两个点的中点了!这时候查一下中点(midx, midy),就能知道abs(x2-x1)+abs(y2-y1),再查一下(1, midy),就能知道abs(x2-x1)+(y1+y2),结合前面求出来的就能算出abs(x2-x1), abs(y2-y1)等等。不妨令x2>x1, y2>y1,这时能求出x1,x2,y1,y2,先查(x1, y1),如果没查到的话就查(x1, y2)以及(x2, y1),能查到的话就继续查(x2, y2)即可。

注意,如果报错Idleness limit exceeded,不一定是没用endl或者fflush的问题,也可能是代码本身写的不太对...

#include <bits/stdc++.h>
using namespace std;
int n, m;
int scan(int r, int c) {
	cout << "SCAN" << " " << r << " " << c << endl;
	int d;
	cin >> d;
	return d;
}
int dig(int r, int c) {
	if (r < 1 || r > n || c < 1 || c > m) {
        return 0;
    }
	cout << "DIG" << " " << r << " " << c << endl;
	int f;
	cin >> f;
	return f;
}
int main() {
	int T;
	cin >> T;
	while(T--) {
		cin >> n >> m;
		int tot = 0;
		int dis1 = scan(1, 1) + 4;
		int dis2 = scan(1, m) + 2;
		int x1px2, y1py2;
		int tmp = dis1 + dis2 - 2 * m;
		x1px2 = tmp / 2;
		y1py2 = dis1 - x1px2;
		int midx = x1px2 / 2, midy = y1py2 / 2;
		int dis3 = scan(midx, midy);//abs(x1 - x2) + abs(y1 - y2)
		int dis4 = scan(1, midy) + 2;//y2-y1+x2+x1
		int y2sy1 = dis4 - x1px2;
		int x2sx1 = dis3 - y2sy1;
		int x2 = (x1px2 - x2sx1) / 2, y2 = (y1py2 - y2sy1) / 2;
		int x1 = x1px2 - x2, y1 = y1py2 - y2;
		if(dig(x1, y1)) {
			dig(x2, y2);
		} else {
			dig(x1, y2);
			dig(x2, y1);
		}
	}
}
posted @ 2022-04-15 17:42  脂环  阅读(149)  评论(0编辑  收藏  举报