trang chủ / bài tập / multithrd

Đa luồng

Đề bài

Mô tả

Cho một chương trình đa luồng gồm N tiến trình. Tiến trình thứ i thực hiện đoạn mã giả sau:

lặp lại n_i lần
    y_i := y
    y := y_i + 1
kết thúc lặp

Ở đây y là biến dùng chung của toàn bộ chương trình, còn yi là biến cục bộ của riêng tiến trình i. Mỗi dòng lệnh là một thao tác nguyên tử: khi một tiến trình bắt đầu thực hiện một dòng thì nó luôn chạy xong dòng đó mà không bị ngắt. Ngoài ràng buộc đó ra, mọi thứ tự đan xen đều có thể xảy ra: tại mỗi bước, bất kỳ tiến trình nào còn lệnh chưa thực hiện đều có thể được chọn để chạy dòng lệnh tiếp theo của nó.

Nói cách khác, tiến trình i có đúng 2ni dòng lệnh, xen kẽ nhau: lệnh đọc (gán yi:=y) rồi lệnh ghi (gán y:=yi+1), lặp lại ni lần. Vì giá trị đọc được có thể đã cũ khi lệnh ghi xảy ra, giá trị của y có thể bị giảm đi.

Ban đầu y=0. Cho số nguyên W, hãy xác định xem có thể xảy ra trường hợp sau khi tất cả tiến trình kết thúc thì y=W hay không. Nếu có, hãy đưa ra một lịch chạy bất kỳ dẫn tới kết quả đó.

Dữ liệu vào

  • Dòng đầu chứa hai số nguyên NW.
  • Dòng thứ hai chứa N số nguyên n1,n2,,nN.

Dữ liệu ra

  • In ra Yes nếu có thể đạt được y=W, ngược lại in ra No.
  • Nếu câu trả lời là Yes, dòng thứ hai in ra một dãy số nguyên mô tả lịch chạy: số thứ k cho biết tiến trình nào thực hiện dòng lệnh tiếp theo của nó ở bước thứ k. Dãy này phải gồm đúng 2i=1Nni số, và tiến trình i phải xuất hiện đúng 2ni lần.

Nếu có nhiều lịch chạy hợp lệ, in ra lịch nào cũng được.

Ràng buộc

  • 1N100
  • 109W109
  • 1ni1000

Ví dụ

Input Output Giải thích
1 10
11
No Chỉ có một tiến trình nên không có sự đan xen nào: y luôn kết thúc bằng 11, không thể bằng 10.
2 3
4 4
Yes
2 2 1 2 2 2 2 1 2 1 1 1 1 1 1 2
Tiến trình 2 chạy một vòng (y=1), tiến trình 1 đọc y=1 rồi bị "treo". Tiến trình 2 chạy thêm hai vòng (y=3), tiến trình 1 ghi đè bằng giá trị cũ nên y=2. Tiến trình 2 đọc y=2 rồi treo, tiến trình 1 chạy nốt ba vòng, cuối cùng tiến trình 2 ghi y=3.
3 6
1 2 3
Yes
2 2 2 2 3 3 3 3 3 3 1 1
Đây là kết quả lớn nhất có thể (ni=6), đạt được khi các tiến trình chạy tuần tự, không có tiến trình nào ghi đè bằng giá trị cũ.

Bình luận

Không có bình luận tại thời điểm này.

gnatmake 12.2.0 a68g 3.1.2 nasm 2.16.1 as_x64 2.46 awk 1.3.4 gcc 16.1.0 csc 6.12.0.200 g++ 16.1.0 g++-themis 16.1.0 g++17 16.1.0 g++20 16.1.0 g++23 16.1.0 clang++ 22.1.6 dmd 2.112.0 dart 3.12.1 gforth 0.7.3 gfortran 12.2.0 go 1.26.3 groovyc 5.0.6 javac 25.0.3 node 26.2.0 kotlinc 2.3.21 sbcl 2.2.9 lua 5.4.8 nim 2.2.10 fpc 3.2.2 fpc-themis 3.2.2 perl 5.36.0 php 8.5.6 pike 8.0 pypy3 7.3.23 python3 3.14.5 racket 8.7 ruby 4.0.5 rustc 1.96.0 csc 5.3.0 ctoj-scratch 0.0.1 sed 4.9 tclsh 8.6 bun 1.3.14 deno 2.8.1 v 0.5.1 zig 0.16.0