Impossible escape
来源:互联网 发布:oracle数据库中文注释 编辑:程序博客网 时间:2024/06/01 21:27
一个数学问题
一个看守跟两个囚徒玩一个游戏。游戏开始前两个囚徒可以商量策略(两位囚徒均熟悉游戏流程),游戏开始后,两个囚徒再也不能相见。看守在一个8×8的棋盘摆了64个硬币,硬币有正面,有反面,是随机的。看守叫来A,明确告诉囚徒A哪一枚硬币下面藏着一张纸。而后,他要求A选择翻转棋盘中的一枚硬币。注意:这个翻转硬币是必须的,而且只能是一枚(除了翻一枚硬币以外,A不允许再有多余的动作)。之后,他让A离开。叫来B,如果B可以指出哪个硬币下藏着这张纸,A和B都可以释放,不然A和B都被绞死。
问:A和B商量哪种策略可以使得两人存活的概率最高?(其实是100%存活)
解法(解法来自知乎: 杨帆)
- 把64个格子按照0~63的顺序编好号。记第i个格子的硬币状态为ai,正面朝上记0,反面朝上记1.对于每一个棋盘的局面{ai},定义函数f({ai})=0 xor k1 xor k2 … xor km,其中aki=1,i=1…m。 即把棋盘上所有向下的硬币的坐标给异或运算,如果全朝上那就是0.
囚犯A:
- 看了任一棋盘局面{ai}后,计算出f({ai}),然后假设纸所在的位置坐标为j, 计算出的值l = j xor f({ai}),然后翻转坐标为l的硬币即可。
囚犯B:
- 直接计算新局面{ai}’对应的f({ai})’, 即为纸条的坐标j。原因:由于新局面{ai}’是局面{ai}翻转坐标为l的硬币得到的,所以显然有:f({ai})’ = f({ai}) xor l. 又有:l = j xor f({ai}),从而有由此f({ai})’ = f({ai}) xor l = f({ai})’ = f({ai}) xor j xor f({ai}) = j,B能够以100%正确率指出纸条的位置。
简单的说就是:
- A和B商量好计算正面朝上所有坐标相互异或的值还是正面朝下
- 商量好后, A计算出当前局面的值,然后翻转坐标为l的硬币
- B计算出自己当前局面的值就是正确的位置
模拟代码
测试样例:
Impossible escape_Input.txt
34U U D D D U U UU U U D D D U UD D D U U U U UD U U U U D U UD D U D U U D UU D U D U U U UU U D D D U U DU U D D D U U D50U D U U U D D UD U U U U U U UU D D U U D U DU D D D U D U UU U U D U U D DU U U U D D U DU D D U D U D UD D U D D D D U40D D U D U D D DD D D D U D D UD D D U D D D UU U U D U D U DD U U U D D D DD U U U D D D UD D U D U U D DU D D D U D U D
测试代码:
Impossible escape.cpp
#include <iostream>using namespace std;const int SIZE = 64;bool box[SIZE]; // 棋盘64格, 0表示正面朝上,1表示正面朝下int main(int argc, char const *argv[]){ char tmp; int fa, fb, l; int RightPos; freopen("Impossible escape_Input.txt", "r", stdin); while (~scanf("%d", &RightPos)) { for (int i = 0; i < SIZE; ++i) { scanf("%c", &tmp); getchar(); // 0表示正面朝上, 1 表示正面朝下 if('D' == tmp) box[i] = 1; else if('U' == tmp) box[i] = 0; } // ==================================== // 模拟囚犯A拿到局面{ai} fa = 0; for (int i = 0; i < SIZE; ++i) { if(box[i]) fa ^= i; } l = fa^RightPos; // 计算A应该翻转硬币的坐标 box[l] ^= 1; // 翻转硬币 // ==================================== // 模拟囚犯B拿到局面{ai}' fb = 0; for (int i = 0; i < SIZE; ++i) { if(box[i]) fb ^= i; } printf("%d\n", fb); // 输出B认为有纸片的目标位置 } return 0;}
生成测试样例代码:
Impossible escape_Createinput.cpp
// 用于生成测试样例// U表示硬币正面朝上, D表示硬币正面朝下#include <iostream>#include <time.h>#include <cstdlib>using namespace std;const char data[2] = {'D', 'U'};int main(int argc, char const *argv[]){ freopen("Impossible escape_Input.txt", "w", stdout); int test_num; srand(time(NULL)); scanf("%d", &test_num); for (int i = 0; i < test_num; ++i) { printf("%d\n", rand()%64); for (int i = 0; i < 8; ++i) { for (int j = 0; j < 8; ++j) { printf("%c", data[rand()%2]); if(j != 7) printf(" "); else printf("\n"); } } printf("\n"); } return 0;}
阅读全文
0 0
- Impossible escape
- escape
- escape
- escape
- Escape
- Escape
- Escape
- Impossible is nothing.
- Nothing is impossible
- Highlight with TMemo Impossible
- Nothing is impossible
- zoj 2081 Mission Impossible
- Impossible is nothing
- ML Impossible and Rescure
- impossible的真正含义
- Impossible is nothing——《The Impossible》观后感
- "Impossible" is "I’m possible"
- 如何完成一项Mission Impossible
- 利用ViewPager实现启动引导页
- JSP-隐式对象、pageContext、错误处理
- NYOJ 121 另类乘法
- 高质量c/c++编程学习之三:常量
- JSP-使用JSTL-out、set、remove、catch捕捉异常、条件判断、流程控制、字符截取
- Impossible escape
- C++浅拷贝与深拷贝(程序员面试宝典试题)
- Hadoop1.x安装:完全分布式安装
- JSP-JSTL-import、redirect、url处理、常用函数
- win32的创建窗口代码
- HDU 2018 母牛的故事(DP递推)
- 栈帧及可变参数列表
- Python 学习->四类逻辑运算符
- C++ 模拟String类增删查改