NHẬP XUẤT DỮ LIỆU TRONG C++
Chào các bạn học sinh và lập trình viên! Khi mới bắt đầu hành trình chinh phục lập trình thi đấu trên Sen Code Online Judge!, bài học đầu tiên và quan trọng nhất chính là hiểu cách viết một chương trình C++ hoàn chỉnh và cách nhập dữ liệu từ bàn phím (Input), xử lý nó, rồi in kết quả ra màn hình (Output).
Bài viết này sẽ hướng dẫn chi tiết từ cấu trúc mã nguồn cơ bản, cách dùng biến, hằng, các phép toán cho đến các câu lệnh nhập xuất tối ưu.
1. Cấu trúc một chương trình C++ đơn giản
Mỗi chương trình C++ đều có một bộ khung cố định. Dưới đây là chương trình đơn giản nhất in ra dòng chữ "Hello, Sen Code Online Judge!".
#include <bits/stdc++.h> // (1) Khai báo thư viện gộp (chứa toàn bộ thư viện chuẩn)
using namespace std; // (2) Sử dụng không gian tên chuẩn std
int main() { // (3) Hàm chính của chương trình, nơi bắt đầu thực thi
cout << "Hello, Sen Code Online Judge!" << "\n"; // (4) In ra màn hình và xuống dòng
return 0; // (5) Trả về trạng thái hoạt động bình thường cho hệ điều hành
}
Giải thích chi tiết:
(1) #include <bits/stdc++.h>: Đây là dòng khai báo sử dụng thư viện gộp đặc biệt trong C++. Thay vì phải nhớ và khai báo từng thư viện riêng lẻ như<iostream>,<string>,<vector>,<cmath>,<algorithm>..., thư viện<bits/stdc++.h>sẽ tự động nạp toàn bộ thư viện chuẩn của C++. Việc này giúp học sinh tiết kiệm thời gian gõ code, rất tiện lợi khi đi thi Lập trình thi đấu.(2) using namespace std;: Khai báo sử dụng không gian tên chuẩnstdđể tránh việc phải viết tiền tốstd::trước mỗi lệnh (ví dụ viếtcoutthay vìstd::cout).(3) int main() { ... }: Đây là Hàm chính của mọi chương trình C++. Khi chạy chương trình, máy tính sẽ luôn tìm đến hàmmainnày để thực thi các câu lệnh bên trong cặp ngoặc nhọn{}trước tiên.(4) cout << "Hello, Sen Code Online Judge!" << "\n";: Lệnhcout(Character Output) kết hợp với toán tử chèn luồng<<để hiển thị văn bản ra màn hình. Ký tự\ndùng để xuống dòng (nhanh hơn lệnhendl).(5) return 0;: Kết thúc hàmmainvà báo cho hệ thống biết chương trình đã chạy thành công tốt đẹp không có lỗi.
2. Khai báo biến (Variable Declaration)
Biến là gì?
Biến là một vùng trong bộ nhớ RAM được đặt tên, dùng để lưu trữ dữ liệu trong quá trình chương trình hoạt động. Giá trị lưu trữ trong biến có thể thay đổi được trong suốt thời gian chạy.
Cú pháp khai báo biến:
kiểu_dữ_liệu tên_biến;
kiểu_dữ_liệu tên_biến_1, tên_biến_2, ...;
kiểu_dữ_liệu tên_biến = giá_trị_khởi_tạo; // Khai báo kết hợp khởi tạo giá trị
Ví dụ minh họa:
#include <bits/stdc++.h>
using namespace std;
int main() {
int chieuDai; // Khai báo biến tên là chieuDai thuộc kiểu số nguyên
chieuDai = 15; // Gán giá trị 15 cho biến chieuDai
int chieuRong = 10; // Khai báo và gán luôn giá trị 10 ban đầu
int chuVi, dienTich; // Khai báo nhiều biến cùng kiểu số nguyên trên một dòng
chuVi = (chieuDai + chieuRong) * 2;
cout << "Chu vi hinh chu nhat: " << chuVi << "\n";
return 0;
}
3. Khai báo hằng (Constant Declaration)
Hằng số là gì?
Hằng số là một giá trị đặc biệt không bao giờ thay đổi trong suốt quá trình chạy chương trình. Việc đặt tên hằng giúp mã nguồn rõ ràng, dễ bảo trì hơn (ví dụ đặt hằng số Pi = 3.14).
Cú pháp khai báo hằng:
Trong C++, ta sử dụng từ khóa const đặt trước kiểu dữ liệu khi khai báo:
const kiểu_dữ_liệu TÊN_HẰNG = giá_trị;
(Quy ước: Nên đặt tên hằng số bằng chữ HOA để dễ phân biệt với biến).
Ví dụ minh họa:
#include <bits/stdc++.h>
using namespace std;
int main() {
const double PI = 3.14159; // Khai báo hằng số PI thuộc kiểu số thực double
// PI = 3.15; // Dòng này nếu mở ra sẽ bị LỖI BIÊN DỊCH vì hằng số không thể gán lại giá trị!
double banKinh = 5.0;
double chuVi = 2 * PI * banKinh;
cout << "Chu vi hinh tron: " << chuVi << "\n";
return 0;
}
4. Kiểu dữ liệu trong C++ (Data Types)
C++ cung cấp nhiều kiểu dữ liệu khác nhau để tối ưu hóa bộ nhớ RAM. Dưới đây là các kiểu dữ liệu thông dụng nhất mà các bạn bắt buộc phải ghi nhớ:
| Kiểu dữ liệu | Ý nghĩa | Kích thước | Phạm vi biểu diễn / Giới hạn |
|---|---|---|---|
int |
Số nguyên | 4 bytes | Khoảng từ -2 * 109 đến 2 * 109 (Tiêu chuẩn). |
long long |
Số nguyên lớn | 8 bytes | Khoảng từ -9 * 1018 đến 9 * 1018. |
float |
Số thực (đơn) | 4 bytes | Độ chính xác khoảng 7 chữ số thập phân. |
double |
Số thực (kép) | 8 bytes | Độ chính xác khoảng 15 chữ số thập phân. Nên dùng khi làm toán số thực. |
char |
Ký tự | 1 byte | Chứa đúng 1 ký tự duy nhất (ví dụ: 'A', 'b', '9', '#'). |
bool |
Kiểu logic | 1 byte | Chỉ nhận 2 giá trị là true (đúng/1) hoặc false (sai/0). |
string |
Chuỗi ký tự | Biến động | Lưu trữ chuỗi văn bản (ví dụ: "Sencode"). |
Ví dụ khai báo và sử dụng:
#include <bits/stdc++.h>
using namespace std;
int main() {
int tuoi = 16;
long long khoangCachSao = 9460730472580LL; // Hậu tố LL cho số long long
double diemToan = 9.75;
char diemChu = 'A';
bool passKyThi = true;
string tenHocSinh = "Nguyen Van A";
cout << "Hoc sinh: " << tenHocSinh << "\n";
cout << "Tuoi: " << tuoi << ", Diem so: " << diemToan << " (" << diemChu << ")\n";
cout << "Ket qua do: " << passKyThi << " (1 nghia la true/dat)\n";
return 0;
}
5. Câu lệnh gán (Assignment Statement)
Khái niệm:
Câu lệnh gán được dùng để lưu giá trị của một biểu thức hoặc một giá trị cụ thể vào một biến.
tên_biến = biểu_thức;
Lưu ý: Phép gán hoạt động theo chiều từ Phải qua Trái. Tức là hệ thống sẽ tính toán kết quả của biểu thức bên phải trước, rồi mới nạp (gán) kết quả đó vào biến ở bên trái.
Phép toán gán kết hợp:
C++ cung cấp các toán tử viết tắt để cập nhật giá trị hiện tại của biến:
x += y;tương đương vớix = x + y;x -= y;tương đương vớix = x - y;x *= y;tương đương vớix = x * y;x /= y;tương đương vớix = x / y;x %= y;tương đương vớix = x % y;
Ví dụ minh họa:
#include <bits/stdc++.h>
using namespace std;
int main() {
int a = 5;
a = a + 3; // a nhận giá trị mới là 8
a += 2; // Tương đương a = a + 2 -> a lúc này bằng 10
a *= 3; // Tương đương a = a * 3 -> a lúc này bằng 30
cout << "Gia tri cuoi cung cua a: " << a << "\n";
return 0;
}
6. Các phép toán, biểu thức và hàm trong C++
1. Phép toán số học cơ bản
- Cộng (
+), Trừ (-), Nhân (*). - Phép chia lấy thương nguyên (
/): Nếu cả số bị chia và số chia đều là số nguyên, kết quả trả về sẽ là phần nguyên (ví dụ7 / 3ra2). - Phép chia lấy phần dư (
%): Chỉ áp dụng cho số nguyên (ví dụ7 % 3ra1).
CẢNH BÁO BẪY SỐ THỰC: Nếu muốn kết quả chia ra số thực đầy đủ, ít nhất một trong hai toán tử phải thuộc kiểu số thực hoặc phải ép kiểu:
double thuong = 7.0 / 3; // Ra 2.3333...double thuong_2 = (double)7 / 3; // Ép kiểu số 7 sang double, ra 2.3333...
2. Phép toán tăng / giảm một đơn vị
x++hoặc++x: Tăngxlên 1 đơn vị.x--hoặc--x: Giảmxđi 1 đơn vị.
3. Các hàm toán học phổ biến
Khi sử dụng thư viện gộp <bits/stdc++.h>, hệ thống đã tích hợp sẵn tất cả các hàm toán học cần thiết nằm trong các thư viện con như <cmath> hay <algorithm>. Các hàm hay dùng bao gồm:
abs(x): Tính giá trị tuyệt đối của số nguyênx. (Đối với số thực ta dùngfabs(x)).sqrt(x): Tính căn bậc hai của số thực không âmx.pow(base, exp): Tính lũy thừa baseexp.round(x): Làm tròn số thựcxvề số nguyên gần nhất.min(a, b),max(a, b): Tìm số nhỏ nhất/lớn nhất giữa hai số.
Ví dụ minh họa biểu thức và hàm:
#include <bits/stdc++.h> // Thư viện gộp đã bao gồm cmath và algorithm
using namespace std;
int main() {
int x = -9;
int y = 4;
cout << "Tri tuyet doi cua x: " << abs(x) << "\n";
cout << "Can bac hai cua y: " << sqrt(y) << "\n";
cout << "Luy thua 2 mu 5: " << pow(2, 5) << "\n";
double a = 5.8;
cout << "Lam tron a: " << round(a) << "\n";
// Tinh bieu thuc phuc tap: S = can_bac_hai(3^2 + 4^2)
double S = sqrt(pow(3, 2) + pow(4, 2));
cout << "Ket qua S: " << S << "\n"; // S = sqrt(9 + 16) = 5
return 0;
}
7. Câu lệnh nhập / xuất dữ liệu
1. Câu lệnh xuất dữ liệu (cout)
- Dùng toán tử
<<để đưa dữ liệu ra màn hình. - Có thể in nhiều giá trị liên tiếp:
cout << "Gia tri: " << a << " va b: " << b << "\n"; - Ký tự xuống dòng: Hãy ưu tiên dùng
"\n"thay vìendlđể tối ưu hóa tốc độ in (đặc biệt khi dữ liệu xuất rất lớn).
2. Câu lệnh nhập dữ liệu (cin)
- Dùng toán tử
>>để đọc dữ liệu từ bàn phím vào biến. - Có thể nhập nhiều biến cùng lúc (ngăn cách bằng khoảng trắng hoặc dấu xuống dòng):
cin >> a >> b >> c;
3. Tối ưu hóa tốc độ nhập xuất trong lập trình thi đấu (Fast I/O)
Để chương trình C++ của bạn đạt tốc độ tối đa, không bị nghẽn luồng nhập xuất khi bài toán có hàng trăm ngàn dòng dữ liệu, hãy luôn thêm ba dòng lệnh này ở đầu hàm main:
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
Giải thích chi tiết:
ios_base::sync_with_stdio(false);: Tắt sự đồng bộ hóa giữa các luồng nhập xuất của C++ (std::cin,std::cout) và C (stdin,stdout). Việc này giúp tăng tốc độ thực thi các câu lệnhcin/coutlên ngang ngửa hoặc thậm chí hơnscanf/printf.cin.tie(NULL);: Ngắt liên kết (untie) mặc định giữa luồng nhậpcinvà luồng xuấtcout. Theo mặc định, mỗi khi có yêu cầu nhập dữ liệu thông quacin, hệ thống sẽ tự động dọn sạch bộ đệm (flush) củacoutđể hiển thị các kết quả trước đó ra màn hình. Việc ngắt liên kết này giúp chương trình không tốn thời gian dọn bộ đệm liên tục khi nhập xuất xen kẽ.cout.tie(NULL);: Tương tự nhưcin.tie, dòng lệnh này ngắt liên kết cho luồng xuấtcout. Mặc dù theo mặc địnhcoutkhông liên kết với luồng nhập nào khác, việc viết thêm dòng này giúp đảm bảo tính đồng bộ hoàn toàn và hình thành thói quen viết code Fast I/O tốt khi lập trình thi đấu.
4. Định dạng chữ số thập phân khi in số thực
Để giới hạn số chữ số sau dấu phẩy của số thực (ví dụ in ra điểm số có đúng 2 chữ số thập phân), ta sử dụng bộ định dạng từ thư viện con <iomanip> (được tự động nạp kèm trong thư viện gộp):
cout << fixed << setprecision(số_chữ_số);
8. Chương trình hoàn chỉnh mẫu
Dưới đây là một bài toán thực tế hoàn chỉnh: Nhập vào bán kính R của hình tròn. Tính và in ra chu vi, diện tích hình tròn đó với độ chính xác lấy đúng 2 chữ số thập phân.
#include <bits/stdc++.h> // Thư viện gộp chứa đầy đủ iostream, iomanip, cmath...
using namespace std;
int main() {
// Tối ưu hóa nhập xuất (Fast I/O)
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
// Khai báo hằng số PI
const double PI = 3.141592653589793;
// Khai báo biến
double banKinh;
// Nhập bán kính từ bàn phím
cin >> banKinh;
// Tính toán chu vi và diện tích
double chuVi = 2 * PI * banKinh;
double dienTich = PI * pow(banKinh, 2);
// Xuất kết quả làm tròn đúng 2 chữ số thập phân
cout << fixed << setprecision(2);
cout << "Chu vi: " << chuVi << "\n";
cout << "Dien tich: " << dienTich << "\n";
return 0;
}
9. ĐỀ XUẤT 10 BÀI TẬP THỰC HÀNH THỰC TẾ (LẬP TRÌNH THI ĐẤU)
Trong lập trình thi đấu, đề bài thường được ẩn giấu dưới dạng các câu chuyện thực tế. Học sinh cần đọc kỹ để trích xuất được Input, Output và xây dựng thuật toán phù hợp. Dưới đây là 10 bài tập rèn luyện kỹ năng đọc hiểu đề và lập trình nhập xuất cơ bản:
Bài 1: Chia kẹo ngày Tết
- Ngữ cảnh: Tới ngày Tết, mẹ mua một túi kẹo gồm X chiếc kẹo và muốn chia đều cho N người con. Phần kẹo còn thừa không chia đều được sẽ dành tặng cho chú cún con cưng của gia đình.
- Yêu cầu: Tính số kẹo mỗi người con nhận được và số kẹo chú cún được thưởng.
- Đầu vào (Input): Một dòng chứa hai số nguyên dương X và N (1 <= X, N <= 109) cách nhau bởi khoảng trắng.
- Đầu ra (Output): Hai số nguyên cách nhau một khoảng trắng: số kẹo mỗi người con nhận và số kẹo chú cún nhận.
- Ví dụ:
- Input:
23 5 - Output:
4 3
- Input:
Bài 2: Hóa đơn điện nước
- Ngữ cảnh: Gia đình Nam sử dụng điện sinh hoạt. Tháng này, chỉ số điện cũ là A (kWh) và chỉ số điện mới là B (kWh). Biết rằng đơn giá mỗi kWh điện là 2500 đồng, và tổng hóa đơn phải chịu thêm 10% thuế giá trị gia tăng (VAT).
- Yêu cầu: Tính tổng số tiền điện mà gia đình Nam phải trả trong tháng này.
- Đầu vào (Input): Một dòng chứa hai số nguyên A và B (0 <= A <= B <= 106).
- Đầu ra (Output): Một số thực duy nhất biểu thị số tiền điện phải trả (lấy chính xác 1 chữ số thập phân).
- Ví dụ:
- Input:
120 250 - Output:
357500.0
- Input:
Bài 3: Quy đổi thời gian của phi hành gia
- Ngữ cảnh: Một phi hành gia tham gia nhiệm vụ ngoài vũ trụ kéo dài S giây.
- Yêu cầu: Quy đổi thời gian S giây đó sang định dạng giờ, phút, giây thông thường (H giờ, M phút, SE giây) để dễ báo cáo về Trái Đất.
- Đầu vào (Input): Một số nguyên duy nhất S (0 <= S <= 109).
- Đầu ra (Output): Ba số nguyên H, M, SE cách nhau bởi dấu cách biểu diễn giờ, phút, giây tương ứng.
- Ví dụ:
- Input:
3665 - Output:
1 1 5
- Input:
Bài 4: Đo đạc thửa ruộng hình thang
- Ngữ cảnh: Bác Ba có một thửa ruộng hình thang vuông có đáy lớn là A mét, đáy bé là B mét và chiều cao là H mét (cạnh bên vuông góc với hai đáy chính bằng H). Bác muốn rào lưới xung quanh ruộng nên cần tính diện tích ruộng và độ dài cạnh bên nghiêng còn lại.
- Yêu cầu: Tính diện tích thửa ruộng và độ dài cạnh bên nghiêng còn lại (Áp dụng định lý Pythagoras: cạnh nghiêng = cănbậchai((A - B)2 + H2)).
- Đầu vào (Input): Ba số thực A, B, H (1 <= B < A <= 104, 1 <= H <= 104).
- Đầu ra (Output): Hai số thực cách nhau bởi dấu cách lần lượt là Diện tích và Độ dài cạnh nghiêng (làm tròn đúng 2 chữ số thập phân).
- Ví dụ:
- Input:
10.0 6.0 3.0 - Output:
24.00 5.00
- Input:
Bài 5: Khoảng cách định vị GPS
- Ngữ cảnh: Trên bản đồ tọa độ Oxy, chiếc xe tự hành A đang ở vị trí (x1, y1) và trạm phát sóng B cố định ở vị trí (x2, y2).
- Yêu cầu: Tính khoảng cách đường thẳng ngắn nhất kết nối từ xe A tới trạm phát sóng B.
- Đầu vào (Input): Bốn số thực x1, y1, x2, y2 cách nhau bởi khoảng trắng (giá trị tuyệt đối không quá 104).
- Đầu ra (Output): Một số thực duy nhất là khoảng cách giữa xe và trạm (lấy chính xác 4 chữ số thập phân).
- Ví dụ:
- Input:
1.0 2.0 4.0 6.0 - Output:
5.0000
- Input:
Bài 6: Đổi ngoại tệ tại sân bay
- Ngữ cảnh: Một khách du lịch mang U USD đến đổi tiền tại sân bay. Tỷ giá hôm nay là: 1 USD đổi được V VND. Tuy nhiên, quầy dịch vụ sẽ thu phí quy đổi là 1.5% trên tổng số tiền VND nhận được trước khi trao cho khách.
- Yêu cầu: Tính số tiền VND thực tế du khách nhận được sau khi đã trừ đi phí dịch vụ quy đổi.
- Đầu vào (Input): Số thực U (1 <= U <= 106) và số thực V (1000 <= V <= 50000).
- Đầu ra (Output): Một số thực duy nhất là số tiền VND thực nhận (lấy chính xác 2 chữ số thập phân).
- Ví dụ:
- Input:
100 25400 - Output:
2501900.00
- Input:
Bài 7: Tính điểm xét tốt nghiệp
- Ngữ cảnh: Điểm xét tốt nghiệp THPT của học sinh được tính dựa trên điểm 3 môn bắt buộc: Toán (hệ số 2), Ngữ văn (hệ số 2), Tiếng Anh (hệ số 1).
- Yêu cầu: Hãy viết chương trình nhận vào điểm 3 môn này và tính điểm trung bình có hệ số.
- Đầu vào (Input): Ba số thực T, V, A lần lượt là điểm Toán, Văn, Anh (0 <= T, V, A <= 10.0).
- Đầu ra (Output): Một số thực duy nhất là điểm trung bình hệ số (lấy chính xác 2 chữ số thập phân).
- Ví dụ:
- Input:
8.5 7.0 9.0 - Output:
8.00
- Input:
Bài 8: Chuyến đò đưa khách
- Ngữ cảnh: Một đoàn khách gồm N người cần di chuyển qua sông bằng đò. Mỗi chuyến đò chỉ chở được tối đa K người (bao gồm cả hành khách, không tính người chèo đò lái thuyền).
- Yêu cầu: Tính số chuyến đò tối thiểu cần thiết để vận chuyển toàn bộ N hành khách qua sông.
- Đầu vào (Input): Hai số nguyên dương N và K (1 <= N, K <= 109).
- Đầu ra (Output): Một số nguyên duy nhất là số chuyến đò tối thiểu.
- Ví dụ:
- Input:
25 7 - Output:
4
- Input:
Bài 9: Sơn hàng rào trường học
- Ngữ cảnh: Trường học cần sơn lại một bức tường hàng rào chạy thẳng có độ dài lớn. Người thợ sơn thứ nhất sơn từ vị trí A mét đến B mét. Người thợ thứ hai sơn từ vị trí C mét đến D mét.
- Yêu cầu: Tính tổng chiều dài bức tường thực tế đã được sơn nếu biết phần sơn của hai người thợ có thể trùng lặp lên nhau.
- Mẹo nhỏ: Tính chiều dài đoạn 1 = B - A, đoạn 2 = D - C. Khoảng giao nhau trùng lặp = max(0, min(B, D) - max(A, C)). Tổng chiều dài được sơn = (đoạn 1 + đoạn 2) - khoảng trùng lặp.
- Đầu vào (Input): Bốn số nguyên A, B, C, D (0 <= A <= B <= 109, 0 <= C <= D <= 109) cách nhau bởi khoảng trắng.
- Đầu ra (Output): Một số nguyên duy nhất là tổng độ dài bức tường được phủ sơn.
- Ví dụ:
- Input:
2 7 5 10 - Output:
8
- Input:
Bài 10: Ước lượng gạch lát sàn
- Ngữ cảnh: Một căn phòng hình chữ nhật có kích thước dài X mét và rộng Y mét. Chủ nhà muốn mua các viên gạch men hình vuông kích thước cạnh A cm để lát kín toàn bộ nền phòng.
- Yêu cầu: Tính số lượng viên gạch men tối thiểu cần mua. Biết rằng khi lát, gạch có thể bị cắt nhỏ để khớp góc tường nhưng các mảnh cắt thừa không thể tái sử dụng (tức là số gạch cần theo chiều dài và chiều rộng đều phải được làm tròn lên trước khi nhân với nhau).
- Đầu vào (Input): Hai số thực X, Y biểu thị kích thước mét (1.0 <= X, Y <= 100.0) và một số nguyên A biểu thị cm (10 <= A <= 100).
- Đầu ra (Output): Một số nguyên duy nhất biểu thị số viên gạch cần mua.
- Ví dụ:
- Input:
4.5 3.2 60 - Output:
48
- Input:
Lời kết
Việc hiểu rõ cách hoạt động của biến, hằng, các phép toán số học và cú pháp nhập xuất dữ liệu là nền móng để bạn tiến xa hơn tới cấu trúc rẽ nhánh (if-else), vòng lặp (for, while) và các thuật toán nâng cao.
Hãy thực hành viết chương trình và gửi lời giải của 10 bài tập nhập xuất cơ bản trên tại Sen Code Online Judge! để thấy những điểm số AC đầu tiên nhé! Chúc các bạn học tập thật tốt!
Bình luận