【发布时间】:2015-01-30 10:12:25
【问题描述】:
这是不久前的高中学位编码竞赛问题。其基本思想是仅使用矩形 XOR 运算重新创建黑白绘画,或者这就是他们所说的。
问题
假设我们正在尝试重建这幅画(表示为二进制矩阵,0 为黑色,1 为白色):
1 0 0
1 1 1
1 0 1
重建绘画的一种方法是以下操作:
(0, 0) (2, 2)
(1, 0) (2, 0)
(1, 2) (1, 2)
操作形式为(xStart, yStart) (xEnd, yEnd)
因此,如果我们从全黑画布开始,上述操作将执行以下操作:
beginning:
0 0 0
0 0 0
0 0 0
after (0, 0) (2, 2) :
1 1 1
1 1 1
1 1 1
after (1, 0) (2, 0) :
1 0 0
1 1 1
1 1 1
after (1, 2) (1, 2) :
1 0 0
1 1 1
1 0 1
关于作业的技术:
- 获胜者的操作最少。
- 一个操作应该是
(xStart, yStart) (xEnd, yEnd)的形式。 - 没有时间或空间限制。
- 在作业中,我们尝试重新创建的绘画尺寸为 200x200,并通过 2000 次随机 XOR 运算生成。
我自己的想法
我想出了几种方法来做到这一点。我将在此处按从差到优的顺序列出它们。
XOR 所有像素:
我们可以通过简单地将 1 写入空白画布来重新创建这幅画,其中 1 驻留在我们试图重新创建的画作中。这个解决方案是最简单和最明显的。所需的操作数基本上就是画中白色像素的数量。
XOR 所有水平相邻的白色:
与第一个解决方案相比,这是一个实质性的改进,但仍然非常简单和明显。在这种方法中,我们只需对所有水平相邻的白色进行异或运算。这样,例如操作
(0, 0) (0, 0)
(1, 0) (1, 0)
(2, 0) (2, 0)
将减少到(0, 0) (2, 0)。
异或矩形:
我认为这是对先前方法的明确跟进,我们可以将其视为对高度为 1 的矩形进行异或运算 - 现在我们只需为矩形添加第二个维度,进一步改进我们的结果。我通过获取白色最多的矩形来确定 XORable 区域。改进还是不错的。
XOR 最大的区别:
这与上述方法略有不同,并且更加暴力。在这种方法中,我找到了与绘画差异最大的矩形,并对其进行异或。例如,如果我们有这幅画
1 0 1
0 1 1
0 1 0
和一个全黑的画布,最大的区别是矩形(0, 0) (2, 1),相差2。我通过获取绘画的所有不同颜色来计算差异,即4上面的情况,然后减去相同颜色的数量,在上面的情况下是2。所以different_colors - same_colors = difference。
在上面的绘画和空白画布中,有许多矩形产生相同的差异。另一个是(1, 0) (2, 2)。
与前一种大型绘画方法相比,这种方法的改进最小,但仍然有所改进。有趣的是,这种方法有时会比以前的小画解决方案更糟糕(但不记得有多小了)。
我为上述方法所拥有的任何代码早已丢失。你能想出令人叹为观止的解决方案吗?有来自外太空的神奇方法吗?我觉得这个问题(帖子)很有趣,想看看是否有人能提出任何建议。
关于标签
我已经用 Java 和 C++ 标记了这个,不是因为这个问题特别关注那些语言,而是因为我可以很容易地理解用这些语言编写的任何代码,以及具有相似语法的语言。
【问题讨论】:
-
@weston 这个问题对 stackexchange 的用户来说并不是一个难题。我个人希望在这些用户的帮助下找到一个很好的解决方案。
-
“异或”我认为您的意思是“与 1 进行异或”,即翻转位。
-
@user1990169 它只是在翻转位,是的。 1 变成 0,0 变成 1。
标签: java c++ algorithm binary xor