201909-3 character painting is easy to understand and uses the simplest code

Keywords: ascii


Do not pursue the most concise code, pursue the most readable code, and strive to make the reader understand and write the code again

Examination questions

According to the meaning of the topic, the color of the area entered in each line does not distinguish the foreground color and background color. The topic changes the background color, so only the background color is changed by default.

1. The foreground color and background color of the terminal are default values at the beginning (foreground white, background black)

If the foreground or background color calculated by the first area is the default value, you do not need to output to the terminal, but you need to output spaces.

2. If the next character and color exactly match the default, you should use the reset escape sequence instead of manually changing the color.

3. If the foreground / background color of a character is the same as its previous character, or the change of color does not affect the final display effect, the control sequence of changing this property should not appear.

Don't forget to output space.

4. After entering each line of characters, if the terminal color is not the default value, you should reset the terminal color status.

Line feed is also required at the end of each line \ n

5. Special cases need to be handled. aabbcc can be written as "abc" and "aaaaaa" can be written as "a"

In three cases, let's deal with okk alone

2, Algorithm strategy

1. Color storage, color conversion, use dot [m][n] to mark the color of any coordinate.

struct dot{
	int R;
	int G;
	int B;
	dot(int a,int b,int c){
		R = a;
		G = b;
		B = c;
	}
}

Convert string to dot and take out a function separately.

3. For area calculation, the number of areas is (mn)/(pq), and the number of lines is n/q. use vector link, and pay attention to the area branch.

4. The initial background color and foreground color are set as the precursor at the beginning of each line, and the precursor is marked to omit the change of color.

5. Don't leave out the situation given by the subject when simulating. Control it strictly in the macro level, and then realize it locally.

void outputRGB()
{
    int size = list.size(); //Number of blocks in a region
    int gap = m/p;       // gap areas per line
    int i;
    dot pre; //Previous area
    dot curr; //Current region
    for(i=0;i<size;i++)
    {
        curr = list[i];
        if(i%gap == 0) // 1. The first in each line sets the front color as the default background color
            pre = defaultDot;

        if(isEqual(curr,pre))   // 2. The current color is the same as the precursor color. Output a space without changing
            outputSpace();
        else if(isEqual(curr,defaultDot)){ // 3. The current color is the default background color
            outputDefaultRGB();     // Output reset terminal, not current color
            outputSpace();         //Output a space
        }
        else{ // Common output
            outputSingleRGB(curr);
        }
        if( (i+1)%gap ==0 && !isEqual(curr,defaultDot)){ // The last one in each line is not the default color
            outputDefaultRGB();
        }
        if( (i+1)%gap == 0 ) // Last in each line
            printf(R"(\x0A)"); //Output'\n'

        pre = curr; // Update forerunner
    }
}

After making sure that the appeal does not miss the situation given by the title, implement the subfunction again.

The final AC code is as follows.

#include <iostream>
#include <cstdio>
#include <string>
#include <vector>
using namespace std;
int m,n;
int p,q;
struct dot{
    int R;
    int G;
    int B;
    dot(int a,int b,int c){
        R = a;
        G = b;
        B = c;
    }
    dot(){
        R=G=B=0;
    }
};
dot arr[1100][2000];
dot defaultDot(0,0,0); // Default background color
vector<dot> list;
int toAscii(char ch)
{
    if(ch>='a')
        return ch-'a'+10;
    else
        return ch-'0';
}
dot strToDot(string str)
{
    str.erase(str.begin()); //Remove lead#
    dot res;
    int len = str.length();
    if(len == 6){
        res.R = toAscii(str[0])*16 + toAscii(str[1]);
        res.G = toAscii(str[2])*16 + toAscii(str[3]);
        res.B = toAscii(str[4])*16 + toAscii(str[5]);
    }
    else if(len == 1){
        str += str[0];
        res.R = res.G = res.B = toAscii(str[0])*16 + toAscii(str[1]);
    }
    else{ //len = 3
        res.R = toAscii(str[0])*16 + toAscii(str[0]);
        res.G = toAscii(str[1])*16 + toAscii(str[1]);
        res.B = toAscii(str[2])*16 + toAscii(str[2]);
    }
    return res;
}
dot countDot(int row,int endRow,int col,int endCol)
{
    dot res;
    int i,j;
    for(i=row;i<endRow;i++)
        for(j=col;j<endCol;j++)
        {
            res.R += arr[i][j].R;
            res.G += arr[i][j].G;
            res.B += arr[i][j].B;
        }
    int area = (endRow-row)*(endCol-col);
    res.R /= area;
    res.G /= area;
    res.B /= area;
    return res;
}
bool isEqual(dot a,dot b)
{
    return (a.R==b.R && a.G==b.G && a.B==b.B);
}
void outputDefaultRGB()
{
    printf(R"(\x1B\x5B\x30\x6D)"); // ESC[0m
}
void outputNumber(int num)
{
    string str;
    str = to_string(num);
    for(char i : str)
    {
        int a = int(i); //Convert to ascii code
        printf(R"(\x)");
        printf("%X",a);
    }
}
void outputSingleRGB(dot curr)
{
    printf(R"(\x1B\x5B\x34\x38\x3B\x32\x3B)"); // ESC[48;2;
    outputNumber(curr.R);
    printf(R"(\x3B)");
    outputNumber(curr.G);
    printf(R"(\x3B)");
    outputNumber(curr.B);
    printf(R"(\x6D\x20)");     // m+space
}
void outputSpace()
{
    printf(R"(\x20)");
}
void outputRGB()
{
    int size = list.size();
    int gap = m/p;       // gap areas per line
    int i;
    dot pre; //Previous area
    dot curr; //Current region
    for(i=0;i<size;i++)
    {
        curr = list[i];
        if(i%gap == 0) // 1, The first setting in each line is the default background color
            pre = defaultDot;

        if(isEqual(curr,pre))   // 2. The current color is the same as the precursor color. Output a space without changing
            outputSpace();
        else if(isEqual(curr,defaultDot)){ // 3. The current color is the default background color
            outputDefaultRGB();     // Output reset terminal, not current color
            outputSpace();         //Output a space
        }
        else{ // Common output
            outputSingleRGB(curr);
        }
        if( (i+1)%gap ==0 && !isEqual(curr,defaultDot)){ // The last one in each line is not the default color
            outputDefaultRGB();
        }
        if( (i+1)%gap == 0 ) // Last in each line
            printf(R"(\x0A)"); //Output'\n'

        pre = curr; // Update forerunner
    }
}
int main() {
    cin>>m>>n;
    cin>>p>>q;
    int i,j;
    string str;
    for(i=1;i<=n;i++)
        for(j=1;j<=m;j++)
        {
            cin>>str;
            arr[i][j] = strToDot(str);
        }
    i = j = 1;
    while( i<=n )
    {
        dot t = countDot(i,i+q,j,j+p);
        list.push_back(t);
        j += p;
        if( j > m )
        {
            j = 1;
            i += q;
        }
    }
    outputRGB();
    return 0;
}
174 original articles published, 18 praised, 10000 visitors+
Private letter follow

Posted by jammesz on Tue, 18 Feb 2020 01:54:37 -0800