QOJ.ac

QOJ

Time Limit: 3 s Memory Limit: 1024 MB Total points: 100 Communication
[0]

# 10178. 그리드 복원

Statistics

这是一道通信题

你有一个 N×N 的网格,每个格子被涂成黑色或白色。这个网格的状态可以用一个 N×N 的矩阵 A 来表示,其中每个元素是 01。对于 0i,jN1,如果 A[i][j]=1,则表示第 i 行第 j 列的格子(以下简称格子 (i,j))是黑色;如果 A[i][j]=0,则表示该格子是白色。此外,已知这个网格满足以下条件:不存在一组 (i1,i2,j1,j2) 同时满足:

  1. 0i1<i2N1,0j1<j2N1
  2. A[i1][j1]=A[i2][j2],A[i1][j2]=A[i2][j1],A[i1][j1]A[i1][j2]

你想把这个网格传递给戴江齐。由于安全原因,传输过程需要遵循以下步骤:

  1. 你从总共 N2 个格子中挑选出若干个格子。
  2. 通信系统持有一对秘密排列 XY,它们是 (0,1,2,,N1) 的某种顺序。
  3. 一个 N×N 的矩阵 B 会被传递给戴江齐。对于你选中的每个格子 (i,j)B[X[i]][Y[j]]=A[i][j] 成立;对于未被选中的格子 (i,j)B[X[i]][Y[j]]=1 成立。

戴江齐的任务是根据矩阵 B,将其中值为 1 的部分还原,使得对所有 0i,jN1,都有 B[X[i]][Y[j]]=A[i][j] 成立。

实现细节

你需要实现以下几个函数:

void send(std::vector<std::vector<int> > A)
  • A:一个大小为 N 的二维向量,每个子向量的长度也是 N
  • 在这个函数中,你需要调用 select 函数来选择要传输的格子。
void select(int i, int j)
  • 调用时需满足 0i,jN1
  • 这个函数被调用的总次数记为 K
vector<vector<int> > reconstruct(vector<vector<int> > B)
  • 评测程序持有一对 (0,1,,N1) 的排列 XY
  • 输入参数 B 是根据 send 函数中给定的二维向量 A 生成的,满足以下条件:
    • BA 的形状相同。
    • 对于 0i,jN1,如果 send 函数中调用了 select(i, j),则 B[X[i]][Y[j]]=A[i][j] 成立。
    • 对于 0i,jN1,如果 send 函数中未调用 select(i, j),则 B[X[i]][Y[j]]=1 成立。
  • 函数返回的矩阵 C 必须满足:对于所有 0i,jN1C[X[i]][Y[j]]=A[i][j]

send 函数中 select 的调用以及 reconstruct 函数的返回值只能依赖于输入参数的值。如果同一个参数值多次调用函数时行为不一致,可能会被判为错误答案。

评测过程中,排列 XY 是预先确定且非自适应的(non-adaptive),但你无法直接访问它们。在示例评测程序中,XY 会作为输入提供。

每个输入包含若干独立的测试数据。每个测试数据会分别调用一次 sendreconstruct 函数。虽然不保证函数按测试数据顺序调用,但保证其调用和返回值符合题目描述的逻辑。

与示例评测程序不同,实际评测时,你的程序会为每个输入运行两次。第一次运行时,对每个测试数据调用 send 函数并输出结果;第二次运行时,以第一次的输出作为输入,调用 reconstruct 函数。每个测试数据的执行时间是两次运行时间的总和,内存使用量也是两次运行的总和。时间和内存限制以两次运行的总和为准。由于 select 函数只在第一次运行中调用,其调用次数限制不受两次运行影响。

你提交的源代码中不得包含任何输入输出函数。

样例

考虑 N=3A=[[1,1,1],[1,1,0],[0,1,0]]X=[2,1,0]Y=[0,1,2] 的情况。

评测程序首先调用:

send([[1, 1, 1], [1, 1, 0], [0, 1, 0]])

假设 send 函数中调用了以下内容:

select(0, 1)
select(0, 2)
select(1, 0)
select(2, 2)

之后,评分程序调用:

reconstruct([[-1, -1, 0], [1, -1, -1], [-1, 1, 1]])

reconstruct 函数的返回值 C 必须满足所有 0i,jN1C[X[i]][Y[j]]=A[i][j],因此 reconstruct([[-1, -1, 0], [1, -1, -1], [-1, 1, 1]]) 应返回 [[0,1,0],[1,1,0],[1,1,1]]

子任务

对于所有输入数据,满足:

  • 1N500
  • send 函数中 select 的调用次数 K 不得超过 N2
  • 所有测试数据中 N2 的总和不超过 106

详细子任务附加限制及分值如下表所示。

子任务 分值 附加限制
1 12 对于 0i,jN1ijA[i][j]=1 等价
2 35 网格呈直方图形式。即对于所有 0jN1,存在 0HjN,使得当 i<HjA[i][j]=1,否则 A[i][j]=0
3 53 无附加限制

如果 reconstruct 函数的返回值 C 满足 C[X[i]][Y[j]]=A[i][j],则各子问题的得分如下。若不满足此条件,则得 0 分。

根据 A 的大小 Nselect 的调用次数 K

  • 如果所有测试用例满足 K2N1,则获得满分。
  • 否则,找到满足 cNK 的最小整数 c
    • c10,则获得子问题分数的 1109c100
  • 若上述条件均不满足,但 KN22+1,则获得子问题分数的 7100
  • 若以上条件均不满足,则该子问题得 0 分。

样例交互库

示例评测程序会接收测试数据数量 T,然后依次接收 T 组输入,每组包括:

  • 1 行:N
  • 2+k (0kN1) 行:A[k][0] A[k][1]  A[k][N1]
  • N+2 行:X[0] X[1]  X[N1]
  • N+3 行:Y[0] Y[1]  Y[N1]

示例评测程序对每个测试数据输出:

  • 若调用的 select(i, j) 不满足 0i,jN1,输出一行 Wrong Answer [1]
  • select 调用次数超过 N2,输出一行 Wrong Answer [2]
  • reconstruct 返回值与 B 形状不一致,输出一行 Wrong Answer [3]
  • reconstruct 返回值未能正确还原矩阵,输出一行 Wrong Answer [4]
  • 其他情况下,输出如 K: 10,表示 select 的调用次数。

一旦输出 Wrong Answer,示例评测程序立即终止。

请注意,示例评测程序可能与实际评测程序有所不同。