【CSP】201909-3 字符画
大模拟,but intersting!因为我在MacOS上写代码,所以确实能看见颜色控制字符如何控制终端颜色,非常的漂亮啊(赞赏)。
总之大约用时2h,最后30min排查bug,没认真读题导致的。写这种大模拟的思路还是解耦模块分别测试。
有时候实在不想做算法题就写下大模拟放松心情,因为确实不用动脑子。也许是C++非常适合造轮子的缘故。
#include <cstdio> #include <iostream> #include <algorithm> #include <vector> #include <set> #include <string.h> #include <string> #define up(l,r,i) for(int i=l;i<=r;i++) #define dn(l,r,i) for(int i=r;i>=l;i--) typedef long long ll; using namespace std; inline int _max(const int& a,const int& b){return a>b?a:b;} inline int _min(const int& a,const int& b){return a<b?a:b;} const int MAXN = 2020; inline int ctoi(char c){ if(c >= 'a' && c <= 'z') c = c-'a'+10; else if(c >= 'A' && c <= 'Z') c = c-'A'+10; else if(c >= '0' && c <= '9') c = c-'0'; return c; } inline char itoc(int x){ char ret; if(x > 9) ret = 'A'-10+x; else ret = x+'0'; return ret; } inline int xto10(char a,char b){ int ret = ctoi(a)*16 + ctoi(b); return ret; } string cto16(char c){ int x = (int)c; int a = x%16; x /=16; int b = x%16; string ret; ret = "\\x"; ret += itoc(b); ret += itoc(a); return ret; } struct RGB{ int d[3]; RGB(){memset(d,0,sizeof(d));} RGB(int r,int g,int b){ d[0] = r; d[1] = g; d[2] = b; } RGB operator +(const RGB &a){ RGB ret; up(0,2,i) ret.d[i] = this->d[i]+a.d[i]; return ret; } RGB operator /(const int &a){ RGB ret; up(0,2,i) ret.d[i] = this->d[i]/a; return ret; } bool operator ==(const RGB &a){ bool ret = 1; up(0,2,i) if(d[i] != a.d[i]) {ret = 0;break;} return ret; } bool operator !=(const RGB &a){ return (*this==a)?0:1; } string rgbtos(){ string ret; up(0,2,i){ ret += to_string(d[i]); if(i != 2) ret += ';'; else ret += 'm'; } return ret; } void pr(){ printf("(%d,%d,%d)",this->d[0],this->d[1],this->d[2]); } }; int n,m; int w,h; int p,q; RGB origin[MAXN][MAXN]; RGB dat[MAXN][MAXN]; int main() { //freopen("y.out","w",stdout); //ios::sync_with_stdio(false); // //cout<<cto16('\n')<<endl; cin>>m>>n>>p>>q; getchar(); up(1,n,i){ up(1,m,j){ string s; getline(cin,s); int l = s.length(); s = s.substr(1,l-1); l--; if(l == 1){ up(0,2,k) origin[i][j].d[k] = xto10(s[0],s[0]); } else if(l == 3){ up(0,2,k) origin[i][j].d[k] = xto10(s[k],s[k]); } else if(l == 6){ up(0,2,k) origin[i][j].d[k] = xto10(s[k*2],s[k*2+1]); } //printf("读取到的颜色数据(%d,%d,%d)\n",origin[i][j].d[0],origin[i][j].d[1],origin[i][j].d[2]); } } w = m/p; h = n/q; up(1,h,i){ up(1,w,j){ RGB sum; up((i-1)*q+1,i*q,k){ up((j-1)*p+1,j*p,l){ sum = sum+origin[k][l]; } } dat[i][j] = sum/(p*q); //printf("在(%d,%d)处的色块平均值为",i,j); //sum.pr(); //cout<<endl; } } string ans; RGB last(0,0,0); RGB def = last; up(1,h,i){ up(1,w,j){ //printf("添加的RGB=%s\n",dat[i][j].rgbtos().c_str()); if(last != dat[i][j]){ if(dat[i][j] != def) ans += "\033[48;2;"+dat[i][j].rgbtos(); else ans += "\033[0m"; last = dat[i][j]; } ans += ' '; } if(last != def){ ans += "\033[0m"; last = def; } ans += '\n'; } int l = ans.length(); up(0,l-1,i){ cout<<cto16(ans[i]); } return 0; }