主要是系统化,模块化设计,先想好表示数据的类型,格式,进而设计大概的逻辑结构,然后依次按输入模块,逻辑处理模块,输出模块来分析解决问题,以这样的思路去做题会好做很多。
#include<bits/stdc++.h>
using namespace std;
class Pixel{ //像素点的有关操作和属性定义
public:
int R,G,B;
Pixel(int r=0,int g=0,int b=0)
{
R=r;
G=g;
B=b;
}
bool operator==(const Pixel &a)
{
if(R==a.R&&G==a.G&&B==a.B)
return true;
return false;
}
bool operator!=(const Pixel& a)
{
return !(*this==a);
}
void operator=(const Pixel &a)
{
R=a.R;
G=a.G;
B=a.B;
}
Pixel operator+(const Pixel &a)
{
return Pixel(R+a.R,G+a.G,B+a.B);
}
Pixel operator/(int v)
{
Pixel a;
a.R=R/v;
a.G=G/v;
a.B=B/v;
return a;
}
};
int Count(char a,char b) //处理输入用的,给两个字符ab,计算0xab下对应的10进制值
{
int sum=0;
if(a>='0'&&a<='9')
sum+=(a-'0')*16;
else
{
int k=a-'a'+10;
sum+=k*16;
}
if(b>='0'&&b<='9')
sum+=(b-'0');
else
{
int k=b-'a'+10;
sum+=k;
}
return sum;
}
Pixel Proce_str(string & s) //处理输入模块
{
int x=s.length();
switch(x)
{
case 2: //#a
{
int val=Count(s[1],s[1]);
return Pixel(val,val,val);}
case 4: //#abc
return Pixel(Count(s[1],s[1]),Count(s[2],s[2]),Count(s[3],s[3]));
default:
return Pixel(Count(s[1],s[2]),Count(s[3],s[4]),Count(s[5],s[6]));
}
}
char ESC=27; //转义
Pixel last=Pixel(); //上一个背景色状态, 默认为黑色
ostringstream fcout; //字符串输出流,方便后面统一格式化输出
void Print(Pixel & cur) //打印某个像素点
{
if(cur==last) //按照逻辑,此时直接打印
fcout<<" ";
else
{
last=cur;
if(cur==Pixel())
fcout<<ESC<<"[0m ";
else
fcout<<ESC<<"[48;2;"<<cur.R<<";"<<cur.G<<";"<<cur.B<<"m ";
}
}
int m,n;
int p,q;
Pixel Pho[2000][2000]; //最终的需要打印的像素点图
int main()
{
cin>>m>>n;
cin>>p>>q;
string s ;
int x,y;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
x=(i-1)/q; //这样x的取值就是[0,n/q - 1] 长度为n/q 下面类似,通过这样的算法,可以让所有的像素点归类到那个对应的q*p矩阵中
y=(j-1)/p;
cin>>s;
Pho[x][y]=Pho[x][y]+Proce_str(s);
}
int m_p=m/p;
int n_q=n/q;
int pq=p*q;
for(int i=0;i<n_q;i++)//开始打印
{
for(int j=0;j<m_p;j++)
{
Pho[i][j]=Pho[i][j]/pq;
Print(Pho[i][j]);
}
//这里比较坑,题目没说明白每一行重置打印的先后顺序,需要分析输出 来推测
if(last!=Pixel())
{
last=Pixel();
fcout<<ESC<<"[0m";
}
fcout<<"\n";
}
string ans=fcout.str();
for(int i=0;i<ans.size();i++)
printf("\\x%02X",(unsigned int)ans[i]);
return 0;
}
/*
1 1 1 1
#010203
*/