202212-3 CCF JPEG decoding full score problem solution (super detailed comment code) + two problem solving ideas (Z-shaped simulation/table method)

Problem Description

insert image description here

problem solving ideas

insert image description here
insert image description here
Except for the step of filling, the rest can be simulated according to the topic, the code is very clear, you can take a look at the code


Code

#include <iostream>
#include <cstring>
#include <algorithm>
#include <unordered_map>
#include <queue>
#include <cmath>

using namespace std;
int L[8][8];
int M[8][8];

int main()
{
    
    
    for (int i = 0; i < 8; i ++)
        for (int j = 0; j < 8; j ++)
            scanf("%d", &L[i][j]); //读入量化矩阵
    memset(M, 0, sizeof(M)); //初始化M数组

    int n, op; 
    scanf("%d%d", &n, &op);
    int t[64]; //存储输入的n + 1个数
    memset(t, 0, sizeof(t));
    for (int i = 0; i < n; i ++) scanf("%d", &t[i]);

    int i = 0, j = 1; //从(0, 1)开始z字形遍历
    int cnt = 0; //记录已经填充了几个数,cnt < n
    M[0][0] = t[cnt ++]; //填入(0, 0)这个点
    bool up = false; //up标志位记录当前是往右上走还是左下走
    while (1)
    {
    
    
        if (!up) //往左下走
        {
    
    
            while (i < 8 && j >= 0 && cnt < n) //i和j没越界并且当前填充个数小于n
            {
    
    
                M[i][j] = t[cnt ++]; //填充
                j --; //左
                i ++; //下
            }
            if (cnt == n) break; //已经填充完了,剩下的是0,不用填充了
            if (i == 8) //在最下面一行越界了,应该要往右水平走一
            {
    
    
                i --; //i往上一行,为第7行
                j += 2; //
                if (i == 7 && j == 7) //是最后一格
                {
    
    
                    M[i][j] = t[cnt ++]; //填充
                    break;
                }
            }
            else if (j < 0)  j = 0; //左边界越界
            up = true; //改方向
            continue;
        }
        else //和上面类似,反一下
        {
    
    
            while (i >= 0 && j < 8 && cnt < n)
            {
    
    
                M[i][j] = t[cnt ++];
                i --;
                j ++;
            }
            if (cnt == n) break;
            if (j == 8)
            {
    
    
                j --;
                i += 2;
            }
            else if (i < 0)  i = 0;
            up = false;
            continue;
        }
    }

    if (op == 0) //任务0
    {
    
    
        for (int i = 0; i < 8; i ++)
        {
    
    
            for (int j = 0; j < 8; j ++)
            {
    
    
                cout << M[i][j] << " "; //输出填充后的矩阵
            }
            cout << endl;
        }
        return 0;
    }
    if (op == 1) //任务1
    {
    
    
        for (int i = 0; i < 8; i ++)
        {
    
    
            for (int j = 0; j < 8; j ++)
            {
    
    
            	M[i][j] *= L[i][j];
                cout << M[i][j] << " "; //输出填充矩阵 * 量化矩阵
            }
            cout << endl;
        }
        return 0;
    }

	//任务2
    if (op == 2)
    {
    
    
        double sum[8][8]; //记录M‘ij

        memset(sum, 0, sizeof(sum));

        for (int i = 0; i < 8; i ++)
        {
    
    
            for (int j = 0; j < 8; j ++)
            {
    
    
                double res = 0;
                for (int u = 0; u < 8; u ++)
                {
    
    
                    for (int v = 0; v < 8; v ++)
                    {
    
    
                        double t = 1;
                        if (M[u][v] == 0) continue; //答案为0,不用算了
						//照着公式看就行
                        if (u == 0 && v == 0) t *= 0.5; 
                        else if (u == 0 || v == 0) t *= sqrt(0.5);

                        t *= M[u][v];

                        double num1 = 1, num2 = 1;
                        if (1)
                        {
    
    
                            num1 *= (i + 0.5);
                            num1 *= u;
                            num1 *= acos(-1);
                            num1 /= 8;
                        }
                        if (1)
                        {
    
    
                            num2 *= (j + 0.5);
                            num2 *= v;
                            num2 *= acos(-1);
                            num2 /= 8;
                        }
                        num1 = cos(num1);
                        num2 = cos(num2);
                        t *= num1;
                        t *= num2;
                        res += t;
                    }
                }
                sum[i][j] = res / 4;
            }
        }

        for (int i = 0; i < 8; i ++)
        {
    
    
            for (int j = 0; j < 8; j ++)
            {
    
    
                int x = round(sum[i][j] + 128); //加128取整
                if (x < 0) cout << 0 << " ";
                else if (x > 255) cout << 255 << " ";
                else cout << x << " ";
                //cout << sum[i][j] << " ";
            }
            cout << endl;
        }
    }
    return 0;
}

Guess you like

Origin blog.csdn.net/qq_51800570/article/details/129597784