ZOJ 1156

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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值