【发布时间】:2015-01-15 03:31:03
【问题描述】:
我有以下任务要做:
给定一个由 m x n 个小矩形组成的矩形巧克力棒,并希望将其分成几部分。在每个步骤中,您只能选择一块并沿其任何垂直线或沿其水平线将其分解。你应该如何用最少的步数打破巧克力棒?
我知道你需要 m x n - 1 个步骤来打破巧克力棒,但我被要求用“CS 方式”来做:
定义一个谓词,该谓词在将巧克力棒分成小块的所有备选可能性中选择最少的步数。在一个额外的参数位置上构建一个结构,它告诉您在哪里以及如何打破条形以及如何处理生成的两个部分。
我的想法:在打破巧克力块一次后,你可以选择在垂直或水平线上打破它。所以这是我的代码,但它不起作用:
break_chocolate(Horizontal, Vertical, Minimum) :-
break_horizontal(Horizontal, Vertical, Min1),
break_vertical(Horizontal, Vertical, Min2),
Minimum is min(Min1, Min2).
break_horizontal(0,0,_).
break_vertical(0,0,_).
break_horizontal(0, V, Min) :-
V > 0,
break_horizontal(0, V, Min).
break_horizontal(H, V, Min) :-
H1 is H-1,
Min1 is Min + 1,
break_vertical(H1, V, Min1).
break_horizontal(H, V, Min) :-
H1 is H-1,
Min1 is Min + 1,
break_vertical(H1, V, Min).
break_vertical(H, V, Min) :-
V1 is V-1,
Min1 is Min + 1,
break_horizontal(H, V1, Min1).
break_vertical(H, V, Min) :-
V1 is V-1,
Min1 is Min + 1,
break_vertical(H, V1, Min1).
break_vertical(H, 0, Min) :-
H > 0,
break_horizontal(H, 0, Min).
谁能帮我解决这个问题?
【问题讨论】:
-
我很久以前就忘记了 Prolog,但我会在 1x2 或 1x1 巧克力棒上测试它。我首先会怀疑无限递归。
-
“...但它不起作用”还不够好。究竟会发生什么?你期望会发生什么?您是否尝试过自己调试,发现了什么?
-
正如@Boris 所指出的,对于
n x m条形图,断点数始终为mn - 1(通过归纳简单证明)。那么,你到底想让这个程序做什么呢?你能展示一个示例输出吗? -
我知道中断的次数总是 mn - 1,但我被要求为它编写一个程序。好吧,问题是 - 什么都没有发生。当我运行我的代码时,Prolog 只是冻结并且我的计算机崩溃了,所以我根本无法进行任何调试。
-
您的代码存在一些问题。首先,使用
break_horizontal(0, V, Min) :- V > 0, break_horizontal(0, V, Min).进行无限递归修复,您的程序可能会停止崩溃。其次,整体逻辑仅假设您将XbyY分成两块X-1byY和1byY,或XbyY-1和@ 987654333@ by1在很多地方。它可能会忽略一些您不只是中断一行或一列的情况。