如何解决C 程序重新排列检查器
我想看看我是否可以将这个称为将跳棋移动到 C 程序中的数学谜题编码。假设我们有 4 个空位和 6 个黑白交替的棋子 比如这个 0,b,w,w
现在您只能成对移动跳棋。一次 2 个,将它们滑动到空位,您不能打扰它们的秩序。这本书展示了这通过 3 个步骤完成,如下所示。
0,w 开始
0,w 第一遍
0,0 秒传
w,0 第三遍
我研究过诸如归并排序和冒泡排序之类的算法。但它们似乎并不适合我编写代码来解决这个问题。
我想把它放到一个数组中。从 4-9 运行 for 循环,因为它们不是空的。比较左右,然后有逻辑来移动它。但是我对如何在 C 代码中实现这一点感到困惑。 for 循环和比较不是问题。这是移动它们的逻辑,直到我在开始时得到三个白色碎片。
解决方法
一个评论是对的,没有通用的排序算法,稍后你会看到问题是缺少严格的顺序。 所以让我们尝试从头开始设计一个。这个答案并不完整,只是关于如何解决此类问题的想法。
由于您的代码片段是已知方法的实现,因此它不会有太大帮助。
那么让我们开始吧:
您的第一种方法不应该介意运行时的复杂性,而是要获得正确的对象。我们试图概括。
已经有人评论说双元素交换是关键。
所以有 9(n) 个元素使它成为 n-1 对。这些是您拥有的字母表的有序对。
这些是00 0w 0b w0 ww wb b0 bw bb
,
给他们起新名字可能会有所帮助,比如
A B C D E F G H I
数学上它们与第二个版本的一些限制相同:
A 只能跟在 B 和 C 之后,依此类推。
您可以只编写两种方法来翻译它们。交换和检查的所有操作都将在此版本上完成。
这里是缺少订单的问题:就像没有答案,例如,哪个更大/更小D 和 G 并且对于排序算法的问题没有任何价值。也许以后会有。
交换:一个必须是 A=00
,另一个必须与它相差 1 个以上的索引。这使得很容易识别交换指数的一侧(最多 2 个元素)(或在均衡配电层 (n/3))
交换后,邻居元素会改变它们的值!
我们想去的地方:我们需要某个序列 www
意味着一个必须是 E 和一个额外的 w,所以我们需要寻找 BE,ED,EF,HE
,广义BE..E,E..ED,E..EF,HE..E
对于核心算法:一次思考一步,这意味着有些递归。从中我们可以检查机会树*。当不再有 A
时(没有地方可以交换),我们处于死胡同,所以我们停止递归,或者我们找到了一个解决方案 www
,如果我们只寻找一个解决方案,否则将路径附加在该树到解决方案列表,直到你有足够的。
因此迭代所有 A
,然后将剩余的索引与它相距一个索引。
每个迭代将有参数交换索引 A (a)、另一个交换索引 (i) 和你的数组 T
通常,您现在会在递归树中寻找模式和机会:
第一:交换永远不会破坏A,所以总会有机会继续,但是:新的交换对不能是旧的(它只会回到树中)。遍历不会结束(因为总是有一个 A),所以没有直接的递归调用或至少是递归深度的破坏条件。可以通过必须检查的树创建一个任务列表,每个元素包含 (a,i,T)
或序列 [(a0,i0),...,(an,in)]
并且您的递归调用被替换为将此元素附加到列表中。
第二:不断变化的邻居中的模式:如果想要创建 E
,有很多方法可以实现(只需检查哪些方法组合到 ww
)这些是交换的主要候选者,并且它们离得越近,就越应该受到青睐。由于这些方式是有限的,它们偶尔会重复一次。有了这种模式,交换的选项就会大大减少。然后,这些模式也可以替换为新字母表的序列。因此,您会寻找三元组,例如“BAH”和“CDC”,它们在交换内部字母时会更改为新的三元组。可以制表,然后可以对这张表进行评分、排序,检查时需要应用此顺序。
既然您直接询问如何处理此类问题的数学或算法方法,这应该是一种看待事物的方式。一般来说:花时间给你的结构命名。或者说到编程,我想是 Stroustrup 曾经说过:如果你能考虑一下,就让它成为一个类!
*给所有喜欢评论的人:bruteforce...指数复杂度 yadda yadda,我完全意识到这一点,这是设计步骤!
,这是我目前为止的代码。 while 循环不再输出任何内容
#include<stdio.h>
int main ()
{
char checkers[10] = {0,'b','w','w'};
int a,temp1,temp2,cntr;
cntr = 1;
int i;
//check each value right and left adjacent
printf("%d a position",a);
while(!(checkers[0] == 'w') && !(checkers[1] == 'w') && !(checkers[2] == 'w'))
{
for(a=4;a>9;a++){
// if 3 white in a row followed by 3 black in a row done and exit
printf("%d a position\n",a);
if(checkers[0] == 'w' && checkers[1] == 'w' && checkers[2] == 'w' && checkers[3] == 'b' && checkers[4] == 'b' && checkers[5] == 'b')
{
printf("workd");
for(i=0;i<(sizeof(checkers)/sizeof (checkers[0]));i++)
{
printf("Checkers have finished being moved result is:%c",checkers[i]);
break;
}
}
//once w and b found move it to empty space 2 and 3
if(checkers[a-1] == 'b' && checkers[a+1] == 'b')
{
//check if 2-3 position is empty
if(checkers[1] == 0 && checkers[2] == 0)
{
temp1 = checkers[a];
temp2 = checkers[a+1];
checkers[cntr] = temp1;
checkers[cntr+1] = temp2;
break;
}
}
// looking for b followed by w,checking if 6 and 7th spot is empty
// then moving it into that spot
if(checkers[a-1] == 'w' && checkers[a+1] == 'w' && checkers[2] == 'b' && checkers[5] && checkers[6] == 0)
{
temp1 = checkers[a];
temp2 = checkers[a+1];
checkers[5] = temp1;
checkers[6] = temp2;
// move 2 and 3 down one
temp1 = checkers[1];
temp2 = checkers[2];
checkers[2+1] = temp1;
checkers[1+1] = temp2;
// finally move two whites to the front
temp1 = checkers[8];
temp2 = checkers[9];
checkers[0] = temp1;
checkers[1] = temp2;
break;
}
}
}
}
/*
just shows what swapping looks like
{0,b,w,w};
{0,0};
{0,0};
*/
我正在做大量的搬家工作,最终应该可以正确放置。令我难以理解的是,可能有一些数学方法和算法可以解决此类问题。所以想知道它如何在代码中工作。我的代码是根据我已经想出来的东西来安排它的,以使其匹配。如果开始时空格的数量发生变化或添加了更多碎片怎么办?我研究了堆排列排序和冒泡排序,但它在示例中一次显示一个项目。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。