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