CSP202212_3

CSP202212_3

题目

JPEG 解码

思路

比较直观的大模拟,仔细地读一遍题后就基本可以明确要求了。

首先针对一个长度为 n 的序列,按 Z 形填入矩阵中。直观地想,总共需要斜着填15行,奇数行都是从左下向右上,偶数行都是从右上向左下,手模一下基本就可以得出结果了。20pts到手

对填入的矩阵,直接和所给矩阵相乘即可完成第二个要求,没有任何难度。40pts到手。

进行离散变换本质上就是一个数学计算过程。相关的数学知识题目都已给出,注意在计算时如果矩阵从 [1, 1] 开始存储,坐标到 u、v 需要平移一次。此外如果用分数计算,注意不要损失精度。最后用 round 函数四舍五入一下,加上 128 并判断一下范围即可AC。

挺水的题目,基本不涉及什么有难度的处理。码量也不大,下面的代码很多地方可以省去,但是懒得改了。总而言之只要细心拿满分还是比较容易的。

Code

#include<bits/stdc++.h>
const double pi = acos(-1);
using namespace std;

int n, opt;

double q[9][9];
double m[9][9];
double ans[9][9];
double num[1010];

double alpha(int x)
{
    if(x) return 1;
    return sqrt(0.5);
}

double cal(int a, int b)
{
    double sum = 0;
    for(int i = 1;i <= 8;i++)
    {
        for(int j = 1;j <= 8;j++)
        {
            int u = i - 1, v = j - 1;
            //u、v要平移到[0, 7],a、b也要对应减一
            sum += m[i][j] * (alpha(u)*alpha(v)) * (cos((a - 0.5)*u*(pi/8.0))*cos((b - 0.5)*v*(pi/8.0)));
        }
    }
    sum /= 4.0;
    return sum;
}

void zmove()
{
    int pos = 0;
    for(int i = 1;i <= 15;i++)
    {
        int dir = i%2;
        int sx = 0, sy = 0;
        // dir = 0 => ↙
        // dir = 1 => ↗
        if(i <= 8)
        {
            if(! dir)
            sx = 1, sy = i;
            else 
            sx = i, sy = 1;
            for(int k = 1;k <= i;k++)
            {
                m[sx][sy] = num[++pos];
                if(! dir)
                sx++, sy--;
                else
                sx--, sy++;
            }
        }
        else
        {
            if(! dir)
            sx = i - 7, sy = 8;
            else
            sx = 8, sy = i - 7;
            for(int k = 1;k <= 16 - i;k++)
            {
                m[sx][sy] = num[++pos];
                if(! dir)
                sx++, sy--;
                else
                sx--, sy++;
            }
        }
        if(pos == n) break;
    }
    return;
}

void func(int opt)
{
    zmove();
    if(opt == 0)
    {
        for(int i = 1;i <= 8;i++)
        {
            for(int j = 1;j <= 8;j++)
            {
                cout << m[i][j] << " ";
            }
            cout << endl;
        }
        return;
    }

    for(int i = 1;i <= 8;i++)
    {
        for(int j = 1;j <= 8;j++)
        {
            m[i][j] *= q[i][j];
        }
    }
    if(opt == 1)
    {
        for(int i = 1;i <= 8;i++)
        {
            for(int j = 1;j <= 8;j++)
            {
                cout << m[i][j] << " ";
            }
            cout << endl;
        }
        return;
    }
    
    for(int i = 1;i <= 8;i++)
    {
        for(int j = 1;j <= 8;j++)
        {
            ans[i][j] = round(cal(i, j));
            ans[i][j] += 128;
            if(ans[i][j] < 0) ans[i][j] = 0;
            if(ans[i][j] > 255) ans[i][j] = 255;
        }
    }
    for(int i = 1;i <= 8;i++)
    {
        for(int j = 1;j <= 8;j++)
        {
            cout << ans[i][j] << " ";
        }
        cout << endl;
    }
    return;
}

int main()
{
    for(int i = 1;i <= 8;i++)
    {
        for(int j = 1;j <= 8;j++)
        {
            cin >> q[i][j];
        }
    }
    cin >> n >> opt;
    for(int i = 1;i <= n;i++)
    {
        cin >> num[i];
    }
    func(opt);
    return 0;
}
/*
16 11 10 16 24 40 51 61
12 12 14 19 26 58 60 55
14 13 16 24 40 57 69 56
14 17 22 29 51 87 80 62
18 22 37 56 68 109 103 77
24 35 55 64 81 104 113 92
49 64 78 87 103 121 120 101
72 92 95 98 112 100 103 99
26
2
-26 -3 0 -3 -2 -6 2 -4 1 -3 1 1 5 1 2 -1 1 -1 2 0 0 0 0 0 -1 -1
*/
posted @ 2023-03-14 10:43  Kevin_Chance  阅读(50)  评论(0)    收藏  举报