【算法】约瑟夫逆问题--魔术师猜牌

题目已经将魔术师出牌的过程描述清楚,我们可以利用倒推的方法,很容易地推出原来牌的排列顺序。人工倒推的方法是:在桌子上放13个空盒子排成一圈,从1开始顺序编号,将黑桃A放入1号盒子中,从下一个空盒子开始对空的盒子计数,当数到第二个空盒子时,将黑桃2放入空盒子中,然后再从下一个空盒子开始对空盒子计数,顺序放入3,4,5…,直到放入全部13张牌。注意在计数时要跳过非空的盒子,只对空盒子计数。

最后牌在盒子中的顺序,就是魔术师手中原来牌的顺序。

#include <iostream>
#include <iomanip>
using namespace std;
void main()
{
    int i,j,a[13],n;
    cout<<"这副牌的排列方式为:";
    j=0;                //13个空盒的下标。
    for(i=0;i<13;i++)
        a[i]=14;            //14代表盒子为空。
    for(i=0;i<13;i++)
    {
        n=0;            //第一个空盒子计为0号盒子。
        while(n<=i)
        {
            if(j>12)
                j=0;     //盒子的编号,当大于12时,j重置为第一个盒子的编号0。
            if(a[j]!=14)      //判断盒子是否为空,若不为空,跳过。
                j++;
            else
            {
                if(n==i)     //当从第一个空盒开始数,数到的空盒数等于牌的编号时,将牌放入。
                    a[j]=i;
                n++;       //若不相同,向后数一个盒子
                j++;       //盒子下标同时+1
            }
        }
    }
    for(i=0;i<13;i++)
    {
        a[i]+=1;       //应为之前给牌赋的值为0-12,所以依次+1后输出
        cout<<setw(3)<<a[i];      
    }
    cout<<endl;
}

猜你喜欢

转载自www.cnblogs.com/paprikatree/p/10515288.html