原理
- 模式匹配
在给定的 n×m
矩阵中,查找是否存在与预定义的 4×4
模式矩阵 g
完全相同的子矩阵。 - 暴力枚举
遍历矩阵中所有可能的 4×4
子矩阵的左上角起始点,逐个与模式矩阵比较。 - 边界处理
若矩阵的行或列不足 4
,直接判定不存在目标子矩阵。
步骤
- 输入处理
读取测试用例数 t
,每个用例读取矩阵的行 n
、列 m
和矩阵数据。 - 矩阵遍历
对每个可能的 4×4
子矩阵的左上角坐标 (i, j)
,检查其是否与模式 g
匹配。 - 模式检查
对每个子矩阵,逐元素与 g
比较,完全一致则返回存在。 - 结果输出
根据检查结果输出 Yes
或 No
。
图示法表示步骤
示例输入矩阵(5x5):
0 0 0 0 0
0 0 1 1 0
0 0 1 1 0
0 0 0 0 0
0 0 0 0 0
模式矩阵 g:
0 0 0 0
0 1 1 0
0 1 1 0
0 0 0 0
遍历可能的子矩阵:
- 左上角 (1,1) → 匹配失败(左上角为0,但g的左上角为0,继续检查其他元素)
- 左上角 (2,2) → 匹配成功,返回 Yes
代码程序及关键行注释
#include <iostream>
#include <vector>
using namespace std;
// 预定义的4x4模式矩阵
const char g[4][4] = {
'0', '0', '0', '0',
'0', '1', '1', '0',
'0', '1', '1', '0',
'0', '0', '0', '0'
};
// 检查子矩阵是否与g匹配
bool check(vector<vector<char>>& matrix, int x, int y) {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
if (matrix[x + i][y + j] != g[i][j]) // 逐元素比较
return false;
}
}
return true;
}
// 遍历所有可能的4x4子矩阵
bool matrixExist(vector<vector<char>>& matrix, int n, int m) {
if (n < 4 || m < 4) return false; // 边界条件
for (int i = 1; i <= n - 3; i++) { // 遍历起始行
for (int j = 1; j <= m - 3; j++) { // 遍历起始列
if (check(matrix, i, j)) {
return true; // 找到匹配的子矩阵
}
}
}
return false;
}
int main() {
int t;
cin >> t;
while (t--) {
int n, m;
cin >> n >> m;
vector<vector<char>> matrix(n + 1, vector<char>(m + 1)); // 从1开始索引
for (int j = 1; j <= n; j++) {
for (int k = 1; k <= m; k++) {
cin >> matrix[j][k]; // 输入矩阵数据
}
}
if (matrixExist(matrix, n, m)) {
cout << "Yes" << endl;
} else {
cout << "No" << endl;
}
}
return 0;
}
时间复杂度
- 单测试用例
- 遍历子矩阵:
(n-3) × (m-3)
次。 - 每次检查:
4×4 = 16
次比较。 - 总时间复杂度:O(nm)。
- 整体复杂度
若有 t
个测试用例,总复杂度为 O(t × n × m)。
总结
- 核心思想
暴力枚举所有可能的 4×4
子矩阵,直接与目标模式比较。 - 适用场景
适用于矩阵规模较小的情况(如 n, m ≤ 100
),时间复杂度可接受。 - 优化空间
若矩阵规模较大,可考虑哈希或更高效的模式匹配算法(如二维KMP),但实现复杂度较高。 - 代码特点
代码简洁直观,但矩阵索引从 1
开始需特别注意边界处理。