春晚刘谦魔术实现(详细解析)

2024春晚刘谦表演了一个魔术,我们回顾一下魔术的全过程:    

        首先打乱四张牌,将四张牌对半分开把其中一半放在另一半下面,然后根据你名字长放对应的牌数到牌底,然后最上面三张牌插在剩下牌中间,可以任意(这里以剩下牌排序,第一张牌后面就输入1,以此类推),然后第一张牌就是我们要和最后牌比对的牌,之后以剩下牌继续,根据你是南方北方或者什么人来输入对应数字,那对应的牌数放在剩下的牌中间,数字输入和上面一样,然后根据男女扔掉几张牌,然后上方牌放最下面重复7次,最后一步,最上面牌往下放一张再丢一张,以此重复,最后那张就和之前那张对应。

        那么根据其表达的意思有三个核心的函数,然后就是编程语言连接:

第一个函数是:这个函数就是将前面的几个数字插入剩余数字的中间,

例如 1 2 3   4 5 6 7,把1 2 3插入 4 5 6 7中,其中4 5 6 7序号是 1 2 3 4,那么提前输入3,就插入序号为3的4的后面,变成  4 5 6 1 2 3 7,可以看成,1 2 3 先和4换变成4 1 2 3 5 6 7,然后1 2 3再和5换变成 4 5 1 2 3 6 7,然后继续变成 4 5 6 1 2 3 7。显然,两个循环可以完成这个过程,第一循环表示第二个循环次数,第二个循环完成一次数组与数字的交换(123 和x)。每次第二个函数的不同就是起点不一样,所以要加begain指示从哪开始。

void func_back(int* arr, int len, int begain, int end) {
    int sorts = end - len; //
(sorts表示下面循环的次数)
    for (int y = 0; y < sorts; y++) {
        for (int x = len - 1; x >= 0; x--) {
            *(arr + x + begain) = *(arr + x + begain) ^ *(arr + x + 1 + begain);                                                      //
(这里的三行就是两个值交换,我换了一个方法而已)
            *(arr + x + 1 + begain) = *(arr + x + begain) ^ *(arr + x + 1 + begain);
            *(arr + x + begain) = *(arr + x + begain) ^ *(arr + x + 1 + begain);
        }
        begain++;
    }
}

第二个函数是:

void print(int* arr, int len) {
    for (int x = 0; x < len; x++) {
        printf("%d ", *(arr + x));
    }
    printf("\n");
}

这个就是简单的数组打印,但是为了让玩家看清过程,如果大家不想看到可以把下面代码适当调整一下

第三个函数是:

void number_back(int* arr, int arr_len, int num) {
    for (int y = 0; y < num; y++) {
        int p = *arr;
        for (int x = 0; x < arr_len - 1; x++) {
            *(arr + x) = *(arr + x + 1);
        }
        *(arr + arr_len - 1) = p;
    }
}

这个函数是将第一个数字放到最后面去,num表示这个动作持续几次。先将第一个数字用临时变量存着,然后后面以此向前再将零时变量放到最后即可。

下面是整个魔术过程,我用几个Sleep延后打印时间,让玩家更好看清数组变化。

#define  _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<windows.h>
void func_back(int* arr, int len, int begain, int end) {
    int sorts = end - len;
    for (int y = 0; y < sorts; y++) {
        for (int x = len - 1; x >= 0; x--) {
            *(arr + x + begain) = *(arr + x + begain) ^ *(arr + x + 1 + begain);
            *(arr + x + 1 + begain) = *(arr + x + begain) ^ *(arr + x + 1 + begain);
            *(arr + x + begain) = *(arr + x + begain) ^ *(arr + x + 1 + begain);
        }
        begain++;
    }
}

void print(int* arr, int len) {
    for (int x = 0; x < len; x++) {
        printf("%d ", *(arr + x));
    }
    printf("\n");
}

void number_back(int* arr, int arr_len, int num) {
    for (int y = 0; y < num; y++) {
        int p = *arr;
        for (int x = 0; x < arr_len - 1; x++) {
            *(arr + x) = *(arr + x + 1);
        }
        *(arr + arr_len - 1) = p;
    }
}

int main() {

    printf("复原2024于谦魔术\n首先请输入你要的四张扑克牌(为了方便只要数字的)\n");
    int arr[8] = { 0 };
    for (int x = 0; x < 4; x++) {
        scanf("%d", arr + x);
        *(arr + x + 4) = *(arr + x);
    }

    printf("你的扑克牌数字是:");
    print(arr, 4);
    printf("现在你要将其折半撕成两半,最后变成:");
    print(arr, 8);

    printf("现在要输入你名字的长度\n");
    int name_len = 0;
    scanf("%d", &name_len);
    printf("根据魔术将会根据名字长度向后放几张牌,处理牌的结果:\n");
    Sleep(5000);
    for (int x = 0; x < name_len; x++) {
        number_back(arr, 8, 1);
        print(arr, 8);
        Sleep(3000);
    }

    printf("现在根据魔术会将前面三张放在剩下卡片中间,请输入要插入的地方(剩下数字排序第几个数字后面就输入几)\n");
    int the = 0;
    scanf("%d", &the);
    func_back(arr, 3, 0, the + 3);

    printf("整理完后牌的位置\n");
    print(arr, 8);
    Sleep(3000);
    printf("\n");
    printf("此时%d就是最终要拼接的牌,请记好\n", *arr);
    printf("\n");
    Sleep(4000);
    number_back(arr, 8, 1);
    printf("你的牌变为:\n");
    print(arr, 7);

    int the_2 = 0;
    printf("接下来如果你是南方人输入1,北方则2,不知道就是3\n");
    scanf("%d", &the_2);
    printf("根据魔术要求和你选的哪方人对应数字的牌数,将会拿出几张前面的牌,放到后面的牌中,请输入放在哪(和上面一样)\n");
    int the_3 = 0;
    scanf("%d", &the_3);
    func_back(arr, the_2, 0, the_3);
    print(arr, 7);

    printf("继续根据魔术要求,如果你是男生输入1,女生输入2,将会根据数字扔掉前面的牌\n");
    int the_4;
    scanf("%d", &the_4);
    number_back(arr, 8, the_4);
    printf("丢掉后牌为:\n");
    print(arr, 7 - the_4);

    printf("根据魔术要求,要将最上方牌放在最下面重复7次,过程为:\n");
    for (int x = 0; x < 7; x++) {
        number_back(arr, 7 - the_4, 1);
        printf("第%d次牌为:", x + 1);
        print(arr, 7 - the_4);
        Sleep(1000);
    }
    int len = 7 - the_4;
    Sleep(3000);
    printf("最后一步,好运留下来(第一张牌放最后),烦恼丢出去(第一张牌丢掉)\n");
    Sleep(3000);
    while (len != 1) {
        number_back(arr, len, 1);
        printf("好运留下来\n");
        print(arr, len);
        Sleep(1500);
        number_back(arr, len, 1);
        len--;
        printf("烦恼丢出去\n");
        print(arr, len, 1);
        Sleep(1500);
    }
    printf("最后的牌:%d", *arr);
    return 0;
}

下面是举例

求求各位点点赞,就当是春节祝福吧  QWQ

  • 72
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值