原题链接:计算机软件能力认证考试系统
#include <iostream>
#include <string>
#include <stack>
#define M 2000
#define N 1100
using namespace std;
int m,n,p,q;
string s[N][M],ss;
string deal(string s){//转换成六个字符的形式
s.erase(0,1);
if(s.size()==1) s=string(6,s[0]);
else if(s.size()==3) s=string(2,s[0])+string(2,s[1])+string(2,s[2]);
return s;
}
int calc(string s){//十六进制转十进制
int ret=0;
for(int i=0;i<2;i++){
if(isdigit(s[i])) ret=ret*16+s[i]-'0';
else ret=ret*16+s[i]-'a'+10;
}
return ret;
}
void tran(int c){//获得每一位上的数字
stack<int> st;
if(!c) st.push(0);//判断是否为0
while(c){
st.push(c%10);
c/=10;
}
while(!st.empty()){
int t=st.top(); st.pop();
printf("\\x%d",t+30);//输出每一位的ASCII码的16进制形式,0-9对应48-57,第一位均为3
}
}
int main()
{
ios::sync_with_stdio(false);
cin>>m>>n>>p>>q;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
cin>>ss;
s[i][j]=deal(ss);//将所有字符串改为rrggbb的形式,便于处理
}
}
int pr=0,pg=0,pb=0,r,g,b;//分别记录前一次颜色值和当前颜色值
for(int i=0;i<n;i+=q){//遍历每一个分块
for(int j=0;j<m;j+=p){
r=0;g=0;b=0;
for(int u=i;u<i+q;u++){//计算块内r、g、b的和
for(int v=j;v<j+p;v++){
r+=calc(s[u][v].substr(0,2));//十六进制转十进制
g+=calc(s[u][v].substr(2,2));
b+=calc(s[u][v].substr(4,2));
}
}
r/=(p*q); g/=(p*q); b/=(p*q);//求平均值
if(r==pr&&g==pg&&b==pb) printf("\\x20");//和前一次颜色相同,输出空格
else if(!r&&!g&&!b){//与默认颜色相同
pr=r; pg=g; pb=b;
printf("\\x1B\\x5B\\x30\\x6D\\x20");//输出重置语句和空格
}
else{
pr=r; pg=g; pb=b;
printf("\\x1B\\x5B\\x34\\x38\\x3B\\x32\\x3B");//输出转义序列的前半部分
tran(r);printf("\\x3B");//输入r和';'
tran(g);printf("\\x3B");//输入g和';'
tran(b);printf("\\x6D\\x20");//输入b和"m "
}
}
if(r||g||b){//如果不是默认值,重置
pr=pg=pb=0;
printf("\\x1B\\x5B\\x30\\x6D");
}
printf("\\x0A");//一层遍历结束,输出换行
}
return 0;
}