[模拟]AT_abc433_e [ABC433E] Max Matrix 2 题解
这个 \(\max\) 的限制很烦,因此需要处理。
可以倒序枚举数字,从 \(n \times m\) 到 \(1\)。这样就保证了放下的每个数字都不会被后面的数字影响。
对于一个 \([1, n \times m]\) 的数字 \(x\)。
-
如果存在一个 \(X_i = Y_j = x\), 那么 \(x\) 只能放在 \(i, j\) 的位置。
-
如果只存在一个 \(X_i = x\),那么 \(x\) 放在 \(i\) 行的某一列。
而为了满足题目条件,它放的这一列上必须已经有了数(由于倒叙枚举,这个数一定比 \(x\) 大,\(x\) 不会对这一列产生影响)。否则 \(x\) 就会成为这一列最大的,导致不合题意。
-
如果只存在一个 \(Y_i = x\),那么同上一种情况。
-
如果都不存在,那么 \(x\) 可以放在任意一个行和列都已经有数的位置(倒序枚举,已有数都比它大,它不产生影响)。
然后我们发现对于情况 2 和 3,我们并不需要 \(x\) 产生影响(因为他所在的行和列都有数了,而且这些数都比他大),只要能放下就行。因此只要满足条件,其实放哪都行。
一个重要的发现是,数字 \(n \times m\) 是一定能确定位置的,因为一定存在 \(X_i = n \times m, Y_j = n \times m\)(否则无解)。
于是我们记录 \(n \times m\) 数字放置的坐标为 \(fx, fy\)。
所以对于情况 2,我们可以把 \(x\) 放在 \(i, fy\)。
对于情况 3,可以放在 \(fx, j\)。
然后处理一下情况 4。其实我们每确定一个数字,就用他更新一下可以放置的地点就可以。因为一共 \(n \times m\) 个位置,因此复杂度没问题。
最后判一下就好了。
#include <bits/stdc++.h>
#define int long long
#define rep(i, a, b) for(register int i = a; i <= b; ++i)
#define rep_(i, a, b) for(register int i = a; i >= b; --i)
using namespace std;
int t;
constexpr int N = 2e5 + 5;
namespace Kx {
bool vis[N];
int n, m, x[N], y[N], a[N], b[N], maxh[N], maxl[N];
vector<int> qdh, qdl;
vector<vector<int>> ans;
vector<pair<int, int>> free;
void main() {
cin >> n >> m;
ans.clear();
ans.resize(n + 1);
rep(i, 1, n * m) {
a[i] = b[i] = vis[i] = 0;
}
qdh.clear(), qdl.clear(), free.clear();
rep(i, 1, n) {
ans[i].resize(m + 1);
maxh[i] = 0;
}
rep(i, 1, m) {
maxl[i] = 0;
}
rep(i, 1, n) {
cin >> x[i];
a[x[i]] = i;
}
rep(i, 1, m) {
cin >> y[i];
b[y[i]] = i;
}
if(!a[n * m] || !b[n * m]) {
cout << "No" << '\n';
return;
}
ans[a[n * m]][b[n * m]] = n * m;
qdh.push_back(a[n * m]);
qdl.push_back(b[n * m]);
rep_(i, n * m - 1, 1) {
if(a[i] && b[i]) {
ans[a[i]][b[i]] = i;
for(const int y : qdl) {
if(!ans[a[i]][y]) {
free.push_back(make_pair(a[i], y));
}
}
for(const int x : qdh) {
if(!ans[x][b[i]]) {
free.push_back(make_pair(x, b[i]));
}
}
qdh.push_back(a[i]);
qdl.push_back(b[i]);
}
else if(a[i] && !b[i]) {
ans[a[i]][b[n * m]] = i;
for(const int y : qdl) {
if(!ans[a[i]][y]) {
free.push_back(make_pair(a[i], y));
}
}
qdh.push_back(a[i]);
}
else if(!a[i] && b[i]) {
ans[a[n * m]][b[i]] = i;
for(const int x : qdh) {
if(!ans[x][b[i]]) {
free.push_back(make_pair(x, b[i]));
}
}
qdl.push_back(b[i]);
}
else {
if(free.size()) {
ans[free.back().first][free.back().second] = i;
free.pop_back();
}
else {
cout << "No" << '\n';
return;
}
}
}
rep(i, 1, n) {
rep(j, 1, m) {
if(vis[ans[i][j]] || ans[i][j] > n * m || ans[i][j] < 1) {
cout << "No" << '\n';
return;
}
vis[ans[i][j]] = true;
}
}
rep(i, 1, n) {
rep(j, 1, m) {
maxh[i] = max(maxh[i], ans[i][j]);
maxl[j] = max(maxl[j], ans[i][j]);
}
}
rep(i, 1, n) {
if(maxh[i] != x[i]) {
cout << "No" << '\n';
return;
}
}
rep(i, 1, m) {
if(maxl[i] != y[i]) {
cout << "No" << '\n';
return;
}
}
cout << "Yes" << '\n';
rep(i, 1, n) {
rep(j, 1, m) {
cout << ans[i][j] << ' ';
}
cout << '\n';
}
}
}
signed main() {
//freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
ios :: sync_with_stdio(0), cin.tie(0), cout.tie(0);
cin >> t;
while(t--) {
Kx :: main();
}
return 0;
}

浙公网安备 33010602011771号