1.解题思路
首先根据m,n,p,q计算出每一个p*q的色块的R,G,B的平均值,通过四重循环实现,外两层为色块间转移,步长分别为q,p,内两层统计每一色块的R,G,B值的总和。
其次判断当前R,G,B是否与前一R,G,B颜色相同,如果相同只需要输出“\\x20”即空格,表示不更改,如果不同,判断是否与终端颜色相同,相同则按终端方式重置,不同则更改为相应的R,G,B值,并更新前一R,G,B值,在每一行结束之后,还需要判断当前终端颜色是否是默认值(即0,0,0)来判断是否需重置终端,最后加上换行"\x0A"即可。
细节见注释(srds,似乎没涉及字符颜色的更改?)
2.满分代码
#include<bits/stdc++.h>
using namespace std;
struct Pixel{
unsigned char r;
unsigned char g;
unsigned char b;
pixel(){
}
pixel(unsigned char R,unsigned char G,unsigned char B)
{
r=R;
g=G;
b=B;
}
}pixel[1081][1921];
void tran(string &s)//将r,g,b转成十六进制
{
string result="";
for(int i=0;i<s.size();i++)
{
result+="\\x3"+s.substr(i,1);//逐个字符读取
}
s=result;
}
int main()
{
int m,n,p,q;
cin>>m>>n;
cin>>p>>q;
string str;
string r,g,b;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cin>>str;
if(str.size()==7)//#111111
{
r=str.substr(1,2);
g=str.substr(3,2);
b=str.substr(5,2);
}
else if(str.size()==4)//#111
{
r=string(2,str[1]);
g=string(2,str[2]);
b=string(2,str[3]);
}
else if(str.size()==2)//#1
{
r=string(2,str[1]);
g=r;
b=r;
}
pixel[i][j]={(unsigned char)stoi(r,nullptr,16),(unsigned char)stoi(g,nullptr,16),(unsigned char)stoi(b,nullptr,16)};
}
}
int R=0,G=0,B=0;
string result="";
int before_r=0,before_g=0,before_b=0;//表示上一色块颜色 初始终端默认颜色
for(int i=1;i<=n;i+=q)
{
for(int j=1;j<=m;j+=p)
{
R=0,G=0,B=0;
for(int x1=i;x1<i+q;x1++)//统计每个P*q的图片的像素之和
{
for(int y1=j;y1<j+p;y1++)
{
R+=pixel[x1][y1].r;
G+=pixel[x1][y1].g;
B+=pixel[x1][y1].b;
}
}
R/=p*q;
G/=p*q;
B/=p*q;
if((R==before_r)&&(G==before_g)&&(B==before_b))//颜色与上次相同
{
result+="\\x20";
}
else if((R==0)&&(G==0)&&(B==0))//与终端默认颜色相同则重置终端
{
result+="\\x1B\\x5B\\x30\\x6D\\x20";
}
else//更改字符颜色
{
string r=to_string(R);
string g=to_string(G);
string b=to_string(B);
tran(r);
tran(g);
tran(b);
result+="\\x1B\\x5B\\x34\\x38\\x3B\\x32\\x3B"+r+"\\x3B"+g+"\\x3B"+b+"\\x6D\\x20";
}
before_r=R;
before_g=G;
before_b=B;
}
if(before_r!=0||before_g!=0||before_b!=0)//重置终端
{
result+="\\x1B\\x5B\\x30\\x6D";
}
result+="\\x0A";//加换行
before_r=0;
before_g=0;
before_b=0;
}
cout<<result<<endl;
return 0;
}