解决"Theater Row"脑筋急转弯的代码

code to solve the "Theater Row" brain teaser

本文关键字:代码 脑筋急转弯 Row Theater 解决      更新时间:2023-10-16

我正在读一本名为《概率中的五十个挑战性问题》的书,里面充满了许多与概率相关的脑筋急转弯。我无法解决那里的一个问题,也无法理解解决方案。所以,我正在编写一个代码以获得更好的感觉。这是原始问题。

剧院街: 八个清晰的单身汉和七个漂亮的模特碰巧在剧院的同一排 15 个座位中随机购买了单人座位。平均而言,适婚夫妇有多少对相邻座位的票?

这是我的代码,从 100 个随机抽样中获取平均数量的相邻对:

#include <iostream>
#include <vector>
#include <cstdlib>
#include <algorithm>
#include <numeric>
using namespace std;
//  computes the probability for the "theater row" problem 
//  in the book fifty challenging probabilty problems.
vector<int> reduce(vector<int>& seats);    //  This function reduces a sequence to a form 
                                           //  in which there is no adjacent 0's or 1's.
                                           //  *example: reduce(111001)=101*
int main()
{
    srand(time(0));
    int total=15;
    int Num=100;
    int count0=0;   //  number of women
    int count1=0;   //  number of men
    vector<int> seats; //   vector representing a seat assignment, 
                       //   seats.size()=total
    vector<int> vpair; //   vector that has number of adjacent pairs 
                       //   as its element, size.vpair()=Num
    for (int i=0; i<Num; ++i) {
        count0=count1=0;        
        while ((count1-count0)!=1) {
                    count0=count1=0;
            seats.clear();
            for (int j=0; j<total; ++j) {
                int r=rand()%2;
                if (r==0)
                    ++count0;
                else
                    ++count1;
                seats.push_back(r);
            }
        }
        for (int k=0;k<seats.size();++k)
            cout<<seats[k];
        reduce(seats);
        for (int k=0;k<seats.size();++k)
            cout<<" "<<seats[k];
        vpair.push_back(seats.size()-1);   // seats.size()-1 is the number 
                                               // of adj pairs.
        cout<<endl;
    }
    double avg=static_cast<double>(accumulate(vpair.begin(),vpair.end(),0))/vpair.size();
    cout<<"average pairs: "<<avg<<endl;

    return 0;
}
vector<int> reduce(vector<int>& seats)  
{
    vector<int>::iterator iter = seats.begin();
    while (iter!=seats.end()) {
        if (iter+1==seats.end())
            ++iter;
        else if (*iter==*(iter+1))
            iter=seats.erase(iter);
        else
            ++iter;
    }
    return seats;
}

该代码生成 0(代表女性)和 1(男性)的随机序列。然后它"减少"随机序列,以便没有重复的 0 或 1。例如,如果代码生成一个随机的011100110010011序列(有 7 个相邻对),则该序列将减少到 01010101。在简化格式中,要计算出相邻对的数量,您只需要获得"size-1"。

这是我的问题。

  1. 这个问题的答案(根据这本书)是 7.47,而我从代码中平均得到大约 7 个左右。有人看到差异的来源吗?

  2. 我的代码有时似乎效率很低。是由于我生成随机序列的方式吗?(如您所见,要生成一个由 8 名男性和 7 名女性组成的随机序列,我一直要求一个大小为 15 的随机序列,直到它恰好有 8 名男性(或"1")和 7 名女性(或"0")。当存在这样的约束时,有没有更好的方法来生成随机序列?

在编程方面,我不是那么精通。我将不胜感激任何评论。谢谢你的帮助!!

这个问题

很搞笑。

有1307674368000种可能的组合。

有 203212800 对夫妇聚在一起的组合。

但是有两对夫妇聚在一起的3048192000组合。

认为这个问题的关键是先做一个规模较小的问题,然后使用该信息来创建你的答案。这只是一个期望值问题。

编辑:与其运行模拟,不如使用期望值获得确切的答案,必须更努力地思考,但您也会准确。我会花一点时间看看我是否可以想出确切的答案并发布它。

重要编辑(阅读):

如果你得到超过 8 个

0 或 8 个 1,你的代码是否说明。感觉你最多只能有 8 个男人和 7 个女人,那么它应该会自动感觉到剩下的符号。