我的问题基本上是对此链接问题的修改Modified Tower of Hanoi
在该问题中,它假设某些光盘具有相同的尺寸。我的问题有点复杂。让我们假设那些具有相同尺寸的光盘具有不同的颜色。当您将这些光盘从a移动到c时,您必须确保光盘的顺序与开头的光盘顺序相同。我们需要找到这个问题的最小动作。
我在这里有一个例子。
如您所见,如果我们有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;
}
欢迎任何建议或指示。谢谢!
答案 0 :(得分:1)
您链接到的“相同大小磁盘”解决方案的关键见解是,最佳策略始终是将相同大小的磁盘作为一个单元移动,因此您可以将相同大小的磁盘压缩到一个磁盘中,同时增加成本。相同大小的磁盘不计入塔的高度,但它们确实计算实际移动它们的成本。
但如果最终答案必须保留原始顺序,那么您的新约束是您必须移动相同大小的板数次。这是因为您先移动它们,然后依次移动它们,直到将底部移动到所有其他相同尺寸的板上。因此,它们通过移动一次(或任何奇数次)来反转,但如果你这样做两次(或任何偶数次),那么它们将再次反转,因此按照原始顺序。
然而,回顾移动相同尺寸印版的已发布解决方案,您会看到每个组总是移动2次,从顶部的2 ^(n-1),一直到2 ^ 0 at底部。但除了底部,这总是一个偶数。因此,如果底部有多个相同尺寸的印版,则必须使用一个底板并假装它比其他底板大,即使尺寸相同。
由于这是作业,我不会发布代码,但一旦弄清楚发生了什么,它应该很容易。它与您链接的答案大致有关,唯一的变化是“相同尺寸的印版”组必须移动偶数次才能处于原始堆叠顺序。