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; }