Strange Problem

题目描述:

  古代某个狱卒某天闲着没事想和两个罪犯玩个游戏,他找了个国际象棋盘,每个格子放上一个硬币,硬币长得都一样,正反都是狱卒自己决定。

  之后他只让A罪犯观看棋盘,并随便指一个硬币告诉A罪犯,只要B罪犯能选出这个硬币就释放A和B,之后A被允许选一个硬币翻面,然后A被带走了。接着B被带过来并被要求选一个硬币,如果他选到狱卒指的那个硬币就GE,反之GG。

  A和B只能在游戏开始前进行策略交流,游戏中无法交流,在被带到棋盘前时他们也完全不知道棋盘上的硬币正反如何。

  问:那么A和B怎么做才能有最大几率被释放呢?

前几天在朋友空间看到的题目,感觉挺有意思就拿过来分享讨论一下。

然而只给出了答案并没有解释答案的思路,答案见下。

(1)首先将棋盘分成下面6种样子(每个格子里面放着一枚硬币正反随意,并且编号为下图所示):

          

(2)然后在给号的棋盘上,对应着数数 。蓝色区域内的硬币个数为奇数时得到1,为偶数时得到0。这样我们就得到了一个六位数(每一张图都可以对应得到一个数字0或者1)上面六张图的顺序是从高位到低位。(A罪犯在观察棋盘的时候要做的首要工作就是将这个六位数按照上面的方式找出来)

(3)然后狱卒随心选择一个格子(这个格子里的硬币就是B罪犯需要翻转的,但是B罪犯并不知道),但是A罪犯知道是这个格子,也知道这个格子的编号(编号从0~63 )。每个格子都有唯一对应的一个六位二进制数,因为最大为111111正好为63 ,最小值为000000正好为0。(A罪犯接下来需要做的就是把狱卒所选格子的编号转化为一个六位的二进制数)

(4)A罪犯最后要求翻转一枚硬币来帮助同伴(B罪犯)找到狱卒所指的硬币。在前面A罪犯首先得到了一个六位数,也得到了狱卒选择格子对应的六位二进制数。最关键的一步:A罪犯需要将这两个数进行异或(相同得0,不同得1),得到了第三个六位二进制数。接下来A罪犯需要将这第三个六位二进制数转为十进制数。这个十进制数就是A罪犯要翻转的格子编号。

(5)A罪犯被带走了,B罪犯被带了过来。现在B罪犯面对着棋盘需要找到狱卒之前所选的硬币,好像无从下手啊。不过A罪犯是程序员给了B罪犯提示。只要按照上面六张图所示的找到现在棋盘对应的一个六位二进制数,然后把它转化为十进制数,这个十进制数就是我要翻转的格子的编号。

给一个棋盘的界面:

0 1 2 3 4 5 6 7
8 9 10 11 12 13 14 15
16 17 18 19 20 21 22 23
24 25 26 27 28 29 30 31
32 33 34 35 36 37 38 39
40 41 42 43 44 45 46 47
48 49 50 51 52 53 54 55
56 57 58 59 60 61 62 63


参考代码:

#include <bits/stdc++.h>

