题解:AT_arc181_c [ARC181C] Row and Column Order
题目描述
给定两个长度为
- 对于每个
i ,将该矩阵的上数第i 行看成长度为N 的01 字符串S_i ,则有S_{P_1}<S_{P_2}<\cdots<S_{P_N} 。 - 对于每个
i ,将该矩阵的左数第i 列看成长度为N 的01 字符串T_i ,则有T_{Q_1}<T_{Q_2}<\cdots<T_{Q_N} 。
称两个字符串
解题思路
场上唐了没想出来。在此 Orz @STUDENT0。
先处理出对于所有
接下来就是本题最关键的部分。如果两个长为
构造方法:令第
正确性证明:
- 对于两行
a,b 满足P\_rk_a<P\_rk_b ,即要求第a 行代表的串小于第b 行,不难发现如果第j 列满足Q\_rk_j 值是前P\_rk_a 大的,那么Q\_rk_j 值也是前P\_rk_b 大的,反之则不一定。于是行方面符合题意。 - 对于两列
a,b 满足Q\_rk_a<Q\_rk_b ,即要求第a 列代表的串小于第b 列,不难发现某一列的Q\_rk 值越大,就越有更多的行在这一列设为1 ,同上述分析可得列方面符合题意。
参考代码
代码写法整体较简单。
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int n, p[510], q[510];
char res[510][510];
int main()
{
cin >> n;
for (int i = 1, i1; i <= n; i++) cin >> i1, p[i1] = i;
for (int i = 1, i1; i <= n; i++) cin >> i1, q[i1] = i;
memset(res, '0', sizeof(res));
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
if (p[i] >= n - q[j] + 1) res[i][j] = '1';
for (int i = 1; i <= n; i++)
res[i][n + 1] = '\0', printf("%s\n", res[i] + 1);
return 0;
}