服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C/C++ - 用 C++ 的方式揭秘 2024 春晚魔术背后的秘密!

用 C++ 的方式揭秘 2024 春晚魔术背后的秘密!

2024-03-12 20:16编程猿来如此 C/C++

今天我用代码的方式,给大家揭露春晚魔术背后的秘密。仅用代码模拟整个过程,不探讨其数学原理。

聊一聊

今年春晚,屏幕前的很多观众跟随刘谦的扑克牌魔术一起见证了奇迹,同时也让全国网友都知道了“小尼的扑克牌没对上”!

用 C++ 的方式揭秘 2024 春晚魔术背后的秘密!

后来我们知道了,原来小尼两张牌是 Q 和 A。

或许这就是上天送给我们的巧合!

Q 跟 A 合在一起,世间万事皆有答案。

正如我们的生活:一半是问题、一半是答案。

用 C++ 代码模拟春晚魔术

1.概述

今天我用代码的方式,给大家揭露春晚魔术背后的秘密。

仅用代码模拟整个过程,不探讨其数学原理。

2.先看结果

(1) 抽取 4 张牌

首先要随机抽取 4 张牌,然后撕成两边,堆在一起:

用 C++ 的方式揭秘 2024 春晚魔术背后的秘密!

(2) 按名字移动牌

把名字长度数量的牌放到底部:

用 C++ 的方式揭秘 2024 春晚魔术背后的秘密!

(3) 移动开头 3 张牌

把开头的 3 张牌插入剩下牌中间:

用 C++ 的方式揭秘 2024 春晚魔术背后的秘密!

(4) 藏牌

把最上面的牌藏起来:

用 C++ 的方式揭秘 2024 春晚魔术背后的秘密!

(5) 按地区移牌

根据地区把开头对应数量的牌插入剩下牌中间:

用 C++ 的方式揭秘 2024 春晚魔术背后的秘密!

(6) 按性别扔牌

按性别扔掉开头对应数量的牌:

用 C++ 的方式揭秘 2024 春晚魔术背后的秘密!

(7) 见证奇迹的时刻

依次把开头的牌挪到末尾:

用 C++ 的方式揭秘 2024 春晚魔术背后的秘密!

(8) 好运留下来烦恼丢出去

把开头的牌挪到末尾,然后扔一张牌,直到剩下一张:

用 C++ 的方式揭秘 2024 春晚魔术背后的秘密!

(9) 结果对比

把剩下的牌和藏的牌比较:

用 C++ 的方式揭秘 2024 春晚魔术背后的秘密!

3.关键知识点

(1) std::shuffle

std::shuffle 是 C++11 中引入的一个函数,用于随机排列容器中的元素,即洗牌。

(2) std::random_device

std::random_device 是 C++11 中引入的一个随机数生成器,用于生成随机数。

std::random_device 通常用于生成种子,然后用这些种子初始化其他随机数生成器,如 std::mt19937。

(3) std::rotate

std::rotate 是 C++ 标准库中的一个算法。

该算法用于旋转容器中的元素,将指定元素移动到容器的开头,同时将其他元素按照原来的顺序移动。

4.完整代码

void print_cards(const std::vector<std::string>& deck) {
 for (auto& card : deck) {
  std::cout << card<< " ";
 }
 std::cout << std::endl;
 std::cout << std::endl;
}