using namespace std ;
int main()
{
    int a[8][8] ;
    srand(time(NULL)) ;
    memset( a , 0 ,sizeof ( a ) ) ;
    for( int i = 0 ; i < 8 ; i ++ )
    {
        for( int j = 0 ; j < 8 ; j ++ )
        {
            a[i][j] = rand()%2 ;
        }
    }
    cout<<"初始化界面为: \n"<<endl ;
    for( int i = 0 ; i < 8 ; i ++ )
    {
        for( int j = 0 ; j < 8 ; j ++ )
        {
            cout<<a[i][j]<<" " ;
        }
        cout<<endl ;
    }
    cout<<"- - - - - - - - - - - - - - - -\n"<<endl ;
    cout<<"原始六位数为: " ;
    int num[6] ;
    int bit0[6] ;
    memset( num , 0 , sizeof ( num ) ) ;
    memset( bit0 , 0 , sizeof ( bit0 ) ) ;
    int temp0[4]={ 1 , 3 , 5 , 7 } ;
    int temp1[4]={ 2 , 3 , 6 , 7 } ;
    int temp2[4]={ 4 , 5 , 6 , 7 } ;
    for( int i = 0 ; i < 4 ; i ++ )
    {
        for( int j = 0 ; j < 8 ;j ++ )
        {
            if( a[temp0[i]][j] == 0 )
                num[3]++ ;
            if( a[temp1[i]][j] == 0)
                num[4]++ ;
            if( a[temp2[i]][j] == 0)
                num[5]++ ;
            if( a[j][temp0[i]] == 0)
                num[0]++ ;
            if( a[j][temp1[i]] == 0)
                num[1]++ ;
            if( a[j][temp2[i]] == 0)
                num[2]++ ;
        }
    }
    for( int i = 0 ; i < 6 ; i ++ )
    {
        if( num[i]%2 == 0 )
            bit0[i] = 0 ;
        else
            bit0[i] = 1 ;
    }
    for( int i = 5 ; i >= 0 ; i -- )
        cout<<bit0[i];
    cout<<endl ;
    int bitnum = 0 ;
    for( int i =0 ; i < 6 ; i ++ )
    {
        int temp = bit0[i]*pow(2,i) ;
        bitnum += temp ;
    }
    cout<<"对应十进制数为: "<<bitnum<<endl<<"\n";
    int row , col ;
    row = rand() % 8 ;
    col = rand() % 8 ;
    cout<<"轮到狱卒选择 :"<<endl ;
    cout<<"所选行为 "<<row<<"  所选列为"<<col<<endl<<"\n" ;
    int choose = 7 * row + col;
    cout<<"狱卒选择的硬币编号为: "<<choose<<endl<<"\n" ;
    int c1 = bitnum^choose ;
    cout<<"A罪犯得到的原始十进制数 异或 狱卒所选硬币的编号 得到: "<<c1<<endl<<"\n" ;
    int row1 = c1/8 ;
    int col1 = c1%8 ;
    cout<<"A罪犯应给为B罪犯翻转的硬币所在位置为:";
    cout<<"行为:"<<row1<<"  列为:"<<col1<<endl<<"\n" ;
    if( a[row1][col1] == 1 )
        a[row1][col1] = 0 ;
    else
        a[row1][col1] = 1 ;
    for( int i = 0 ; i < 8 ; i ++ )
    {
        for( int j = 0 ; j < 8 ; j ++ )
        {
            cout<<a[i][j]<<" " ;
        }
        cout<<endl ;
    }
    cout<<"- - - - - - - - - - - - - - - -\n"<<endl ;
    int bit1[6] ;
    memset( bit1 , 0 , sizeof ( 6 ) ) ;
    memset( num , 0 , sizeof ( num ) ) ;
    for( int i = 0 ; i < 4 ; i ++ )
    {
        for( int j = 0 ; j < 8 ;j ++ )
        {
            if( a[temp0[i]][j] == 0 )
                num[3]++ ;
            if( a[temp1[i]][j] == 0 )
                num[4]++ ;
            if( a[temp2[i]][j] == 0 )
                num[5]++ ;
            if( a[j][temp0[i]] == 0)
                num[0]++ ;
            if( a[j][temp1[i]] == 0)
                num[1]++ ;
            if( a[j][temp2[i]] == 0)
                num[2]++ ;
        }
    }
    cout<<"B罪犯得到的六位二进制数为: " ;
    for( int i = 0 ; i < 6 ; i ++ )
    {
        if( num[i]%2 == 0 )
            bit1[i] = 0 ;
        else
            bit1[i] = 1 ;
    }
    for( int i = 5 ; i >= 0  ; i -- )
        cout<<bit1[i] ;
    cout<<endl ;
    int bitnum1 = 0 ;
    for( int i =0 ;i < 6 ; i ++ )
    {
        int temp = bit1[i] * pow ( 2 , i ) ;
        bitnum1 += temp ;
    }
    cout<<"B罪犯反转的硬币为: "<<bitnum1<<endl ;
}

GCC运行结果:

求解释该方法的思路。O(∩_∩)O~

转载请注明出处:www.cnblogs.com/zpfbuaa

时间: 2024-10-22 22:14:46

Strange Problem的相关文章

hdu 5152 A Strange Problem线段树+欧拉函数

*****************************************BC题解**********************************************************************1003 A Strange Problem 对于操作二,利用公式 当x >= Phi(C), A^x = A ^ (x%Phi(C) + Phi(C)) (mod C) 对于2333333这个模数来说,求18次欧拉函数后就变成了1,所以只需要保存19层第三次操作的加数

Python程序员糟糕的一天

Python程序员糟糕的一天!! 第一张图是上午上班前,第二张图是下午下班前,一天下来就加了一个return! 为了方便你们看懂具体(主要)的改动,我加了第三张图(上班前)和第四张图(下班前). 第一张图(因图片显示不完整而看不清楚的,请在"在新标签页中打开图片"): 第二张图: 第三张图: 第四张图: 上班前代码: #!/usr/bin/python # encoding: utf-8 # -*- coding: utf8 -*- """ Created

HDU 3496 Watch The Movie(看电影)

Time Limit: 1000MS   Memory Limit: 65536K [Description] [题目描述] New semester is coming, and DuoDuo has to go to school tomorrow. She decides to have fun tonight and will be very busy after tonight. She like watch cartoon very much. So she wants her un

Ubuntu 13.10 PHP 5.5.x mcrypt missing – Fatal Error: Undefined function mcrypt_encrypt()!

[原文]http://www.tuicool.com/articles/goto?id=myM7veR I had updgraded my Ubuntu from 13.04 to 13.10 last week and everything went quite good. The only problems that I faced as developer are: Apache 2.4 was not working with default previous installation

HDU_3496_(二维费用背包)

Watch The Movie Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Total Submission(s): 7585    Accepted Submission(s): 2427 Problem Description New semester is coming, and DuoDuo has to go to school tomorrow. She deci

HDU3496-Watch The Movie

描述: New semester is coming, and DuoDuo has to go to school tomorrow. She decides to have fun tonight and will be very busy after tonight. She like watch cartoon very much. So she wants her uncle to buy some movies and watch with her tonight. Her gran

Fix “Could Not Find This Item” When Deleting in Windows 7

If you’ve been using Windows for as long as I have, you have probably run into your share of weird error messages. One that I got recently when trying to delete a file was: Could not find this item. This is no longer located in X. Verify the item’s l

hdu 4850 Wow! Such String! 构造 欧拉回路

Wow! Such String! Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 934    Accepted Submission(s): 318 Special Judge Problem Description Recently, doge starts to get interested in a strange probl

hdu3496+poj1948(二维费用背包)

Watch The Movie Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others) Total Submission(s): 5106    Accepted Submission(s): 1614 Problem Description New semester is coming, and DuoDuo has to go to school tomorrow. She dec