【CCF-CSP】201909-3字符画

 原题链接:计算机软件能力认证考试系统

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

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值