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;
}
相关推荐
通信仿真爱好者11 小时前
第【60期】--大规模MIMO系统信号检测算法误码率比较 --matlab完整代码+参考文章
算法·matlab·mimo·信号检测
AI科技星11 小时前
全域谱分析:无穷维超复数信息场分形统一场论——自然、量子、金融多重分形第一性原理完整体系(中英双语终稿)
人工智能·python·算法·金融·乖乖数学·全域数学
utf8mb4安全女神11 小时前
【Redis数据库】哨兵集群/redis集群/安装配置/主从复制/数据持久化操作/数据结构/安全限制/PHP redis/
linux·服务器·数据结构·数据库·redis·缓存
先吃饱再说12 小时前
为什么堆能 O(log n) 插入?拆解完全二叉树的数组魔法
算法·排序算法
丘山望岳12 小时前
哈希——数据分类存储柜
数据结构·散列表
留白_13 小时前
【决策树】泰坦尼克号生存预测
算法·决策树·机器学习
hqzing13 小时前
鸿蒙 PC 底层开发技术详解(七):二进制自签名算法的实现
算法·华为·harmonyos
AI科技星13 小时前
超复数全域经济周期场与信息谱场——金融与密码学底层理论重构《0·1·∞三元一体全域超复数统一场论》系列全集(六一字不漏完整合订终版)
人工智能·算法·金融·密码学·拓扑学·乖乖数学·全域数学
AI科技星13 小时前
《01无穷全域信息场论:算子G与宇宙本体高维完备公理大典》
人工智能·python·算法·金融·乖乖数学·全域数学
Tim_1013 小时前
【C++】013、空类占多少字节?
算法