• [JOISC 2021] Navigation 2


    Sol

    (题面太长,所以无了)

    这题是一道通信题,需要构造方案。

    观察该图形的染色(字母染色):

    [A][B][C][A][B][C]
    [D][E][F][D][E][F]
    [G][H][I][G][H][I]
    [A][B][C][A][B][C]
    [D][E][F][D][E][F]
    [G][H][I][G][H][I]
    

    发现了什么?任意取一个 (3 imes 3) 的矩形,每个字母仅出现一次。这在接下来的方法中十分有用。

    为了保证关于每一个 目标点 信息能够实时获取,我们就采用上面的方式来实现。当然,对于不同的矩形,处在最左上角的字母是不一样的,所以我们需要选取一个 基准点,由上面染色方法的规律性,找到基准点就能还原出整个矩形中的东西。

    所以,在下面的矩形中:

    [1][2][3]
    [=][+][4]
    [7][6][5]
    

    我们令 + 为基准点,1~7 中存关于目标点 1 到 7 的信息,= 的信息暂时不管。格子在标号(原题:插旗子)的时候,基准点要与众不同,我们使用 最大的数字 (L) 来表示基准点。对于 1 到 7,想一想如何分配剩下的数字。

    举特例,我们要让 [1] 信息要能 准确、连续 地引导 Bruno 前往终点 并且在 终点停下。这里,如果终点在以 [1] 的位置为中心的九格以内,使用 (9) 个数字表示终点的位置,这里的位置表示相对于 [1] 的位置。例如

    (1)(2)(3)
    (8)(9)(4)
    (7)(6)(5)
    

    每个数字表示了相对于 [1] 的位置。例如这里 数字1 代表 1 号目标点在 [1] 的左上格,数字9 代表就在 [1] 的位置

    反之,使用 (4) 个数字表示以 [1] 的位置为基准,到终点 坐标差 (geq 2) 的方向 (X) 走,也就是说,只要 Bruno 落在 [1] 的九格范围之内(能看到这个 [1]),都往 (X) 方向走。例如

        (13)
    (11)    (10)
        (12)
    

    数字10 表示往右(东)走,数字13 表示往上(北)走。

    举例子:对于地图上终点分布如下的图

    [ ][ ][ ][ ][ ]
    [ ][1][ ][ ][ ]
    [ ][ ][ ][ ][ ]
    [ ][ ][ ][2][ ]
    [ ][ ][ ][ ][ ]
    

    我们可以这样染色

    [1][2][3][1][2]
    [=][+][4][=][+]
    [7][6][5][7][6]
    [1][2][3][1][2]
    [=][+][4][=][+]
    

    我们可以这样标号

    ( 5)(12)( /)(11)(12)
    ( /)( L)( /)( /)( L)
    ( /)( /)( /)( /)( /)
    (13)(10)( /)(11)( 8)
    ( /)( L)( /)( /)( L)
    

    符号 / 表示任意填数字。

    下面简略说明这样的标识一定能够找到终点。首先,对于格子的指示其实是有延时的,比如下列情况(x 表示 Bruno)

    [ ][ ][x]
    [ ][1][ ]
    [ ][ ][ ]
    

    假设 [1] 告诉 Bruno 要往上走,那只是相对其而言 (Delta >1),但对于 (x) 而言 (Delta ge 1)。即使这样,往上走一步也不会导致 走过线,因为此时已经超出 [1] 的指示范围了。

    如果直接指向终点,显然没什么问题,对着终点走或者停下来即可。

    通过以上的方法,我们数一数发现 (L=9+4+1=14),可以获得 75 分。

    注意到我们调整基准点坐标模 3 意义下的位置,我们可以避免掉终点在正中间的情况,这样可以做到 (L=13),获得 85 分。

    但是我们不太容易再次去掉一个终点在某一格的情况,这样可能会出现无法调整的情况。注意,我们还有一个格子 [=] 没有使用。结合题目中 每轮场景只会调用一次,能得到一个出错率在 (10^{-4}) 以下的方法:[=] 表示将每个小矩形染色旋转一定角度,例如:

    [1][2][3]
    [=][+][4]
    [7][6][5]
    

    [=][1][2]
    [7][+][3]
    [6][5][4]
    

    我们可以令 [=] 的值也为 (L),这样每个矩形内将会有两个 (L),以此判断旋转了多少度。旋转结合平移,仅记录 7 个终点位置、避免掉 2 个位置,对于绝大多数情况下都不会出问题。这样可以 (L=12)。多调整几次就能通过此题。

    Code

    // Anna
    #include "Anna.h"
    #include <bits/stdc++.h>
    using std::vector;
    const int N = 105;
    namespace {
    int n, r[8], c[8], a[N][N], col[N][N];
    int dx[8] = {-1, -1, 0, 1, 1, 1, 0, -1};
    int dy[8] = {0, -1, -1, -1, 0, 1, 1, 1};
    }
    bool In(int x, int y) { return x >= 0 && x < n && y >= 0 && y < n; }
    bool test(int s, int px, int py) {
    	int ok = 1;
    	memset(a, 0, sizeof a); memset(col, 0, sizeof col);
    	for (int i = -1; i <= n; i++)
    		for (int j = -1; j <= n; j++)
    			if ((i + 3) % 3 == px && (j + 3) % 3 == py) {
    				if (In(i, j)) a[i][j] = 12;
    				if (In(i + dx[s], j + dy[s])) a[i + dx[s]][j + dy[s]] = 12;
    				for (int k = 1; k < 8; k++) {
    					int x = i + dx[(s + k) % 8], y = j + dy[(s + k) % 8];
    					if (!In(x, y)) continue;
    					col[x][y] = k;
    					if (x - r[k] > 1) a[x][y] = 8;
    					else if (r[k] - x > 1) a[x][y] = 9;
    					else if (y - c[k] > 1) a[x][y] = 10;
    					else if (c[k] - y > 1) a[x][y] = 11;
    					else if (x - 1 == r[k] && y - 1 == c[k]) a[x][y] = 1;
    					else if (x - 1 == r[k] && y == c[k]) a[x][y] = 2;
    					else if (x - 1 == r[k] && y + 1 == c[k]) a[x][y] = 3;
    					else if (x == r[k] && y - 1 == c[k]) a[x][y] = 4;
    					else if (x == r[k] && y + 1 == c[k]) a[x][y] = 5;
    					else if (x + 1 == r[k] && y - 1 == c[k]) a[x][y] = 6;
    					else if (x + 1 == r[k] && y + 1 == c[k]) a[x][y] = 7;
    					else { ok = 0; a[x][y] = 9; }
    				}
    			}
    	return ok;
    }
    void Anna(int n, int k, vector<int> r, vector<int> c) {
    	::n = n;
    	for (int i = 0; i < k; i++)
    		::r[i + 1] = r[i], ::c[i + 1] = c[i];
    	for (int s = 1; s < 5; s++)
    		for (int i = 0; i < 3; i++)
    			for (int j = 0; j < 3; j++)
    				if (test(s, i, j)) goto nice;
    	nice:
    	for (int i = 0; i < n; i++)
    		for (int j = 0; j < n; j++)
    			SetFlag(i, j, a[i][j]);
    }
    
    // Bruno
    #include "Bruno.h"
    #include <bits/stdc++.h>
    using std::vector;
    namespace {
    int dx[9] = {-1, -1, 0, 1, 1, 1, 0, -1, 0};
    int dy[9] = {0, -1, -1, -1, 0, 1, 1, 1, 0};
    int a[3][3];
    }
    vector<int> Bruno(int k, vector<int> value) {
    	vector<int> ret(7);
    	for (int i = 0; i < 9; i++)
    		a[i / 3][i % 3] = value[i];
    	for (int p = 0; p < 9; p++)
    		for (int s = 1; s < 5; s++)
    			if (a[1 + dx[p]][1 + dy[p]] == 12 && a[(4 + dx[p] + dx[s]) % 3][(4 + dy[p] + dy[s]) % 3] == 12) {
    				for (int i = 1; i < 8; i++) {
    					int x = (4 + dx[p] + dx[(s + i) % 8]) % 3, y = (4 + dy[p] + dy[(s + i) % 8]) % 3;
    					if (a[x][y] == 8) ret[i - 1] = 3;
    					else if (a[x][y] == 9) ret[i - 1] = 2;
    					else if (a[x][y] == 10) ret[i - 1] = 1;
    					else if (a[x][y] == 11) ret[i - 1] = 0;
    					else {
    						int locx, locy;
    						if (a[x][y] == 1) locx = x - 1, locy = y - 1;
    						else if (a[x][y] == 2) locx = x - 1, locy = y;
    						else if (a[x][y] == 3) locx = x - 1, locy = y + 1;
    						else if (a[x][y] == 4) locx = x, locy = y - 1;
    						else if (a[x][y] == 5) locx = x, locy = y + 1;
    						else if (a[x][y] == 6) locx = x + 1, locy = y - 1;
    						else if (a[x][y] == 7) locx = x + 1, locy = y + 1;
    						if (locy > 1) ret[i - 1] = 0;
    						else if (locy < 1) ret[i - 1] = 1;
    						else if (locx > 1) ret[i - 1] = 2;
    						else if (locx < 1) ret[i - 1] = 3;
    						else ret[i - 1] = 4;
    					}
    				}
    				goto nice;
    			}
    	nice:
    	return ret;
    }
    
  • 相关阅读:
    leetcode-hard-array-239. Sliding Window Maximum
    leetcode-hard-array- 227. Basic Calculator II
    leetcode-hard-array-287. Find the Duplicate Number
    leetcode-hard-array-128. Longest Consecutive Sequence
    leetcode-hard-array-41. First Missing Positive-NO
    基于深度学习的自然图像和医学图像分割:损失函数设计(1)
    对于自己,2020年应该思考的问题和要完成的任务
    查看两张相似图形的差异
    几种模型评价指标实现代码
    实验二涉及的步骤记录
  • 原文地址:https://www.cnblogs.com/ac-evil/p/14585908.html
Copyright © 2020-2023  润新知