by 华师小刚
解题思路:
这道题是一道非常经典的解码解密的模拟题,题目背景是图像的四分图压缩和解压缩算法,我们分析不难发现四分图有一定的规律,我们通过寻找规律设计算法。题目的每个Case要求是这样的,先给我们两个树,这两个树分别代表着密码哈希映射图的四分树和待解密图的四分树,由于四分树是原图经过四分树算法压缩过的,我们首先要对树进行解码(decoding),我们可以通过观察压缩的过程来倒推解压缩的过程。可以发现,四分图压缩的过程实际上就是一个不断四分的过程。所以我们设计一个深度优先搜索算法(dfs),对四分树做递归处理,但遍历到的节点不为-1时,就在图上相应的块上写上值,否则递归调用该节点四分后的子节点。这样就得到哈希映射图和带解密的图,在做相应的映射就得到解密后的原图了。
AC代码如下:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iomanip>
using namespace std;
const int N = 10000;
int arr1[N];
int arr2[N];
int g1[20][20];
int g2[20][20];
int res[20][20];
void dfs(int arr[], int g[][20], int pos, int r, int c, int len)
{
if (arr[pos] != -1)
{
for (int i = r; i < r + len; ++i)
for (int j = c; j < c + len; ++j)
{
g[i][j] = arr[pos];
}
return;
}
len /= 2;
if (len)
{
dfs(arr, g, pos * 4 + 1, r, c, len);
dfs(arr, g, pos * 4 + 2, r, c + len, len);
dfs(arr, g, pos * 4 + 3, r + len, c, len);
dfs(arr, g, pos * 4 + 4, r + len, c + len, len);
}
}
int main()
{
int tt;
cin >> tt;
for (int op1 = 0; op1 < tt; ++op1)
{
if (op1) cout << endl;
int ttt;
cin >> ttt;
int cnt = 1;
for (int op2 = 0; op2 < ttt; ++op2)
{
if (op2) cout << endl;
int n;
cin >> n;
int leaf;
cin >> leaf;
memset(arr1, -1, sizeof arr1);
for (int i = 0; i < leaf; ++i)//数组存储树1
{
int x, y;
cin >> x >> y;
arr1[x] = y;
}
dfs(arr1, g1, 0, 0, 0, n);
cin >> leaf;
memset(arr2, -1, sizeof arr2);
for (int i = 0; i < leaf; ++i)//数组存储树2
{
int x, y;
cin >> x >> y;
arr2[x] = y;
}
dfs(arr2, g2, 0, 0, 0, n); //建表2
for (int i = 0; i < n; ++i)//填入答案
{
for (int j = 0; j < n; ++j)
{
int sit = g1[i][j];
int x = sit / n;
int y = sit % n;
res[x][y] = g2[i][j];
}
}
cout << "Case " << cnt++ << endl << endl;//打印答案
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < n; ++j)
{
cout << setw(4) << res[i][j];
}
cout << endl;
}
}
}
return 0;
}