[Java] 201909-3 字符画

import java.io.*; 
import java.util.StringTokenizer; 

class RGB {
	private final int RADIX = 16;
	private int r, g, b;
	public RGB(String pixel) {
		if (pixel.length() == 2) {
			r = g = b = Integer.parseInt(pixel.substring(1, 2) + pixel.substring(1, 2), RADIX);
		}
		else if (pixel.length() == 4) {
			r = Integer.parseInt(pixel.substring(1, 2) + pixel.substring(1, 2), RADIX);
			g = Integer.parseInt(pixel.substring(2, 3) + pixel.substring(2, 3), RADIX);
			b = Integer.parseInt(pixel.substring(3, 4) + pixel.substring(3, 4), RADIX);
		}
		else {
			r = Integer.parseInt(pixel.substring(1, 3), RADIX);
			g = Integer.parseInt(pixel.substring(3, 5), RADIX);
			b = Integer.parseInt(pixel.substring(5, 7), RADIX);
		}
	}
	public void add(RGB that) {
		this.r += that.r;
		this.g += that.g;
		this.b += that.b;
	}
	public RGB average(int count) {
		this.r /= count;
		this.g /= count;
		this.b /= count;
		return this;
	}
	public String toString() {
		StringBuilder ans = new StringBuilder();
		ans.append("\\x3B");
		for (char ch : String.valueOf(r).toCharArray()) {
			ans.append("\\x").append(String.format("%X", (int)ch));
		}
		ans.append("\\x3B");
		for (char ch : String.valueOf(g).toCharArray()) {
			ans.append("\\x").append(String.format("%X", (int)ch));
		}
		ans.append("\\x3B");
		for (char ch : String.valueOf(b).toCharArray()) {
			ans.append("\\x").append(String.format("%X", (int)ch));
		}
		ans.append("\\x6D");
		return ans.toString();
	}
	public boolean equals(RGB that) {
		return this.r == that.r && this.g == that.g && this.b == that.b;
	}
}
public class Main {

	private String space = "\\x20";
	private String newLine = "\\x0A";
	private String reset = "\\x1B\\x5B\\x30\\x6D";
	private String changBackground = "\\x1B\\x5B\\x34\\x38\\x3B\\x32";

	public Main() {
        Scanner sc = new Scanner(System.in); 
        PrintWriter out = new PrintWriter(System.out);
        int m = sc.nextInt(), n = sc.nextInt();
        int p = sc.nextInt(), q = sc.nextInt();
        RGB[][] image = new RGB[n][m];
        for (int i = 0; i < n; i++) {
        	for (int j = 0; j < m; j++) {
        		String pixel = sc.next();
        		image[i][j] = new RGB(pixel);
        		// out.println(image[i][j]);
        	}
        }
        RGB defau = new RGB("#0"); // 默认颜色
        int _n = n / q, _m = m / p;
        for (int i = 0 ; i < _n; i++) {
        	// 每一行开始的前一个字符均为默认颜色
	        RGB prev = defau;
        	for (int j = 0; j < _m; j++) {
				RGB cur = new RGB("#0"); // 当前的颜色
				for (int ki = q * i; ki < q * (i+1); ki++) {
					for (int kj = p * j; kj < p * (j+1); kj++) {
						cur.add(image[ki][kj]);
					}
				}
        		cur.average(p * q);
        		// 如果颜色与前一个字符相同,不必输出控制序列
        		if (cur.equals(prev)) {
        		}
        		// 如果颜色与默认值完全相同,直接使用重置转义序列
        		else if (cur.equals(defau)) {
        			out.print(reset);
        		}
        		else {
        			out.print(changBackground + cur);
        		}
        		prev = cur;
        		// (m * n)/(p * q) = _n * _m 个空格
        		out.print(space);
        	}
        	// 如果终端颜色不是默认值,则重置终端颜色状态
        	if (!prev.equals(defau)) {
        		out.print(reset);
        	}
        	// (n / q) = _n 个换行符
        	out.print(newLine);
        }
		out.flush();
	}

    public static void main(String[] args) { 
    	new Main();
    }
} 

class Scanner{
	private BufferedReader reader;
	private StringTokenizer st;

	public Scanner(InputStream stream){
		reader = new BufferedReader(new InputStreamReader(stream));
		st = null;
	}

	public String next(){
		while(st == null || !st.hasMoreTokens()){
			try {
				String line  = reader.readLine();
				if (line == null) return null;
				st =  new StringTokenizer(line);
			} catch (Exception e) {
				throw (new RuntimeException());
			}
		}
		return st.nextToken();
	}

	public int nextInt(){
		return Integer.parseInt(next());
	}
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值