问题3147--3-1 坏苹果

3147: 3-1 坏苹果

时间限制: 2Sec 内存限制:256 MB
提交:6 解决:1
[ 状态] [ 讨论版] [ 提交] [命题人: ]
题目描述

空梦闲暇时间用 Kotlin 基于 JNI 写了一个 JVM 端的操作 Windows 控制台的库,通过这个库我们便可以在 JVM 中操作控制台。

为了展示库的功能,空梦决定使用这个库编写一个应用程序——在控制台播放“Bad Apple”。


空梦很快就写好了最基本的代码,但是非常遗憾的是,由于 JNI 存在一些性能损失,空梦逐帧绘制时出现了明显的卡顿,这段程序很显然是需要进行优化的。

空梦想出了两种优化方式:

  1. 多线程优化

  2. 画布重用

多线程优化顾名思义就是多个线程同时绘制一帧或多帧,以此更加充分的利用 CPU 的各个核心的性能;画布重用就是绘制当前帧时不重置画布,而是在上一帧(如果使用了多级缓存则需要在前 N - 1 帧)的基础上进行绘制,仅重绘两帧之间不同的像素。

这两种优化方法的思路都是可行的,前者尝试通过多线程技术优化程序性能,后者则尝试通过改变程序逻辑来优化性能。

经过一番抉择,空梦决定使用“画布重用”来进行优化,但是由于空梦太笨,没有搞定如何计算两帧之间的不同的区域,并推导出一个最优的重绘方案,现在他来寻求参加天梯赛的各位佬的帮助,希望佬们能够帮助他解决这个问题。

空梦已经为控制台建好了坐标系,坐标系原点位于控制台的左上角,X 轴向右为正,Y 轴向下为正,原点的坐标为 (0, 0);同时他也已经对图像进行了预处理,将“Bad Apple”的每一帧都转换为了灰度图像(RGB 图像具有三个通道,灰度图像仅有一个通道),并规定了区分亮色与暗色像素的分界线,大于等于 128 的像素认为是亮色,小于 128 的像素认为是暗色。

需要注意的是,控制台在绘制颜色时只能横向绘制,不能纵向绘制(即每次填充的矩形的高度只能为 1),绘制区域超过当前行的范围时会自动换行

假设我们现在有一个背景为亮色、长宽为 3 × 3 的画布:

222, 255, 160 128, 200, 255 233, 255, 151

现在我们要在 (0, 1) 的位置填充一个宽 4 的暗色矩形,填充后的结果为:

222, 255, 160 000, 000, 000 000, 255, 151

现在请你写一个程序,比较两帧的画面的差异,在保证填充区域最小的情况下,计算出绘制操作数量最少的方案。

输入

第一行输入两个正整数 n, m (1 ≤ n, m ≤ 500),其中 n 表示画布的宽,m 表示画布的高。

接下来 m 行每行 n 个非负整数,表示上一帧当前行的各个像素的灰度值 Ai,j,两两之间使用逗号间隔(行末没有逗号)。

接下来 m 行每行 n 个非负整数,表示要绘制的这一帧的当前行的各个像素的灰度值 Bi,j,两两之间使用逗号间隔(行末没有逗号)。

注:输入的每个灰度值 Ai,j, Bi,j均为三位整数,有前缀 0,∀Ai,j, Bi,j∈ {000, 001, 002, ... , 255}。保证最后一行数据行末包含换行符。

输出

先输出一行一个正整数 k,表示最少的操作数。

然后输出 k 行,每行表示一个绘制操作,一个绘制操作的格式如下:

x, y, color, width

其中 "x, y" 表示这个绘制操作起始的坐标点,"color" 表示要绘制的颜色("BLACK" 或 "WHITE",其中 "BLACK" 代表暗色,"WHITE" 代表亮色),"width" 表示绘制的宽度。

注意:逗号后包含一个空格,行末没有逗号。

输出时按绘制操作的起始坐标进行排序,逐行扫描(从左到右,从上到下)先扫描到的点先输出。

样例输入 Copy
3 3 222,255,160 128,200,255 233,255,151 222,255,160 000,000,000 000,255,151
样例输出 Copy
1 0, 1, BLACK, 4
提示

样例输入 2:

5 5 001,002,003,004,005 201,202,203,204,205 125,126,127,128,129 128,127,126,125,124 000,111,222,233,255 255,233,222,111,000 128,127,126,125,124 129,128,127,126,125 201,202,203,204,205 005,004,003,002,001

样例输出 2:

6 0, 0, WHITE, 3 1, 1, BLACK, 4 0, 2, WHITE, 2 3, 2, BLACK, 2 1, 3, WHITE, 4 2, 4, BLACK, 3

样例解释:

在样例输入 1 中,需要修改的坐标是 (0, 1), (1, 1), (2, 1), (0, 2),均为亮色改为暗色,所以我们在 (0, 1) 填充一个宽度为 4 的暗色矩形即可