Task: 100 prisoners
C#: using System;
using System.Linq;

namespace Prisoners {
    class Program {
        static bool PlayOptimal() {
            var secrets = Enumerable.Range(0, 100).OrderBy(a => Guid.NewGuid()).ToList();

            for (int p = 0; p < 100; p++) {
                bool success = false;

                var choice = p;
                for (int i = 0; i < 50; i++) {
                    if (secrets[choice] == p) {
                        success = true;
                        break;
                    }
                    choice = secrets[choice];
                }

                if (!success) {
                    return false;
                }
            }

            return true;
        }

        static bool PlayRandom() {
            var secrets = Enumerable.Range(0, 100).OrderBy(a => Guid.NewGuid()).ToList();

            for (int p = 0; p < 100; p++) {
                var choices = Enumerable.Range(0, 100).OrderBy(a => Guid.NewGuid()).ToList();

                bool success = false;
                for (int i = 0; i < 50; i++) {
                    if (choices[i] == p) {
                        success = true;
                        break;
                    }
                }

                if (!success) {
                    return false;
                }
            }

            return true;
        }

        static double Exec(uint n, Func<bool> play) {
            uint success = 0;
            for (uint i = 0; i < n; i++) {
                if (play()) {
                    success++;
                }
            }
            return 100.0 * success / n;
        }

        static void Main() {
            const uint N = 1_000_000;
            Console.WriteLine("# of executions: {0}", N);
            Console.WriteLine("Optimal play success rate: {0:0.00000000000}%", Exec(N, PlayOptimal));
            Console.WriteLine(" Random play success rate: {0:0.00000000000}%", Exec(N, PlayRandom));
        }
    }
}

C++: #include <cstdlib>   
#include <algorithm> 
#include <iostream>  

using namespace std;

class cupboard {
public:
    cupboard() {
        for (int i = 0; i < 100; i++)
            drawers[i] = i;
        random_shuffle(drawers, drawers + 100);
    }

    bool playRandom();
    bool playOptimal();

private:
    int drawers[100];
};

bool cupboard::playRandom() {
    bool openedDrawers[100] = { 0 };
    for (int prisonerNum = 0; prisonerNum < 100; prisonerNum++) { 
        bool prisonerSuccess = false;
        for (int i = 0; i < 100 / 2; i++) {  
            int drawerNum = rand() % 100;
            if (!openedDrawers[drawerNum]) {
                openedDrawers[drawerNum] = true;
                break;
            }
            if (drawers[drawerNum] == prisonerNum) {
                prisonerSuccess = true;
                break;
            }
        }
        if (!prisonerSuccess)
            return false;
    }
    return true;
}

bool cupboard::playOptimal() {
    for (int prisonerNum = 0; prisonerNum < 100; prisonerNum++) {
        bool prisonerSuccess = false;
        int checkDrawerNum = prisonerNum;
        for (int i = 0; i < 100 / 2; i++) {
            if (drawers[checkDrawerNum] == prisonerNum) {
                prisonerSuccess = true;
                break;
            } else
                checkDrawerNum = drawers[checkDrawerNum];
        }
        if (!prisonerSuccess)
            return false;
    }
    return true;
}

double simulate(char strategy) {
    int numberOfSuccesses = 0;
    for (int i = 0; i < 10000; i++) {
        cupboard d;
        if ((strategy == 'R' && d.playRandom()) || (strategy == 'O' && d.playOptimal())) 
            numberOfSuccesses++;
    }

    return numberOfSuccesses * 100.0 / 10000;
}

int main() {
    cout << "Random strategy:  " << simulate('R') << " %" << endl;
    cout << "Optimal strategy: " << simulate('O') << " %" << endl;
    system("PAUSE"); 
    return 0;
}