Tiếp cận với Lập trình thi đấu là đòi hỏi sự luyện tập lâu dài và liên tục, nhưng cũng phải hiệu quả. Vì vậy, ta cần phải trang bị những kỹ năng cơ bản để có phương pháp luyện tập tối ưu và phù hợp với bản thân.
Cấu trúc của một chương trình trong C++
#include <bits/stdc++.h>
using namespace std;
int main() {
//solution goes here
}
#include <bits/stdc++.h> Phần đầu tiên của mọi chương trình được lập trình bằng C++ sẽ luôn là khai báo thư viện sử dụng trong code, thư viện bits/stdc++.h là một thư viện tổng hợp các thư viện cần thiết nhất, gần như khi khai báo thư viện này thì sẽ không cần phải đung tới các thư viện khác. Ở những năm về trước, khi việc cài đặt máy chấm còn chưa được phổ cập, thành phố khi chấm bài thường loại trừ thư viện này ra và yêu cầu thí sinh phải khai báo từng thư viện một, điều này khiến cho nhiều thí sinh bài làm không thể chạy được khi khai báo thư viện bits/stdc++.h và bị mất điểm trắng. Những năm trở lại đây thì điều này trở nên ít đi và chuyện đặt nặng vấn đề khai báo thư viện đã gần như hạn chế, do đó chuyện khai báo chỉ một thư viện này cho mọi bài tập là hoàn toàn hợp lệ.
using namespace std Việc sử dụng lệnh using trong code có ý nghĩa là khởi tạo một class hoặc function từ thư viện và câu lệnh này được áp dụng trong xuyên suốt chương trình. Khi sử dụng using namespace std tức là bạn không cần phải viết hẳn ra là std::cout khi thực hiện thao tác in mà chỉ cần viết là cout.
int main() { ~\dots~ } Đây sẽ là nơi viết code chính, mọi câu lệnh sẽ được thực thi trong hàm này, nếu thay thế hàm này bằng một hàm khác với tên khác thì chương trình sẽ không thể chạy.
Nhập/xuất trong C++
Bất cứ một bài toán nào thì cũng cần có dữ liệu đầu vào và chương trình phải có dữ liệu đầu ra để kiếm tra tính đúng đắn của code. Chính vì thế ta phải hiểu rõ về chuyện nhập/xuất trong C++.
- Nhập/xuất chuẩn (Standard Input/Output): khái niệm này đã được đề cập trong blog Giới thiệu về Lập trình thi đấu (Competitive Programming), nhìn chung ta sẽ sử dụng chính hai câu lệnh là cin cho việc nhập và cout cho việc xuất.
Sau đây là đoạn code minh họa cho thao tác nhập dữ liệu:
int a, b;
string x;
cin >> a >> b >> x;
Đoạn code đang có hai biến ~a~ và ~b~ thuộc kiểu dữ liệu int, tức kiểu dữ liệu cho phép nhận vào số nguyên trong khoảng từ ~-2147483648~ đến ~2147483647~. Đoạn code còn có thêm một biến ~x~ thuộc kiểu dữ liệu string, tức kiểu dữ liệu cho phép nhận vào một chuỗi các kí tự. Để hiểu sâu hơn về các kiểu dữ liệu, tham khảo thêm tại đây.
Sau đây là đoạn code minh họa cho thao tác xuất dữ liệu:
int a = 123, b = 456;
string x = "monkey";
cout << a << " " << b << " " << x << '\n';
Khi chạy đoạn code này, trên màn hình đen sẽ xuất ra như sau:
123 456 monkey
~\rightarrow~ Nhìn chung, thao tác nhập/xuất trong C++ ít phức tạp hơn Pascal.
- Nhập/xuất qua File (Input/Output via File): khái niệm này cũng đã được đề cập trong blog Giới thiệu về Lập trình thi đấu (Competitive Programming), khi thực hiện Nhập/xuất qua File thì ta chỉ cần thêm hai câu lệnh sau:
freopen("name.inp", "r", stdin);
freopen("name.out", "w", stdout);
Ở phần "name.inp" hay "name.out" thì có thể thay "name" thành tên bài theo yêu cầu của đề bài. Ta có thể thấy file "name.inp" được đi cùng với tham số stdin và "name.out" được đi cùng với tham số stdout. Ta cần nhớ kĩ điều này để tránh trường hợp "name.inp" đi với stdout và "name.out" đi với stdin.
- Nhập/xuất khi không biết trước số lượng dữ liệu: ở một số bài yêu càu nhập các số những không cho trước số lượng số thì ta sẽ thực hiện nhập/xuất như sau:
while(cin >> x){
//code
}
Vòng lặp này sẽ đọc lần lượt các phần tử có trong dữ liệu đầu vào và sẽ dừng khi không còn dữ liệu nào nữa.
- Nhập/xuất khi muốn đọc hết một dòng: đôi lúc ta cần phải đọc hết dữ liệu trên cùng một dòng, và trên dòng đó cũng có chứa các khoảng trắng thì ta sẽ thực hiện nhập/xuất như sau:
string s;
getline(cin, s);
Tốc độ chạy của thao tác nhập/xuất trong C++
Trong Lập trình thi đấu thì tốc độ code chạy rất quan trọng, vì thế đôi lúc chuyện nhập/xuất trong C++ trở thành vấn đề chính trong chuyện chương trình chạy quá thời gian (TLE) khi nộp bài. Để giảm thiểu chuyện này, ta có một số mẹo như sau:
- Tắt những thao tác dư thừa trong khi nhập/xuất: trong C++ thì hàm cin và cout gồm rất nhiều thao tác bên trong, có một số thao tác trở nên dư thừa và vô tình làm cho chuyện đọc dữ liệu trở nên bị chậm đi, thế nên để hạn chế điều này, thì ở đầu đoạn code nhưng trong hàm main(), ta sẽ thêm hai câu lệnh này:
ios::sync_with_stdio(0);
cin.tie(0);
Sử dụng lệnh '\n' thay vì endl để xuống hàng: khi muốn xuống hàng khi in ra, '\n' tỏ ra nhanh hơn bởi vì không cần phải thực hiện thao tác flush. Để hiểu thêm về thao tác flush, tham khảo thêm tại đây
Sử dụng nhập/xuất kiểu C: khác với C++ nhập/xuất bằng cin và cout thì C nhập/xuất bằng scanf và printf, về mặt tốc độ thì scanf và printf nhanh hơn một chút, nhưng bù lại thì câu lệnh phức tạp hơn. Tuy vậy ở những bản C14 trở đi trên các trang nộp bài Online thì chuyện này không còn là vấn đề lớn nữa. Thậm chí ngay cả các kì thi Offline cũng hạn chế chuyện bài làm của thí sinh bị TLE do chuyện nhập/xuất. Vì vậy ta không nên vì một chút tốc độ mà gây cản trở trong việc code.
Làm việc với các kiểu dữ liệu số
Trong lập trình thì việc làm việc với các con số là thường xuyên, chính vì thế ta cần phải trang bị kiến thức cần thiết về các loại biến số trong C++. Ở phần này sẽ không liệt kê hết toàn bộ kiểu dữ liệu xuất hiện trong C++ mà chỉ đề cập những kiểu dữ liệu phổ biến thường được áp dụng trong các bài tập.
int: kiểu dữ liệu ~32~-bit cho phép lưu trữ các số nguyên trong khoảng từ ~-2^{31}~ đến ~2^{31}-1~ (tương đương ~-2 \times 10^9~ đến ~2 \times 10^9~).
long long: kiểu dữ liệu ~64~-bit cho phép lưu trữ các số nguyên trong khoảng từ ~-2^{63}~ đến ~2^{63}-1~ (tương đương ~-9 \times 10^{18}~ đến ~9 \times 10^{18}~).
unsigned: là một tiên tố thường đi trước một kiểu dữ liệu: unsigned int, unsigned long long, ~\dots~. Ý nghĩa của tiền tố này là sẽ hạn chế khoảng giá trị số nguyên âm lại và bổ sung khoảng giá trị đó vào phần số nguyên dương. Như unsigned int có khoảng giá trị từ ~0~ đến ~2 \times 2^{31}~.
float: kiểu dữ liệu
Bình luận