thắc mắc Các bác cho em hỏi code python bài toán này với ạ

nhatlathangngu123

Senior Member
Em không học bên Tin nhưng đứa bạn nó hỏi một bài liên quan đến lập trình mà không biết câu trả lời. Đề bài là: Tung đồng xu 100 lần, tính xác suất để đồng xu ngửa liên tiếp 5 lần trong 100 lần đó. Giải bằng ngôn ngữ python ạ. Em cảm ơn ạ.
 

teeeeeeeee

Senior Member
Em không học bên Tin nhưng đứa bạn nó hỏi một bài liên quan đến lập trình mà không biết câu trả lời. Đề bài là: Tung đồng xu 100 lần, tính xác suất để đồng xu ngửa liên tiếp 5 lần trong 100 lần đó. Giải bằng ngôn ngữ python ạ. Em cảm ơn ạ.
Cái này là công thức xác suất bth chứ cần gì code đâu nhỉ
OG0lsXv.png
 

Ayemdi

Senior Member
Theo em tìm hiểu thì bài này có phần giống 1 bài đã từng được up lên voz, là bài này: https://vozforum.org/threads/nho-giup-do-can-giup-1-bai-xac-suat.249679
Trong đó có bác @BiBanXCaiNick có lời giải đúng và code bằng python nhưng em lại không tìm được code nữa. Bác nào giúp em em xin hậu tạ 100k ạ vì em không biết tý gì về code ạ. View attachment 1203435
Haha, tôi nghĩ ông @BiBanXCaiNick chạy hàm tung coin 10tr lần để tìm xác suất xảy ra chứ không theo công thức gì đâu.
 

Violet_7

Senior Member
Em không học bên Tin nhưng đứa bạn nó hỏi một bài liên quan đến lập trình mà không biết câu trả lời. Đề bài là: Tung đồng xu 100 lần, tính xác suất để đồng xu ngửa liên tiếp 5 lần trong 100 lần đó. Giải bằng ngôn ngữ python ạ. Em cảm ơn ạ.
Solution backtracking:
1654959907586.png

ứng trước 50k thì làm tiếp solution quy hoạch động 8-)8-)
 

Kurisu Makise

Senior Member
Chạy lệnh random rồi tích lũy khi nào vào 1 được >= 5 thì tăng giá trị trả về lên 1. Nếu vào 0 thì reset biến tích lũy á.
 

jupyter

Senior Member
thì công thức thôi, xác xuất đồng xu ngửa là 0.5, 5 lần liên tiếp là 0.5 ^ 5
print(0.5 ** 5)
sai bét
đó là bài tung đồng xu 5 lần và xác suất cả 5 lần đều mặt ngửa
bài này phức tạp hơn rất nhiều
 

turky mark

Senior Member
thế đưa về bài chỉnh hợp lặp đc ko các phen, xem như trạng thái xấp ngửa của đồng xu là 0,1 thì bài toán sẽ là tạo chỉnh hợp lặp của dãy dài 100 với 2 phần tử, trong quá trình tạo thì kiểm tra xem những case nào có 1 liên tiếp nhau lớn hơn hoặc bằng 5 , rồi từ đó tìm xác xuất đc ko nhỉ
 

jupyter

Senior Member
thế đưa về bài chỉnh hợp lặp đc ko các phen, xem như trạng thái xấp ngửa của đồng xu là 0,1 thì bài toán sẽ là tạo chỉnh hợp lặp của dãy dài 100 với 2 phần tử, trong quá trình tạo thì kiểm tra xem những case nào có 1 liên tiếp nhau lớn hơn hoặc bằng 5 , rồi từ đó tìm xác xuất đc ko nhỉ
thì bản chất là thế mà
chắc làm khoảng 10000 lần là dc
bài này giải tay mới vui
 

God Emperor Leto

Senior Member
cho cái code

lặp 100k lần mất 1-2 giây, nó ra từ 80.5 tới 81% gì đấy

Python:
import random

def sim(total, consecutive, repeat):
    def sim1(total, consecutive):
        bits = random.getrandbits(total)
        heads = 0
        for _ in range(total):
            if bits & 1:
                heads += 1
                if heads == consecutive: return 1
            else: heads = 0
            bits >>= 1
        return 0
    return float(sum(sim1(total, consecutive) for _ in range(repeat))) / repeat

print(sim(100, 5, 100000))

Code C++ lẹ gấp 30 lần, simulate 10tr lần trong tầm 5 giây
C++:
#include <iostream>
#include <random>
#include <cstdint>
#include <limits>
#include <limits.h> // for CHAR_BIT

template <class URBG = std::mt19937, class UIntType = std::uint32_t>
struct Coin {
    bool toss() {
        if (!bitCount) {
            cache = std::uniform_int_distribution<UIntType>{
                std::numeric_limits<UIntType>::min(),
                std::numeric_limits<UIntType>::max()}(gen);
            bitCount = sizeof(UIntType) * CHAR_BIT;
        }
        bool res = cache & 1;
        cache >>= 1;
        --bitCount;
        return res;
    }
    URBG gen{std::random_device{}()};
    UIntType cache = 0;
    size_t bitCount = 0;
};

double sim(int total, int consec, int repeat) {
    auto sim1 = [coin = Coin<>{}](int total, int consec) mutable {
        for (int heads = 0; total--;)
            if (coin.toss()) heads = 0; else if (++heads == consec) return 1;
        return 0;
    };
    int cnt = 0;
    for (int i = 0; i < repeat; ++i) cnt += sim1(total, consec);
    return static_cast<double>(cnt) / repeat;
}

int main() {
    std::cout << sim(100, 5, 10'000'000) * 100 << "%\n";
}
 
Last edited:
Top