• 20212022 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);
    		}
    	}
    }
    
  • 相关阅读:
    【JAVA基础】强引用、弱引用、软引用、虚引用
    检测手机传感器【Sensor】
    Nginx下搭建flv视频服务器且支持视频拖动进度条播放
    盘点Web开源项目大集合【太全了!!】
    打造属于自己的Notepad++
    魔兽1.20E作弊内存地址全公开
    万能的js复制按钮
    js定时刷新网页
    解决flv格式视频在网页中播放问题
    程序员该如何学习新知识
  • 原文地址:https://www.cnblogs.com/lipoicyclic/p/16150333.html
Copyright © 2020-2023  润新知