問題の第三の問題の解決 - キャラクターの絵 - 13日CCFのコンピュータ専門の認定試験
質問番号:201909から3
質問名:キャラクター塗装
時間制限を:5.0s
メモリ制限を:512.0メガバイト
問題の解決策
最初のマップ時:
そしてACCIIコードをリリース:
ポイントは、私は、ASCIIコードを参照してください
そして、いくつかのリリースprintf
:印刷技能の機能
異なるコンテンツ出力%でC言語を
私はこのトピックはまだピットがたくさんあると言っています!
トピックの前景色と背景色を変更する方法を与えられたが、我々は唯一の背景色を使用する必要があるので、フォアグラウンドの色をコントロールしていないされています
最初はデータを読まれないことです
への難しさ、有料の注意を
16進数に変換され
間違いない場合に進
そして、各小領域の平均色を算出し、我々は何の困難もなかったです
その後、我々は、変更プロセスカラーを記述する必要があり、困難を来ました。
私は、文字列のコースを変更するには、最初の印刷を選択しました
用い、その後、%02X
印刷を
自然の六角[印刷]をクリックします
各文字の。
各色を列挙ターンでは、各印刷は、以前の色は、現在の文字の前の文字の色で、変更色に同じ必要でない場合は、新しい色を設定するかどうかを判断する。現在の文字は、デフォルト以外の最初の文字と色であれば色(黒)だけでなく、色を変更します。
小さなディップがあることに注意してください:
木があり、長い時間のためにこのカードTM文私......
~~> _ <~~
不快な
コード
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <string>
#include <cstring>
#define maxn 2000
#define _for(i, a) for(LL i = 0; i < (a); ++i)
typedef long long LL;
using namespace std;
struct poi {
LL R[3];
};
LL n, m, p, q; //原图像尺寸,区域图像尺寸
char s[maxn * maxn]; //原像素十六进制编码
LL mm, nn; //分割后的图像尺寸
poi a[maxn][maxn]; //像素/色块 颜色
char ans[maxn * maxn * 3]; //最终编码
LL al; //ans长度
LL flag; //当前颜色标识
void init() {
al = 0;
ans[0] = 0;
flag = 0; //默认背景色为黑色
}
LL getnum(char c) { //识别十六进制数字
if (c >= 'a' && c <= 'z') return c - 'a' + 10;
if (c >= 'A' && c <= 'Z') return c - 'A' + 10;
if (c >= '0' && c <= '9') return c - '0';
return -1;
}
bool equ(LL i, LL j) { //判断是否需要设置颜色
LL ffl = 0, f;
_for(k, 3) ffl = ffl * 256 + a[i][j].R[k];
f = (ffl == flag);
flag = ffl;
return f;
}
void sol() {
init();
cin >> m >> n >> p >> q;
//读取色块
_for(i, n) {
_for(j, m) {
cin >> s;
LL slen = strlen(s), t = 1, x, y;
if (slen == 4) { //#abc
_for(k, 3) {
x = getnum(s[t++]);
a[i][j].R[k] = x * 16 + x;
}
}
else if (slen == 2) { //#a
x = getnum(s[t]);
_for(k, 3) a[i][j].R[k] = x * 16 + x;
}
else { //#abcdef
_for(k, 3) {
x = getnum(s[t++]);
y = getnum(s[t++]);
a[i][j].R[k] = x * 16 + y;
}
}
}
}
mm = m / p;
nn = n / q;
//算出每个小块的平均色块
_for(i, nn) {
_for(j, mm) {
LL R[3] = { 0 }; //求和
_for(k, q) {
_for(l, p) {
_for(o, 3) {
R[o] += a[i*q + k][j*p + l].R[o];
}
}
}
_for(k, 3) a[i][j].R[k] = R[k] / p / q; //平均
}
}
//编码
_for(i, nn) {
_for(j, mm) {
if (!equ(i, j)) { //需要设置颜色
LL x[3] = { a[i][j].R[0], a[i][j].R[1], a[i][j].R[2] };
if (flag) sprintf(ans + al, "\x1B[48;2;%lld;%lld;%lldm ", x[0], x[1], x[2]), al = strlen(ans);
else sprintf(ans + al, "\x1B[0m "), al = strlen(ans);
}
else sprintf(ans + al, " "), al = strlen(ans); //不需要设置颜色
if (j == mm - 1 && flag) sprintf(ans + al, "\x1B[0m"), al = strlen(ans), flag = 0; //行末尾是否需要重置
if (j == mm - 1) sprintf(ans + al, "\x0A"), al = strlen(ans); //行末尾添加换行符
}
}
//printf("%s", ans);
//把编码转16进制输出
for (LL i = 0; ans[i]; i++) {
printf("\\x%02X", ans[i]);
}
}
int main() {
//freopen("in.txt", "r", stdin);
sol();
return 0;
}
/* 测试样例:
1 1
1 1
#010203
\x1B\x5B\x34\x38\x3B\x32\x3B\x31\x3B\x32\x3B\x33\x6D\x20\x1B\x5B\x30\x6D\x0A
2 2
1 2
#111111
#0
#000000
#111
\x1B\x5B\x34\x38\x3B\x32\x3B\x38\x3B\x38\x3B\x38\x6D\x20\x20\x1B\x5B\x30\x6D\x0A
4 4
2 2
#000000
#000000
#ffffff
#ffffff
#000000
#000000
#ffffff
#ffffff
#000000
#000000
#ffffff
#ffffff
#000000
#000000
#ffffff
#ffffff
\x20\x1B\x5B\x34\x38\x3B\x32\x3B\x32\x35\x35\x3B\x32\x35\x35\x3B\x32\x35\x35\x6D\x20\x1B\x5B\x30\x6D\x0A\x20\x1B\x5B\x34\x38\x3B\x32\x3B\x32\x35\x35\x3B\x32\x35\x35\x3B\x32\x35\x35\x6D\x20\x1B\x5B\x30\x6D\x0A
//printf("\033[38;2;255;0;0mHe11o\033[0m \033[38;2;0;0;255m\033[48;2;255;255;255mWor1d\033[0m\n");
*/