Algorithm 翻转卡片组的最小步骤数

Algorithm 翻转卡片组的最小步骤数,algorithm,logic,Algorithm,Logic,这是一个竞赛问题,不是家庭作业 如果N卡面朝下,则必须将所有N卡面朝上翻转。如果你翻动第i张牌,i-1,i,i+1将翻动。 例如:如果N=3,则最小步数为1 给定N张卡片,我们必须计算翻转所有卡片的最小步骤数 起初我认为这是一种斐波那契,让N=2,3,4和最小步长Min=1,1,4,但如果N=6,那么最小步长将是2。我很惊讶,有谁能帮忙吗?N=1、2和3的情况很简单 对于N=3k,这很容易。只需从第二张开始翻转k卡 对于N=3k+1,首先翻转两端的两张卡,翻转超过4张卡。然后我们剩下3k-3张牌

这是一个竞赛问题,不是家庭作业

如果
N
卡面朝下,则必须将所有
N
卡面朝上翻转。如果你翻动第i张牌,i-1,i,i+1将翻动。 例如:如果N=3,则最小步数为1
给定N张卡片,我们必须计算翻转所有卡片的最小步骤数


起初我认为这是一种斐波那契,让
N=2,3,4
和最小步长
Min=1,1,4
,但如果
N=6
,那么最小步长将是2。我很惊讶,有谁能帮忙吗?

N=1、2和3的情况很简单

对于N=3k,这很容易。只需从第二张开始翻转k卡

对于N=3k+1,首先翻转两端的两张卡,翻转超过4张卡。然后我们剩下3k-3张牌,可以被3整除,在k-1移动中很容易翻转


对于N=3k+2,首先选择第一张卡,这将翻转两张卡。现在你还有3k张牌要翻转,这很容易用k个翻转来完成。

我给出了一个非常类似的问题的答案。乍一看,这个问题似乎有点不同,但完全一样。所以我的答案,用C代码,是:

int min_steps(n){
    return (n / 3) + (n % 3 > 0); // So it's n/3 with multiples of 3
                                  // n/3 + 1 otherwise
}
编辑:如评论所述,它可以进一步缩减为:

    return (n + 2) / 3;

我已经采纳了伊瓜罗的意见,不再需要轮换。这个公式给出了N张牌作为一个整数的最小圈数。

我得到了一个满分的正确答案。以下是解决方案:-

if( n==1 || n ==2) return 1
else if( n%3 == 0) return n/3
else  return n
只需将这些组合一直运行到n=7或8,您就会知道它。这里的诀窍是把3组翻过来——用一种艰难的方式解决了它,并用了一些数学归纳法


注意:-我尝试了上面提到的其他解决方案,结果证明是错误的

你把牌翻三翻三,你需要知道你要翻几次?邪恶的孪生兄弟:两人都没有接受答案,但可能有用。看起来这个解决方案可以用
N/3+(N%3?1:0)
@higuaro来计算,我就是这么想的too@higuaro:所以,
(n+2)/3
,然后呢?我无法获得3K+1。两次初始翻转+k-1=k+1@Eduardo利昂:在N=3K+1的情况下,翻转最后两张牌,意味着第一张和最后一张牌都应该翻转,但是如果你翻转最后一张牌,那么第一张牌也会再次翻转。我的错误是,忘记添加另一个contion,如果你翻转第N张牌,那么,N-1,N,1将被翻转。@vignesh:“如果你翻转第n张牌,那么n-1,n,1将被翻转”-->你从来没有提到过!所以,
(n+2)/3
,然后呢?
(5+2)/3=7/3=2
很漂亮,我甚至不知道我之前的评论是怎么想的xd,但它不是
(n+2)
而不是
(n+3)
?呃,是的,对不起,我粗心了。@Emiliano Sorbello:是的,我理解你的解决方案。但我可以知道它是如何工作的吗?例如,如果N为4,则最小无步数为2。如何将4张牌完全翻转?你能解释一下吗?你完全正确。(n+2)/3或n/3+(n%3?1:0)将不起作用。
if( n==1 || n ==2) return 1
else if( n%3 == 0) return n/3
else  return n