CCF 201909-3 字符画
CCF 201909-3 字符画
题意:
-
将n * m的RGB图片压缩成q * p的块,每块为该原像素的平均值,我们暂且称之为像素块
(代码注释为字符块)。 -
输入n行m列的RGB图片:
- 第一行:图片的宽m高n
- 第二行:要压缩的单位宽p高q,即对原图片的每q*p个像素取平均值得到像素块,保证输入得到整数个像素块。
- 接下来n*m行,自上到下,自左往右输入图片的HTML格式的像素:
- #a 表示RGB(0xaa,0xaa,0xaa)
- #abc 表示RGB(0xaa,0xbb,0xcc)
- #abcdef 表示RGB(0xab,0xcd,0xef)
-
输出压缩后的图片的背景色
- 像素块行处理:
- 若背景色与该行的像素块的前一块(第一块与默认值比较)颜色相同,则不处理;否则若与默认值相同则输出 ESC[0m 的格式化表示,不相同则输出 ESC[48;2;R;G;Bm 的格式化表示(此处RGB指代像素块的RGB)。
- 每一个像素块后必须紧跟一个格式化的空格: \x20
- 像素块行尾处理:
- 若该行的最后一个像素块颜色不是默认值则输出 ESC[0m 的格式化表示。
- 始终在像素块行尾追加一个格式化的回车: \x0A
- 像素块行处理:
考点:
- 字符串进制转换
- 递推循环
- 数字按位分割
上面引自Here
//100分 453ms #include<iostream> #include<iomanip> #define OPT __attribute__((optimize("O3"))) using namespace std; const int N=2e3; short c[N][N][3];//c[n][m][Pixel:RGB] 表示原图片在第n行m列的像素颜色 int m,n,p,q,PQ,R,G,B,r,g,b,num[10];string s; OPT inline short getCell(const char &a,const char &b){//将16进制像素数转换为10进制的char return (isalpha(a)?(10+a-'a'):(a-'0'))*16+(isalpha(b)?(10+b-'a'):(b-'0')); } OPT inline void outChar(const char &ch){//输出题意格式化的字符 cout<<"\\x"<<hex<<uppercase<<setw(2)<<int(ch); } OPT inline void outStr(const string &str){//输出题意格式化的字符串 for(const char &ch:str) outChar(ch); } inline void outCell(int x){ int cnt(0); if(!x) num[++cnt]=0; for(;x;x/=10) num[++cnt]=x%10; for(int i=cnt;i;i--) outChar(char(num[i]+'0')); } OPT int main(){ ios::sync_with_stdio(false); cin>>m>>n>>p>>q,PQ=p*q,cout.fill('0'); for(int i=1;i<=n;i++){ for(int j=1,len;j<=m;j++){ cin>>s;len=s.length(); switch(len){//统一格式标准化为 #abcdef case 2:s=s+string(5,s[1]);break; case 4:s="#"+string(2,s[1])+string(2,s[2])+string(2,s[3]);break; } for(int k=0;k<3;k++) c[i][j][k]=getCell(tolower(s[k*2+1]),tolower(s[k*2+2])); } } for(int i=1;i<=n;i+=q){//共n/q个字符块行 for(int j=1;j<=m;j+=p){//每字符块行共m/p段 R=G=B=0;//以下处理属于i行j段的字符块 for(int k=i,ke=k+q;k<ke;k++) for(int l=j,le=j+p;l<le;l++) R+=c[k][l][0],G+=c[k][l][1],B+=c[k][l][2]; R/=PQ,G/=PQ,B/=PQ;//求平均值 if(R!=r||G!=g||B!=b){//如果与该行上一段的颜色不同 if(!R&&!G&&!B)//如果与默认值相同 outStr(string(1,char(27))+"[0m"); else//其他颜色处理 outStr(string(1,char(27))+"[48;2;"),outCell(R),outChar(';'),outCell(G),outChar(';'),outCell(B),outChar('m'); r=R,g=G,b=B;//记录上次的颜色 } outChar(' ');//输出 (n*m)/(p*q) 个空格 } if(R||G||B) outStr(string(1,char(27))+"[0m");//行尾判断是否需要重置颜色 r=g=b=0;//重置默认颜色 outChar('\n');//输出n/q个回车 } return 0; }