题意:
给定 两个矩阵,矩阵 a
大小为 h1
行 w1
列,矩阵 b
大小为 h2
行 w2
列。
h1 >= h2
, 且 w1 >= w2
。
判断 对矩阵 a
进行有限次 删行、删列 操作 能否转化成 矩阵 b
。
如果 能够办到,则 输出 “Yes
”,否则 输出 “No
”。
思路
将 删行列 转化为 保留行列,
设置 两个 dfs
,前者负责 枚举准备保留的行,后者 枚举准备保留的列,
在 第一个 dfs
选择了 h2
行 进行 保留 之后,进行 第二个 dfs
选择 w2
列 进行 保留,
每搜到一个 从第一个矩阵 a
保留 h2
行、w2
列之后 转化而来的 与第二个矩阵 b
大小相等 的 矩阵 c
之后,判断 c
是否与 b
完全相等,
如果 相等,则 表示 a
矩阵可以通过若干次删行或删列操作转化为 b
矩阵 输出 “Yes
”,否则,输出 “No
”。
代码:
#include <bits/stdc++.h>
using namespace std;
//#define map unordered_map
//#define int long long
const int N = 15;
int h1, w1, h2, w2;
int a[N][N], b[N][N], row[N], col[N];
int idx1, idx2;
void dfs2(int start) //保留哪些列
{
if (idx1 == w2)
{
int tot1 = 0, tot2 = 0;
for (int i = 1; i <= h2; ++i)
{
++tot1, tot2 = 0;
for (int j = 1; j <= w2; ++j)
{
int r = row[tot1], c = col[++tot2];
if (a[r][c] != b[i][j]) return; //如不相等,搜下一个分支
}
}
puts("Yes"); //相等输出yes 直接强制结束所有程序(注意是所有)
exit(0);
}
if (start == w1) return;
dfs2(start + 1);
for (int i = start + 1; i <= w1; ++i)
{
col[++idx1] = i; //把保留的列加入数组
dfs2(i);
--idx1;
}
}
void dfs1(int start) //保留哪些行
{
if (idx2 == h2)
{
dfs2(0);
return;
}
if (start == h1) return;
//不删
dfs1(start + 1);
//删
for (int i = start + 1; i <= h1; ++i)
{
row[++idx2] = i; //把保留的行加入一个数组
dfs1(i);
--idx2;
}
}
signed main()
{
cin >> h1 >> w1;
for (int i = 1; i <= h1; ++i)
{
for (int j = 1; j <= w1; ++j)
{
cin >> a[i][j];
}
}
cin >> h2 >> w2;
for (int i = 1; i <= h2; ++i)
{
for (int j = 1; j <= w2; ++j)
{
cin >> b[i][j];
}
}
dfs1(0);
puts("No");
}