字符画csp

1.解题思路

首先根据m,n,p,q计算出每一个p*q的色块的R,G,B的平均值,通过四重循环实现,外两层为色块间转移,步长分别为q,p,内两层统计每一色块的R,G,B值的总和。

其次判断当前R,G,B是否与前一R,G,B颜色相同,如果相同只需要输出“\\x20”即空格,表示不更改,如果不同,判断是否与终端颜色相同,相同则按终端方式重置,不同则更改为相应的R,G,B值,并更新前一R,G,B值,在每一行结束之后,还需要判断当前终端颜色是否是默认值(即0,0,0)来判断是否需重置终端,最后加上换行"\x0A"即可。

细节见注释(srds,似乎没涉及字符颜色的更改?)

2.满分代码

#include<bits/stdc++.h>
using namespace std;
struct Pixel{
	unsigned char r;
	unsigned char g;
	unsigned char b;
	pixel(){
	}
	pixel(unsigned char R,unsigned char G,unsigned char B)
	{
		r=R;
		g=G;
		b=B;
	}
}pixel[1081][1921];
void tran(string &s)//将r,g,b转成十六进制 
{
	string result="";
	for(int i=0;i<s.size();i++)
	{
		result+="\\x3"+s.substr(i,1);//逐个字符读取 
	}
	s=result;
}
int main()
{
	int m,n,p,q;
	cin>>m>>n;
	cin>>p>>q;
	string str;
	string r,g,b;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			cin>>str;
			if(str.size()==7)//#111111 
			{
				r=str.substr(1,2);
				g=str.substr(3,2);
				b=str.substr(5,2);
			}
			else if(str.size()==4)//#111 
			{
				r=string(2,str[1]);
				g=string(2,str[2]);
				b=string(2,str[3]);
			}
			else if(str.size()==2)//#1 
			{
				r=string(2,str[1]);
				g=r;
				b=r;
			}
			pixel[i][j]={(unsigned char)stoi(r,nullptr,16),(unsigned char)stoi(g,nullptr,16),(unsigned char)stoi(b,nullptr,16)};
		}
	} 
	int R=0,G=0,B=0;
	string result="";
	int before_r=0,before_g=0,before_b=0;//表示上一色块颜色 初始终端默认颜色 
	for(int i=1;i<=n;i+=q)
	{
		for(int j=1;j<=m;j+=p)
		{
			R=0,G=0,B=0;
			for(int x1=i;x1<i+q;x1++)//统计每个P*q的图片的像素之和 
			{
				for(int y1=j;y1<j+p;y1++)
				{
					R+=pixel[x1][y1].r;
					G+=pixel[x1][y1].g;
					B+=pixel[x1][y1].b;
				}
			} 
			R/=p*q;
			G/=p*q;
			B/=p*q;
			if((R==before_r)&&(G==before_g)&&(B==before_b))//颜色与上次相同 
			{
				result+="\\x20";
			}
			else if((R==0)&&(G==0)&&(B==0))//与终端默认颜色相同则重置终端 
			{
				result+="\\x1B\\x5B\\x30\\x6D\\x20";
			}
			else//更改字符颜色 
			{
				string r=to_string(R);
				string g=to_string(G);
				string b=to_string(B);
				tran(r);
				tran(g);
				tran(b);
				result+="\\x1B\\x5B\\x34\\x38\\x3B\\x32\\x3B"+r+"\\x3B"+g+"\\x3B"+b+"\\x6D\\x20";
			}
			before_r=R;
			before_g=G;
			before_b=B;
		}
		if(before_r!=0||before_g!=0||before_b!=0)//重置终端 
		{
			result+="\\x1B\\x5B\\x30\\x6D";
		}
		result+="\\x0A";//加换行 
		before_r=0;
		before_g=0;
		before_b=0;
	}
	cout<<result<<endl;
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值