CCF-CSP 202212-3 JPEG解码

思路分析

题目本身比较直白,按照该过程一点一点翻译就可以了。
应当注意下面几个点:

  1. 如何实现填数的操作:观察到x+y的和可以作为区分按照从下到上还是从上到下进行填数是一个关键的点,同时需要注意填数的边界问题
  2. 本题要求四舍五入输出,开始的时候我强行转为了int导致wa了好几次,应当用round函数完成四舍五入。
#include <iostream>
#include <cmath>
#include <queue>
using namespace std;
#define pi acos(-1)
int q[9][9];
double m[9][9], nm[9][9];
int scan[65];
queue<int>d;
void print()
{
	for (int i = 0; i < 8; i++)
	{
		for (int j = 0; j < 8; j++)
		{
			cout << round(nm[i][j]) << " ";
		}
		cout << endl;
	}
}
void test()
{
	for (int i = 0; i < 8; i++)
	{
		for (int j = 0; j < 8; j++)
		{
			cout << round(m[i][j]) << " ";
		}
		cout << endl;
	}
}
void t0()
{
	int x = 0, y = 0;
	while (!d.empty()) {
		m[x][y] = d.front();
		d.pop();
		if ((x + y) % 2 == 0) {
			if ((x + y) <= 7) {
				if (x == 0) y++;
				else x--, y++;
			}
			else if ((x + y) > 7) {
				if (y == 7) x++;
				else x--, y++;
			}
		}
		else if ((x + y) % 2 != 0) {
			if ((x + y < 7)) {
				if (y == 0) x++;
				else x++, y--;
			}
			else if ((x + y) >= 7) {
				if (x == 7) y++;
				else x++, y--;
			}
		}
	}
}
void t1()
{
	for (int i = 0; i < 8; i++)
	{
		for (int j = 0; j < 8; j++)
		{
			m[i][j] = m[i][j] * q[i][j];
		}
	}
}
void t2()
{
	for (int i = 0; i < 8; i++)
	{
		for (int j = 0; j < 8; j++)
		{
			double tmp = 0;
			for (int u = 0; u < 8; u++)
			{
				for (int v = 0; v < 8; v++)
				{
					double alphau, alphav;
					if (u == 0)
						alphau = sqrt(0.5);
					else
						alphau = 1;
					if (v == 0)
						alphav = sqrt(0.5);
					else
						alphav = 1;
					tmp += alphau * alphav * m[u][v] * cos(pi / 8 * (i + 0.5) * u) * cos(pi / 8 * (j + 0.5) * v);
				}
			}
			nm[i][j] = tmp / 4;
		}
	}
	for (int i = 0; i < 8; i++)
	{
		for (int j = 0; j < 8; j++)
		{
			nm[i][j] += 128;
			if (nm[i][j] < 0)
				nm[i][j] = 0;
			else if (nm[i][j] > 255)
				nm[i][j] = 255;
		}
	}
}

int main()
{
	for (int i = 0; i < 8; i++)
	{
		for (int j = 0; j < 8; j++)
			cin >> q[i][j];
	}
	int n, T;
	cin >> n >> T;
	for (int i = 1; i <= n; i++)
	{
		int num;
		cin >> num;
		d.push(num);
	}
	if (T == 0)
	{
		t0();
		test();
	}
	else if (T == 1)
	{
		t0();
		t1();
		test();
	}
	else
	{
		t0();
		t1();
		t2();
		print();
	}
	return 0;
}
/*
16 11 10 16 24 40 51 61
12 12 14 19 26 58 60 55
14 13 16 24 40 57 69 56
14 17 22 29 51 87 80 62
18 22 37 56 68 109 103 77
24 35 55 64 81 104 113 92
49 64 78 87 103 121 120 101
72 92 95 98 112 100 103 99
26
2
-26 -3 0 -3 -2 -6 2 -4 1 -3 1 1 5 1 2 -1 1 -1 2 0 0 0 0 0 -1 -1
*/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值