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

Thư viện Widget

Đề bài

Mô tả

Ta xây dựng giao diện đồ hoạ bằng cách lồng các widget vào nhau. Mỗi widget chiếm một hình chữ nhật trên màn hình, có chiều rộng và chiều cao. Có ba loại widget:

  • Widget: một widget cơ bản với chiều rộng và chiều cao cố định.
  • HBox: một hộp chứa, xếp các widget con theo chiều ngang (từ trái sang phải).
  • VBox: một hộp chứa, xếp các widget con theo chiều dọc (từ trên xuống dưới).

HBox và VBox có thể đóng gói (pack) các widget khác vào bên trong. Một widget có thể được đóng gói nhiều lần vào cùng một hộp, khi đó nó xuất hiện nhiều lần theo đúng thứ tự được pack. Khi pack chỉ lưu liên kết tới widget, nên nếu widget con thay đổi kích thước thì hộp chứa nó cũng thay đổi theo.

Mỗi HBox và VBox có hai tham số nguyên không âm: border (viền bao quanh tất cả widget con) và spacing (khoảng cách giữa hai widget con liền kề), mặc định đều bằng 0.

Kích thước của một hộp chứa (HBox hoặc VBox) đang chứa các widget con c1,c2,,ck (k1) với chiều rộng wi và chiều cao hi được tính như sau:

  • HBox (xếp ngang):
    • Chiều rộng: (i=1kwi)+(k1)·spacing+2·border
    • Chiều cao: (maxihi)+2·border
  • VBox (xếp dọc):
    • Chiều rộng: (maxiwi)+2·border
    • Chiều cao: (i=1khi)+(k1)·spacing+2·border

Nếu một HBox hoặc VBox không chứa widget con nào thì kích thước của nó là 0×0, bất kể border và spacing.

Cho mã lệnh mô tả quá trình tạo và lồng các widget, hãy tính kích thước cuối cùng của mọi widget.

Dữ liệu vào

Dòng đầu chứa số nguyên n là số lệnh. n dòng tiếp theo, mỗi dòng là một lệnh thuộc một trong các dạng sau:

  • Widget [name]([x],[y]) — tạo widget cơ bản tên [name] có chiều rộng [x], chiều cao [y].
  • HBox [name] — tạo một HBox tên [name].
  • VBox [name] — tạo một VBox tên [name].
  • [name1].pack([name2]) — đóng gói widget [name2] vào [name1] ([name1] phải là HBox hoặc VBox).
  • [name].set_border([x]) — đặt border của [name] bằng [x] ([name] phải là HBox hoặc VBox).
  • [name].set_spacing([x]) — đặt spacing của [name] bằng [x] ([name] phải là HBox hoặc VBox).

Các từ trong một lệnh cách nhau đúng một dấu cách, không có dấu cách thừa. Tên widget gồm các chữ cái Latin thường, dài từ 1 đến 10 ký tự và đôi một khác nhau. Mọi số trong mã lệnh là số nguyên từ 0 đến 100.

Dữ liệu vào đảm bảo hợp lệ: mọi thao tác với một widget đều xảy ra sau khi widget đó đã được tạo, và không có widget nào được đóng gói vào chính nó (trực tiếp hoặc gián tiếp). Có ít nhất một widget được tạo.

Dữ liệu ra

Với mỗi widget, in ra một dòng gồm tên, chiều rộng và chiều cao của nó, cách nhau bởi dấu cách. Các dòng được sắp xếp theo thứ tự từ điển của tên widget.

Ràng buộc

  • 1n100
  • Tên widget dài từ 1 đến 10 ký tự, gồm chữ cái Latin thường.
  • Mọi số trong mã lệnh nằm trong đoạn [0,100].
  • Kết quả có thể rất lớn, cần dùng kiểu số nguyên 64-bit.

Ví dụ

Input Output Giải thích
12
Widget me(50,40)
VBox grandpa
HBox father
grandpa.pack(father)
father.pack(me)
grandpa.set_border(10)
grandpa.set_spacing(20)
Widget brother(30,60)
father.pack(brother)
Widget friend(20,60)
Widget uncle(100,20)
grandpa.pack(uncle)
brother 30 60
father 80 60
friend 20 60
grandpa 120 120
me 50 40
uncle 100 20
father là HBox chứa me (50,40) và brother (30,60): rộng 50+30=80, cao max(40,60)=60. grandpa là VBox chứa father (80,60) và uncle (100,20) với border 10, spacing 20: rộng max(80,100)+2·10=120, cao (60+20)+20+2·10=120. friend không được pack vào đâu nên giữ nguyên.
15
Widget pack(10,10)
HBox dummy
HBox x
VBox y
y.pack(dummy)
y.set_border(5)
y.set_spacing(55)
dummy.set_border(10)
dummy.set_spacing(20)
x.set_border(10)
x.set_spacing(10)
x.pack(pack)
x.pack(dummy)
x.pack(pack)
x.set_border(0)
dummy 0 0
pack 10 10
x 40 10
y 10 10
dummy là HBox rỗng nên có kích thước 0×0 dù đã đặt border/spacing. x là HBox chứa pack, dummy, pack với spacing 10, border cuối cùng đặt lại về 0: rộng (10+0+10)+2·10+0=40, cao max(10,0,10)=10. y là VBox chứa dummy (0,0) với border 5: rộng 0+2·5=10, cao 0+2·5=10.

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