在我的空闲时间里,我喜欢通过解决topcoder.com或uva.onlinejudge.com等网页上的问题来优化我的算法/编程技巧(好吧,我的技能很糟糕,我试图改进它们)。通常我可以为更简单的问题编写和编码正确的算法 - 我理解大多数关于递归或图形等基本概念。
问题是,大部分时间,我都无法解决更难的问题。至于现在,我偶然发现了这个(在spoj.pl上):
小约翰尼正在和他一起玩 小魔法邮票,试图绘制一个 兔子在一张纸上 k由k分为单位 正方形与约翰尼的印章是 一个有3边的正方形,由 较小的正方形与边1.完全正确 其中两个正方形突出。 而且,两个突出的正方形都是 在同一行或同一列中。 如果约翰尼想用画画 这张邮票,他把它压到了一块 以这样的方式纸张 突出的正方形完全匹配一些 这张纸的正方形。如果有的话 突出的方形触及这件作品 纸上,感动的广场上 一张纸改变它的颜色 - 从黑色到白色或从白色到白色 黑色。小邮票可以放置 部分在纸上, 但突出的方块总是如此 在里面。邮票可以 以任何方式转移,但它不可能 转动。一开始这张纸是 整个白色。兔子包括 一些黑色的方块 (剩下的都必须是 白色)。约翰尼试图画出兔子 带着他的小印章很长一段时间 时间,但他没有成功(这个 并不一定意味着 兔子不能画,但只能画 画画非常困难 在如此大的纸上使用 这么小的邮票!)。所以他问他 哥哥,大约翰,寻求帮助。
大约翰可以帮助小约翰尼 给他一个巨大的神奇印章。该 大邮票的尺寸是s,有一个 任意数量的突起 正方形(这些正方形没有 必然需要位于 相同的行或列)。这个邮票有效 就像小邮票一样,但是 强制执行一项额外约束 - 它只能按在一块上 如果纸完全在纸内 一张纸。
在大约翰给小约翰尼之前 他想要制作他的大邮票 确保一起使用的邮票是 足以画出兔子。他问 你在帮助确定那个。 输入
标准输入的第一行 包含一个整数t(1≤t≤10) 表示测试用例的数量。
单个测试用例的描述 以带有两个整数s的行开头 和k(1≤s≤k≤1000,1≤s≤200) 由一个空格隔开。他们 表示大约翰的邮票大小 和那张纸的大小。
以下三行包含一个 小约翰尼的描述 邮票。这些行中的每一行都包含 三个字符0或1.这样的 说明显示如何白色 一张纸看起来像之后 按下小印章:0表示 白色方块,1 - 黑色 广场。正好两个字符 这三条线都是一条线 两者都位于同一行或 在同一列中。请注意 这种描述没有说明 邮票本身的设计 - 邮票与绘制的图形对称 把它放在纸上。
以下s行包含 大约翰的邮票描述 类似的格式;这个描述 但是,可能包含任意的 数量。以下k行 用相同的格式描述兔子 正如在描述中所使用的那样 邮票。一个代表黑色 正方形,而零 - 白色 方。
输出
对于每个测试用例写出来 标准输出单行一个 单词“YES”(不带引号) 或“否”,取决于是否 可以绘制来自测试用例的兔子 使用测试用例中的邮票 (一起)。
实施例
输入数据:
2 3 8 010 000 010 000 010 011 01100000 00100000 00010000 00001100 00011110 10111100 01111100 01111110 5 10 001 001 000 00000 10100 00001 00001 00100 0011110000 0000111000 0010011100 0111001110 1110000000 1101001000 1000001100 0110110110 0001001000 0000110000
正确的输出是:
NO YES
诀窍在于,我可以编写简单的解决方案这一事实并不意味着我可以编写硬编码。这与事实类似,在某些游戏中,在达到一定程度后,杀死弱小的敌人并不会给你任何(或非常低的数量)经验。
我不想要任何解决方案或现成的算法 - 但我可以要求一些指导方针吗?
在尝试解决此类问题(或特定问题)时,正确的思考方式是什么?
答案 0 :(得分:4)
解决问题的本质在于它结合了你现有的知识和洞察力。我不认为可以有一种“正确”的思维方式。相反,我建议你组装一系列处理问题的策略。诸如此类的事情(这些并不一定适用于这个问题,但我发现自己在解决问题时会做这些事情)
问题出现的一个有趣的事情是,如果你“玩”了他们,就会想到足够的意想不到的想法,通常是在你停止思考问题之后。
在这种情况下,我想知道,给你几张邮票,你怎么能识别出一个无法设置的像素......嗯必须依赖于白色空间的模式......看看我们正在考虑反问题 - 我们不绘制的内容。
答案 1 :(得分:1)
当我十二岁的时候,我在团队环境中学习了魔法课程。魔术师的名字叫Joe Carota。他做了一次伎俩,我脱口而出,“你是怎么做到的?”从那以后,他说了那天一直困扰着我的事情。
乔的回答,“迈克尔,如果你真的想知道这个技巧是如何完成的,你必须弄清楚你将如何自己做。”
当然,这不是我想听到的,但确实让我的注意力集中在解决问题上。从我的角度来看,解决问题不仅仅是解决问题。如果我第一次尝试解决这个问题需要十七步并且非常笨拙,那么好消息是我解决了这个问题。
然后,通过查看我开发的解决方案并寻找改进该解决方案的方法,我将学习如何简化最终结果。后来在我的计算机编程生涯中,我发现这个过程被称为“逐步细化”。
当时它仍然有效。
答案 2 :(得分:0)
接下来,我通过仅使用小印章来简化给定的kxk图片。我尝试将黑色像素从顶部和底部边框移开,并将它们合并在中间。那么你应该最终得到一行或两行包含黑色像素,这取决于小印章上黑色像素之间的距离是一个还是两个。
接下来,我在大邮票上应用了相同的简化(用小邮票简化了大邮票)。 然后你可以通过重复应用大邮票从左到右简化图片。在这些步骤之间,使用小标记确保您没有超过两行包含黑色像素。
最后,检查应该很容易......