The 28th csp certification T3 JPEG decoding analysis

The 28th csp certification T3 JPEG decoding analysis

topic description

The question is rather long, so just put a link: http://118.190.20.162/view.page?gpid=T158

experience sharing

To do this kind of large-scale simulation topic, for novices who are not very experienced, they should focus on the scoring points, first do those subtasks with simple problems and small data scale, continue to debug, and gradually improve the score. The exam basically does not limit the number of submissions. If you write it once and then debug it, there will be many mistakes for such a complicated problem. At that time, mistakes in grammar, logic, etc. will not be easy to be found, so It is best to write a small function and test it to make sure it is correct before proceeding downwards, and get some points first, so as not to lose all the games in the end! For this question, it is necessary to check step by step whether the changes in the matrix of the data given by the question are correct, and finally adjust faster and more accurately!

For such large simulation questions, the background of the question can basically be ignored, or omitted to get a general idea. The focus is on the input and output of the problem description, and there is a certain probability that the correct answer can be obtained by writing the code completely according to the steps of the problem description. Sometimes it is necessary to choose a less complex algorithm to optimize from 70 points to 100 points and so on.

Detailed topic

This question is considered a super simple question in the third question of csp. There is no complicated resource allocation and time logic. It is just a jpeg decoding task. The task is clear and the difficulty is super low, because the question fully explains the steps. Just follow the steps.

The real difficulty lies in the matrix correspondence of the scanned data and the discrete cosine transform of the matrix.

For the former, you only need to determine the mapping relationship between the matrix and the input linear data. Here I use the mapping relationship of the diagonal matrix, one is from the bottom left to the top right, and the other is from the top right to the bottom left. It is necessary to discuss whether i+j is an odd number or an even number to correspond to the above two cases. At the same time, it is also necessary to pay attention to the small squares that each line passes through after the diagonal angle exceeds the middle diagonal line will gradually decrease! That is to say, two formulas need to be determined. The following formula is derived by summing the arithmetic sequence. Be careful that the subscript of the ij array starts from 0, and the +1-1 problem in some numbers requires a lot of debugging. Second-rate!

  • 1. From bottom left to top right (i+j is an even number)

  1. In the case of i+j<=7: map[i,j]=Line[(i+j)*(i+j+1)/2+j] (that is, to calculate the number of squares + j in front of the position of ij, Because this direction j is increasing from 0)

  1. In the case of i+j>7: map[i,j]=Line[36+(23-ij)*(-8+i+j)/2+7-i] (that is, calculate the 36 before the diagonal line squares+ij the number of squares behind the diagonal line in front of this position+7-i, because this direction 7-i increases from 0)

  • 2. From top right to bottom left (i+j is an odd number)

  1. The case of i+j<=7: map[i,j]= Line[(i+j)*(i+j+1)/2+i] (same as above)

  1. In the case of i+j>7: map[i,j]=Line[36+ (23-ij)*(-8+i+j)/2+7-j] (same as above)

Divide into the above two cases and check whether i+j is even or odd to complete the serpentine input in four cases, without spending a lot of other code simulation process.

For the latter, you only need to figure out how to calculate the process, and save the intermediate variables to calculate. There are also places that need to be careful, such as 1/2 in the title. If the code is also written as 1/2, it will follow Integer division is calculated as 0, you need to write 0.5 to be calculated as double, and there are also calculations such as square root, acos, cos, etc.

The rest of the points are nothing more than simulation, which is very simple and will not be repeated here.

Full score code

Here is my debugging process:

#include<bits/stdc++.h>
using namespace std;

int Q[8][8];
double M[8][8];
double MM[8][8];
int n;
int T;
int N[70];
int index;

void t0(){
    for(int i=0;i<8;i++){
        for(int j=0;j<8;j++){
            if((i+j)%2==0){//偶数 
            if(i+j<=7){
                index = (i+j)*(i+j+1)/2+j;
                M[i][j] = N[index];
            }
            else{
                index = 36+(23-i-j)*(-8+i+j)/2+7-i;
                M[i][j] = N[index];
            }
            }
            else{//奇数 
            if(i+j<=7){
                index = (i+j)*(i+j+1)/2+i;
                M[i][j] = N[index];    
            }
            else{
                index =36+ (23-i-j)*(-8+i+j)/2+7-j;
                M[i][j] = N[index];
            }
        }
        }
    }
}

void t1(){
    t0();
    for(int i=0;i<8;i++)
        for(int j=0;j<8;j++)
            M[i][j]*=Q[i][j];
}

void t2(){
    t1();
    for(int i=0;i<8;i++){
        for(int j=0;j<8;j++){
            double tempres = 0;
            for(int u=0;u<8;u++){
                for(int v=0;v<8;v++){
                    double temptempres = M[u][v];
                    if(u==0) temptempres*=sqrt(0.5);
                    if(v==0) temptempres*=sqrt(0.5);
                    temptempres*=cos(acos(-1)/8*(i+0.5)*u)*cos(acos(-1)/8*(j+0.5)*v);
                    tempres += temptempres;
                }
            }
            MM[i][j] = tempres/4+128;
            if(MM[i][j]>=255) MM[i][j] = 255;
            else if(MM[i][j]<=0) MM[i][j] = 0;
            else MM[i][j] =  round(MM[i][j]);
        }
    }
    for(int i=0;i<8;i++)
        for(int j=0;j<8;j++)
            M[i][j] = MM[i][j];
}

int main(){
    for(int i=0;i<8;i++)
        for(int j=0;j<8;j++)
            cin>>Q[i][j];
    cin>>n>>T;
    for(int i=0;i<n;i++) cin>>N[i];
    if(T==0) t0();
    else if(T==1) t1();
    else if(T==2) t2();
    for(int i=0;i<8;i++){
        for(int j=0;j<8;j++){
            cout<<M[i][j]<<" ";}
        cout<<endl;}
}

Guess you like

Origin blog.csdn.net/Sunnyztg/article/details/129510722