ccf- csp 202212-3 JPEG 解码

救命,我真的觉得这是我做过最简单的一个三题了。

 题目自己去看

思路:

1.填充

填充矩阵时依次按对角线来填充。从左上角开始,不难观察出第偶数条对角线的填充方向为右上,第奇数条对角线的填充方向为左下。将整个矩阵按照最中间的对角线分为两部分,第一部分的每条对角线依次增长,第二部分依次减小。

2.逆变换

该步骤主要是将题目中所给的公式转换为代码计算。本步骤要注意double和int数据类型的转换。应该新声明一个double类型的二维数组记录变换结果。

#include
#include
using namespace std;
const int N=8;
int a[N][N],M[N][N],M1[N][N];
double M2[N][N];
int n,T;
int q[65];

double chan(double i,double j)
{
	double temp=0;
	for(int x=0;x<8;x++)
	{
		for(int y=0;y<8;y++)
		{
			if(x==0 && y==0)
			{
				temp += (double)M1[x][y]*cos(0)*cos(0)/2.0;
			}
			else if(x==0 || y==0)
			{
				temp += (double)M1[x][y]*sqrt(0.5)*cos(acos(-1)*(i+0.5)*double(x)/8.0)*cos(acos(-1)*(j+0.5)*y/8.0);
			}
			else
			{
				temp += (double)M1[x][y]*cos(acos(-1)*(i+0.5)*double(x)/8.0)*cos(acos(-1)*(j+0.5)*double(y)/8.0);
			}
		}
	}
	return (double) temp/4.0;
}

int main()
{
	for(int i=0;i<8;i++)
	{
		for(int j=0;j<8;j++)
		{
			cin>>a[i][j];
		}
	}
	cin>>n;
	cin>>T;
	for(int i=0;i>q[i];
	}
	
	//填充后的矩阵
	int k=0;
	for(int i=0;i<8;i++)
	{
		if(i%2==0)
		{
			for(int j=0;j<=i;j++)
			{
				M[i-j][j]=q[k++];
			}
		}
		else
		{
			for(int j=0;j<=i;j++)
			{
				M[j][i-j]=q[k++];
			}
		}
	}
	for(int i=8;i<15;i++)
	{
		if(i%2==0)
		{
			for(int j=i-7;j<=7;j++)
			{
				M[i-j][j]=q[k++];
			}
		}
		else
		{
			for(int j=i-7;j<=7;j++)
			{
				M[j][i-j]=q[k++];
			}
		}
	}
	
	//量化矩阵逐项相乘后
	for(int i=0;i<8;i++)
	{
		for(int j=0;j<8;j++)
		{
			M1[i][j]=M[i][j]*a[i][j];
		}
	}
	
	//离散余弦逆变换
	for(int i=0;i<8;i++)
	{
		for(int j=0;j<8;j++)
		{
			M2[i][j]=round(chan(i,j)+128);
			if(M2[i][j]>255) M2[i][j]=255;
			if(M2[i][j]<0) M2[i][j]=0;
		}
	}
	
	if(T==0)
	{
		for(int i=0;i<8;i++)
		{
			for(int j=0;j<8;j++)
			{
				cout<

你可能感兴趣的:(算法,矩阵,线性代数)