C语言解决魔术师发牌问题(循环链表)

魔术师手中有A、2、3……J、Q、K十三张黑桃扑克牌。在表演魔术前,魔术师已经将他们按照一定的顺序叠放好(有花色的一面朝下)。魔术表演过程为:一开始,魔术师数1,然后把最上面的那张牌翻过来,是黑桃A;然后将其放到桌面上;第二次,魔术师数1、2;将第一张牌放到这些牌的最下面,将第二张牌翻转过来,正好是黑桃2;第三次,魔术师数1、2、3;将第1、2张牌依次放到这些牌的最下面,将第三张牌翻过来正好是黑桃3……直到将所有的牌都翻出来为止。则原来牌的顺序为???

每次写的都这么慢,,不想吐槽自己了。而且还一会蒙一会清楚的,本来很清楚,一会又蒙了,本来不清楚,一会又清楚了,唉唉唉(终究还是我太菜)
#include 
#include 
#define CardNumber 13
struct card
{
    int num;
    struct card *next;
};
//创建循环链表
struct card *Createcard()
{
    struct card *head = NULL, *p = NULL;
    head = (struct card *)malloc(sizeof(struct card)); //已申请,不为空
    p = head;
    struct card *pp = NULL;
    for (int i = 1; i <= CardNumber; i++)
    {
        pp = (struct card *)malloc(sizeof(struct card));
        pp->num = 0;
        p->next = pp;
        p = pp;
    }
    pp->next = head->next; //最后一个结点的下一个执行头结点的下一个,形成环
    free(head);            //删除头结点(因为已经连起来了,且头结点本身又没有数据)
    return pp->next;
}
//定义发牌次序
void SendCard(struct card *p)
{
    int i;
    int CountNumber = 2;
    struct card *pp = NULL;
    pp = p;
    pp->num = 1; //正向第一个结点牌为1;
    while (1)
    {
        //需要间隔几个数填上
        for (i = 0; i < CountNumber; i++)
        {
            pp = pp->next;
            if (pp->num != 0) //已经放置过,且会优先于它被取出
            {
                i--; //跳过已经被取走的,即该位置有牌的话,则下一个位置
            }
        }
        //找到要填充的位置并赋值
        if (pp->num == 0)
        {
            pp->num = CountNumber;
            CountNumber++;
            if (CountNumber == 14)
            {
                break;
            }
        }
    }
}

int main()
{
    struct card *p = Createcard();
    SendCard(p);
    printf("扑克牌次序为:\n");
    for (int i = 0; i < CardNumber; i++)
    {
        printf("黑桃%d ", p->num);
        p = p->next;
    }
    return 0;
}

C语言解决魔术师发牌问题(循环链表)_第1张图片

你可能感兴趣的:(经典算法问题C/C++)