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;
}
相关推荐
敲上瘾3 分钟前
操作系统的理解
linux·运维·服务器·c++·大模型·操作系统·aigc
福大大架构师每日一题5 分钟前
文心一言 VS 讯飞星火 VS chatgpt (396)-- 算法导论25.2 1题
算法·文心一言
不会写代码的ys9 分钟前
【类与对象】--对象之舞,类之华章,共绘C++之美
c++
兵哥工控11 分钟前
MFC工控项目实例三十二模拟量校正值添加修改删除
c++·mfc
EterNity_TiMe_20 分钟前
【论文复现】(CLIP)文本也能和图像配对
python·学习·算法·性能优化·数据分析·clip
长弓聊编程21 分钟前
Linux系统使用valgrind分析C++程序内存资源使用情况
linux·c++
cherub.28 分钟前
深入解析信号量:定义与环形队列生产消费模型剖析
linux·c++
机器学习之心30 分钟前
一区北方苍鹰算法优化+创新改进Transformer!NGO-Transformer-LSTM多变量回归预测
算法·lstm·transformer·北方苍鹰算法优化·多变量回归预测·ngo-transformer
yyt_cdeyyds41 分钟前
FIFO和LRU算法实现操作系统中主存管理
算法
暮色_年华43 分钟前
Modern Effective C++item 9:优先考虑别名声明而非typedef
c++