修改了河内塔c ++

时间:2016-10-22 10:10:03

标签: c++

我的问题基本上是对此链接问题的修改Modified Tower of Hanoi

在该问题中,它假设某些光盘具有相同的尺寸。我的问题有点复杂。让我们假设那些具有相同尺寸的光盘具有不同的颜色。当您将这些光盘从a移动到c时,您必须确保光盘的顺序与开头的光盘顺序相同。我们需要找到这个问题的最小动作。

我在这里有一个例子。

modified tower of hanoi

如您所见,如果我们有1张大小为1的光盘和2张大小为2的光盘,我们至少需要移动7次。

Kenny Ostrom的Thx。首先,我知道如果底部有多个相同尺寸的板,那么你必须拿一个底板并假装它比其他底板大,即使它的尺寸相同。其次,我认为对于一组中等大小的光盘,除了底部光盘之外的每张光盘都应移动两次,因为我们试图获得正确的顺序。

然而,它似乎没有得到正确的答案。

这是我们的c ++家庭作业的问题,问题给出了:

N代表我们拥有的光盘大小,介于1到15000之间

M只是一个数字,介于1和1000000之间。

a [i]表示大小为i的光盘的编号

我需要打印出来(最少数量的动作)mod M.所以我猜想也许应该有更好的方法来计算(2 ^ n)mod M?

这是我的代码:

#include<iostream>
#include <math.h>
using namespace std;
int main()
{
    int N,M; //for an example:N=2,M=1000
    cin>>N>>M;
    int *a=new int[N+2];
    for(int i=1;i<=N;i++) cin>>a[i]; //I abandon the first element of this array
                                     // just to make it easier for after
                                     // for an example: {0,1,2}

    if(a[N]>1){      //take the bottom one as a seperate group
        a[N]=a[N]-1;
        a[N+1]=1;
    }
    int j=N+1;

    int num=0;

    for(int i=1;i<=j;i++){
        if(a[i]<=1){
            num=num+pow(2,j-i);
        }
        else{
            num=num+pow(2,j-i)*(2*(a[i]-1)+1);//for every group of discs in the middle
        }
    }
    cout<<num;
    cout<<num%M;

    return 0;
}

欢迎任何建议或指示。谢谢!

1 个答案:

答案 0 :(得分:1)

您链接到的“相同大小磁盘”解决方案的关键见解是,最佳策略始终是将相同大小的磁盘作为一个单元移动,因此您可以将相同大小的磁盘压缩到一个磁盘中,同时增加成本。相同大小的磁盘不计入塔的高度,但它们确实计算实际移动它们的成本。

但如果最终答案必须保留原始顺序,那么您的新约束是您必须移动相同大小的板数次。这是因为您先移动它们,然后依次移动它们,直到将底部移动到所有其他相同尺寸的板上。因此,它们通过移动一次(或任何奇数次)来反转,但如果你这样做两次(或任何偶数次),那么它们将再次反转,因此按照原始顺序。

然而,回顾移动相同尺寸印版的已发布解决方案,您会看到每个组总是移动2次,从顶部的2 ^(n-1),一直到2 ^ 0 at底部。但除了底部,这总是一个偶数。因此,如果底部有多个相同尺寸的印版,则必须使用一个底板并假装它比其他底板大,即使尺寸相同。

由于这是作业,我不会发布代码,但一旦弄清楚发生了什么,它应该很容易。它与您链接的答案大致有关,唯一的变化是“相同尺寸的印版”组必须移动偶数次才能处于原始堆叠顺序。