Tuyển sinh 🎓 Mình nhận đào tạo lập trình giải thuật thi đấu: thi vào lớp 10 chuyên tin · thi học sinh giỏi tin học cấp tỉnh/thành · thi vào đội tuyển quốc gia · Olympic tin học sinh viên / ICPC · phỏng vấn thuật toán. Bấm vào đây để xem thông tin khóa học → Xem khóa học

Calexp (Tin học trẻ toàn quốc 2024 – Vòng sơ khảo – Bảng B)

Calexp (Tin học trẻ toàn quốc 2024 – Vòng sơ khảo – Bảng B)
Nguồn: Tin học trẻ 2024 Độ khó: Dễ Toán Biểu thức Nhập xuất

Đề bài

Nguồn đề: Hội thi Tin học trẻ toàn quốc 2024 – Vòng sơ khảo – Bảng B (bài calexp, viết tắt của calculate expression – tính biểu thức). Đề bên dưới do mình viết lại bằng lời của mình cho dễ hiểu (giữ đúng nghĩa, đúng số liệu và ví dụ của đề gốc).

Cho biểu thức

$$A = x^2 + y^2 + x \times y.$$

Biết giá trị của hai số nguyên $x$ và $y$, em hãy tính giá trị của $A$.

Dữ liệu vào:

  • Dòng thứ nhất: số nguyên $X$ ($0 \le X \le 100$) – giá trị của $x$;
  • Dòng thứ hai: số nguyên $Y$ ($0 \le Y \le 100$) – giá trị của $y$.

Kết quả: in ra một số nguyên duy nhất là giá trị của $A$.

Giới hạn thời gian: 1 giây. Dữ liệu nhập từ bàn phím, in ra màn hình.

Ví dụ – input
1
2
Ví dụ – output
7

Giải thích: $x = 1$, $y = 2$ nên $A = 1^2 + 2^2 + 1 \times 2 = 1 + 4 + 2 = 7$.

Lời mở đầu

Đây là bài "khởi động" của đề sơ khảo Bảng B Tin học trẻ 2024: đọc hai số, thay vào công thức và in kết quả. Bài dễ nhưng vẫn có vài điểm các em mới học hay vấp: đọc dữ liệu nằm trên hai dòng, viết $x^2$ trong C++ thế nào (đừng viết x^2!), và có bị tràn số không. Mình đi lần lượt từng ý, kèm một hình vẽ nhỏ để thấy biểu thức này "trông như thế nào".

Dành cho học viên · Ưu tiênNộp bài trên hệ thống CLUE OJ

Link này chỉ học viên đã tham gia tổ chức mới vào được. Học viên nên ưu tiên nộp ở đây vì sẽ được chấm nhanh hơn.

Nộp bài trên CLUE OJ

Lộ trình lời giải, bấm vào từng phần để nhảy tới:

Bộ testBộ test có gì?

Bộ test trên CLUE do mình tự sinh theo đúng giới hạn của đề: 20 test, test 1 là ví dụ của đề. Đề không chia subtask (cả bài là một nhóm 100%).

Nhóm testTestNội dung
Ví dụ của đề1$x = 1, y = 2$, đáp án $7$
Biên2–10$x = y = 0$ (đáp án $0$), $x = y = 100$ (đáp án lớn nhất $30000$), một số bằng $0$, hai số bằng nhau, $99$ và $100$…
Ngẫu nhiên11–20$x, y$ ngẫu nhiên trong đoạn $[0, 100]$

Có 5 test có ít nhất một số bằng $0$ (test 2, 4–5, 7, 10), trong đó test 2 cả hai số đều bằng $0$. Đáp án lớn nhất là $30.000$ (test 3, $x = y = 100$).

Đã nộp thử trên bộ chấm chính thức
Lời giải bên dưới mình đã nộp lên hệ thống chấm chính thức của Hội thi (tinhoctre.vn) và được 100/100 điểm (AC).
SubtaskĐiều kiệnTestCách làm
C++
Cách làm
Python
Duy nhất (100%)$0 \le X, Y \le 100$1–2020/2020/20

Ý tưởngBiểu thức nhìn bằng hình vuông

Cách làm thì chỉ là thay số vào công thức. Nhưng có một cách nhìn rất đẹp: vẽ hình vuông cạnh $x + y$. Diện tích của nó là $(x + y)^2 = x^2 + y^2 + 2xy$ – gồm hình vuông $x \times x$, hình vuông $y \times y$ và hai hình chữ nhật $x \times y$. Biểu thức $A$ chỉ lấy một hình chữ nhật, nên

$$A = x^2 + y^2 + xy = (x + y)^2 - xy.$$

Em nhập $x, y$ nhỏ (không quá 12) rồi bấm Tiếp để đếm từng phần (mỗi ô vuông nhỏ là $1$ đơn vị diện tích):

Ví dụ nhanh:

Với ví dụ $x = 1, y = 2$: $(1 + 2)^2 - 1 \cdot 2 = 9 - 2 = 7$ – đúng như đáp án. Công thức $(x+y)^2 - xy$ chỉ là để hiểu thêm; trong code mình tính thẳng theo đề cho dễ đọc.

Lời giảiTính thẳng theo công thức – O(1)

Vài lưu ý khi viết code:

  • Bình phương: trong C++ và Python, x^2 là phép XOR bit chứ không phải lũy thừa! Hãy viết x * x. (Python có x ** 2; C++ có pow(x, 2) nhưng hàm này trả về số thực double – không nên dùng cho số nguyên.)
  • Hai dòng: cin >> x >> y đọc được cả khi hai số nằm trên hai dòng (C++ bỏ qua dấu xuống dòng). Trong Python thì mỗi lệnh input() đọc một dòng, nên gọi hai lần.
  • Tràn số: lớn nhất $A = 100^2 + 100^2 + 100 \cdot 100$ $= 30000$ – kiểu int là đủ. Mình vẫn dùng long long theo thói quen an toàn, không tốn gì cả.
C++▶ Chạy tay từng dòng codeĐọc x, y rồi tính A = x*x + y*y + x*y.
Dữ liệu mẫu:
Không gian$O(1)$
Thời gian$O(1)$

Kết quả chạy thật: Bản C++ đúng 20/20 test, chạy lâu nhất 0.003s. Bản Python đúng 20/20 test, chạy lâu nhất 0.021s.

Tổng kếtKết quả chạy thật trên bộ test

CáchNgôn ngữĐúngLâu nhất
(test đúng)
Điểm theo subtask
Tính thẳng theo công thứcC++20/200.003s100%
Python20/200.021s100%
Ghi chú của mình: thời gian là thời gian CPU đo trên máy mình (giới hạn 1 giây). Bài dễ nhưng là dịp ôn lại ba thói quen tốt: (1) viết bình phương bằng phép nhân x * x, không dùng ^; (2) luôn ước lượng giá trị lớn nhất của đáp án để chọn kiểu dữ liệu; (3) thử lại với các trường hợp biên như $x = y = 0$ và $x = y = 100$ trước khi nộp.
Rất vui khi anh em nào đã đọc đến những dòng cuối cùng này. Anh em đọc chắc cũng mỏi mắt luôn chứ 😅 vậy anh em nghĩ người viết ra hết đống ở trên còn thế nào nữa 🤪. Vậy nên đừng tiếc gì cho mình một lời bình luận hoặc chia sẻ bài viết để động viên mình nè. Chúc anh em học tốt và gặt hái nhiều thành công 😇

Nhận xét