CCF刷题计划——JPEG 解码(状态方向辅助Z型填充)

JPEG 解码

计算机软件能力认证考试系统

这道题唯一的难点其实是处理数据Z型填入。本题可以学到:dir表示方向填充。相当于使用dir为状态机表示当前状态,根据当前状态进行移动。我看到有题解,可以直接枚举存储状态,也是一个不错的选择,就是输入的时候有点手痛。

这种问题(z型插入)也不是第一次见了,可以专门记一记,出现类似的也可以考虑使用dir状态表示。

cpp 复制代码
bool dir=false;			//表示插入方向,一开始是向左下填充 
	int x=0,y=0;
	for(int i=0;i<n;i++)	//插入所有数据
	{
		m[x][y]=data[i];
		//四种情况:上右边界、右上移动、左下边界、左下移动(注意!顺序不能换。因为我们筛选是一步一步的) 
		if(!dir && (!x||y==7))	//之前是右上走的,判断是否到边界 当为上、右边界的时候,向左下移动
		{
			dir=true;
			y==7?x++:y++;	//当为上边界的时候,就x水平移动;为右边界的话,y竖直向下走 
		 }
		else if(!dir)	x--,y++;	//dir==false-->右上走
		else if (!y || x == 7) dir = false, x == 7 ? y++ : x++;	//同理,遇见左、下边界  
		else	x++,y--;
	}

AC:

cpp 复制代码
#include <iostream>
#include <cmath>
#include <vector>
using namespace std;
#define pi 3.1415926535

int n,T;
int lm[8][8]={0};	//量化矩阵 
int m[8][8]={0};	//经数据填充的矩阵 
int data[66]={0};

void Fill()	
{
//构造矩阵M的时候设置一个变量dir 表示方向,dir=true 时从左下往右上填充,dir=false 时从右上往左下填充。
//注意判断边界是两个维度都要考虑是否到达边界。
	bool dir=false;			//表示插入方向,一开始是向左下填充 
	int x=0,y=0;
	for(int i=0;i<n;i++)	//插入所有数据
	{
		m[x][y]=data[i];
		//四种情况:上右边界、右上移动、左下边界、左下移动(注意!顺序不能换。因为我们筛选是一步一步的) 
		if(!dir && (!x||y==7))	//之前是右上走的,判断是否到边界 当为上、右边界的时候,向左下移动
		{
			dir=true;
			y==7?x++:y++;	//当为上边界的时候,就x水平移动;为右边界的话,y竖直向下走 
		 }
		else if(!dir)	x--,y++;	//dir==false-->右上走
		else if (!y || x == 7) dir = false, x == 7 ? y++ : x++;	//同理,遇见左、下边界  
		else	x++,y--;
	}
}

void pirntMatrix()
{
	for(int i=0;i<8;i++)
		{
			for(int j=0;j<8;j++)
				cout<<m[i][j]<<" ";
			cout<<endl;
		}
}

void MulMatrix()
{
	for(int i=0;i<8;i++)
	for(int j=0;j<8;j++)
		m[i][j]*=lm[i][j];
}

void changeMatrix()
{
	double temp[8][8]={0};
	vector<double> a(8,1);
	a[0]=sqrt(0.5);
	
	for(int i=0;i<8;i++)
		for(int j=0;j<8;j++)
			for(int u=0;u<8;u++)
				for(int v=0;v<8;v++)
					temp[i][j]+=0.25*a[u]*a[v]*m[u][v]*cos(pi/8*(i+0.5)*u)*cos(pi/8*(j+0.5)*v);

	for(int i=0;i<8;i++)
	for(int j=0;j<8;j++)
	{
		temp[i][j]+=128;
		temp[i][j]=temp[i][j]>255?255:temp[i][j];
		temp[i][j]=temp[i][j]<0?0:temp[i][j];
		//四舍五入
		int t= temp[i][j]+0.5;
		temp[i][j]=t;
	}
	
	for(int i=0;i<8;i++)
	{
		for(int j=0;j<8;j++)
			cout<<temp[i][j]<<" ";
		cout<<endl;
	}
 } 

int main()
{
	for(int i=0;i<8;i++)
	for(int j=0;j<8;j++)
		cin>>lm[i][j];
		
	cin>>n>>T;
	for(int i=0;i<n;i++)
		cin>>data[i];
	if(T==0)
	{
		Fill();
		pirntMatrix();
	}
	else if(T==1)
	{
		Fill();	//先填充
		MulMatrix();	//相乘 结果放在m中(不是矩阵乘法,就是对应值相乘) 
		pirntMatrix();
	}
	else
	{
		Fill();	//先填充
		MulMatrix();
		changeMatrix();	//变换 
	}
	
	return 0;
}
相关推荐
小白程序员成长日记40 分钟前
2025.11.29 力扣每日一题
数据结构·算法·leetcode
咫尺的梦想0071 小时前
链表-反装链表
数据结构·链表
在黎明的反思2 小时前
进程通信之消息队列(IPC)
算法
老鱼说AI2 小时前
算法基础教学第一步:数据结构
数据结构·python·算法
极地星光2 小时前
C++链式调用设计:打造优雅流式API
服务器·网络·c++
Jing_Rainbow2 小时前
【LeetCode Hot100 刷题日记(19/100)】54. 螺旋矩阵 —— 数组、矩阵、模拟、双指针、层序遍历🌀
算法·面试·程序员
小陈要努力3 小时前
Visual Studio 开发环境配置指南
c++·opengl
程序猿本员3 小时前
5. 实现
c++
Bona Sun3 小时前
单片机手搓掌上游戏机(十五)—pico运行fc模拟器之编译环境
c语言·c++·单片机·游戏机
地平线开发者3 小时前
征程 6 | linear 高精度输出配置方式
算法·自动驾驶