int main() {
 std::vector<std::string> cards = { "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A" };

 std::cout << "初始扑克牌:" << std::endl ;
 print_cards(cards);
 
 std::random_device rd;
 std::mt19937 g(rd());
 std::shuffle(cards.begin(), cards.end(), g);

 std::cout << "洗牌:" << std::endl;
 print_cards(cards);

 
 std::vector<std::string> random_8_cards;
 for (int i = 0; i < 4; ++i) {
  const auto idx = rd() % cards.size();
  random_8_cards.push_back(cards[idx]);
  cards.erase(cards.begin() + idx);
 }

 std::cout << "随机抽取 4 张牌:" << std::endl;
 print_cards(random_8_cards);

 for( int i = 0;i < 4;++i)
 {
  random_8_cards.push_back(random_8_cards[i]);
 }
 std::cout << "把牌撕成两半后叠一块:" << std::endl;
 print_cards(random_8_cards);

 // 根据名字字数调整牌的顺序
 int name_length;
 std::cout << "请输入名字字数:";
 std::cin >> name_length;
 std::cout << "名字长度为:" << name_length << std::endl;

 std::rotate(random_8_cards.begin(), random_8_cards.begin() + name_length, random_8_cards.end());

 std::cout << "将开头 "<< name_length <<" 张牌放入底部" << std::endl;
 print_cards(random_8_cards);

 std::rotate(random_8_cards.begin(), random_8_cards.begin() + 3, random_8_cards.begin()+ std::uniform_int_distribution<>(4, static_cast<int>(random_8_cards.size()) - 2)(g));
 std::cout << "把前三张牌随机插入剩余牌中:" << std::endl;
 print_cards(random_8_cards);

 const std::string hidden_card = random_8_cards.front();
 std::cout << "把最上面的牌为:" << hidden_card << std::endl;
 random_8_cards.erase(random_8_cards.begin());

 std::cout << "把最上面的牌藏起来:" << std::endl;
 print_cards(random_8_cards);
 
 int location;
 std::cout << "请输入地区,南方人输入1,北方人输入2,无法确定输入3:";
 std::cin >> location;
 std::cout << "地区为:" << location << std::endl;

 std::rotate(random_8_cards.begin(), random_8_cards.begin() + location, random_8_cards.begin() + std::uniform_int_distribution<>(location+1, random_8_cards.size() - 2)(g));
 std::cout << "将开头 " << location << " 张牌随机插入剩余牌中" << std::endl;
 print_cards(random_8_cards);

 int gender;
 std::cout << "请输入性别,男性输入1,女性输入2:";
 std::cin >> gender;
 std::cout << "性别为:" << gender << std::endl;
 for (int i = 0; i < gender; ++i) {
  random_8_cards.erase(random_8_cards.begin());
 }
 std::cout << " 扔掉开头的 "<< gender <<" 张牌" << std::endl;
 print_cards(random_8_cards);

 const std::vector<std::string> temp = {"见","证","奇","迹","的","时","刻"};
 for (const auto& i : temp)
 {
  std::rotate(random_8_cards.begin(), random_8_cards.begin() + 1, random_8_cards.end());
  std::cout << i << std::endl;
  print_cards(random_8_cards);
 }

 while (random_8_cards.size() > 1) {
  random_8_cards.push_back(random_8_cards.front());
  random_8_cards.erase(random_8_cards.begin());
  std::cout <<  "好运留下来" << std::endl;
  print_cards(random_8_cards);

  random_8_cards.erase(random_8_cards.begin());
  std::cout << "烦恼丢出去" << std::endl;
  print_cards(random_8_cards);
 }

 std::cout << "剩余最后一张牌是:" << random_8_cards.front() << std::endl;
 std::cout << "藏起来的一张牌是:" << hidden_card << std::endl;

 return 0;
}

5.结尾

用 C++ 来实现还是很方便的,可能比用 Python 稍微多几行代码吧。

所以,你看出来小尼老师是哪一步做错了吗?

用 C++ 的方式揭秘 2024 春晚魔术背后的秘密!

其实,在这一步已经确定了,只要开头和结尾牌一样,就肯定不会错,剩下的步骤全是障眼法!

原文地址:https://mp.weixin.qq.com/s?__biz=MzUyODYzNTY5Ng==&mid=2247496509&idx=2&sn=71f8231e35b2a259b9b1c7bcdd7c4989

延伸 · 阅读

精彩推荐