Bài 25.1: Khái niệm và sử dụng mảng 2 chiều trong C++

Bài 25.1: Khái niệm và sử dụng mảng 2 chiều trong C++
Chào mừng trở lại với chuỗi bài viết về C++! Hôm nay, chúng ta sẽ nâng cấp kiến thức về mảng của mình bằng cách khám phá một cấu trúc dữ liệu mạnh mẽ và cực kỳ hữu ích: mảng 2 chiều (2D Array). Nếu mảng 1 chiều giúp bạn lưu trữ một danh sách các giá trị, thì mảng 2 chiều cho phép bạn biểu diễn dữ liệu dưới dạng bảng hoặc lưới - một thứ cực kỳ phổ biến trong thế giới thực!
Hãy cùng đi sâu vào thế giới của các bảng số trong C++!
Mảng 2 chiều là gì?
Hãy tưởng tượng mảng 1 chiều là một danh sách các ngăn kéo được xếp thẳng hàng. Mỗi ngăn kéo chứa một giá trị.
[ Ngăn 0 ] [ Ngăn 1 ] [ Ngăn 2 ] [ Ngăn 3 ] ...
Còn mảng 2 chiều? Nó giống như một bảng các ngăn kéo được sắp xếp thành nhiều hàng và nhiều cột. Mỗi ngăn kéo vẫn chứa một giá trị, nhưng bây giờ bạn cần biết nó nằm ở hàng nào và cột nào để truy cập.
Cột 0 Cột 1 Cột 2 Cột 3 ...
Hàng 0 [ ] [ ] [ ] [ ]
Hàng 1 [ ] [ ] [ ] [ ]
Hàng 2 [ ] [ ] [ ] [ ]
...
Về bản chất, mảng 2 chiều trong C++ có thể được coi là một mảng của các mảng 1 chiều. Mỗi "phần tử" của mảng chính là một mảng 1 chiều (một hàng).
Cấu trúc này cực kỳ hữu ích khi bạn cần làm việc với:
- Ma trận trong toán học.
- Bảng tính hoặc dữ liệu dạng bảng.
- Bản đồ hoặc lưới trò chơi.
- Hình ảnh (lưới điểm ảnh).
- Và nhiều ứng dụng khác cần tổ chức dữ liệu theo cấu trúc hàng và cột.
Khai báo mảng 2 chiều
Để khai báo một mảng 2 chiều trong C++, bạn cần chỉ định kiểu dữ liệu của các phần tử, tên mảng, số lượng hàng và số lượng cột. Cú pháp như sau:
kieu_du_lieu ten_mang[so_hang][so_cot];
Lưu ý quan trọng: Đối với mảng C-style (mảng tĩnh) được khai báo theo cách này, so_hang
và so_cot
phải là các giá trị hằng số nguyên dương (hoặc biểu thức có thể tính toán tại thời điểm biên dịch).
Ví dụ:
#include <iostream>
int main() {
// Khai báo một mảng số nguyên có 3 hàng và 4 cột
int matrix[3][4];
// Khai báo một mảng ký tự có 5 hàng và 10 cột
char grid[5][10];
// Kích thước có thể là hằng số
const int ROWS = 2;
const int COLS = 5;
double data[ROWS][COLS];
cout << "Da khai bao cac mang 2 chieu." << endl;
return 0;
}
Giải thích:
- Chúng ta khai báo ba mảng 2 chiều với các kiểu dữ liệu và kích thước khác nhau.
matrix
là một bảng 3x4 chứa các số nguyên.grid
là một bảng 5x10 chứa các ký tự.data
là một bảng 2x5 chứa các số thực (double), sử dụng hằng số để chỉ định kích thước, giúp code dễ đọc và dễ bảo trì hơn.- Lúc này, các phần tử trong mảng có giá trị không xác định (rác).
Khởi tạo mảng 2 chiều
Bạn có thể gán giá trị cho các phần tử của mảng 2 chiều ngay khi khai báo. Có một vài cách phổ biến:
Khởi tạo đầy đủ bằng danh sách lồng nhau: Sử dụng dấu ngoặc nhọn
{}
lồng nhau. Mỗi cặp{}
bên trong biểu diễn một hàng.#include <iostream> #include <iomanip> // Để định dạng output int main() { // Khởi tạo một mảng 2x3 với các giá trị cụ thể int simpleMatrix[2][3] = { {1, 2, 3}, // Hàng 0 {4, 5, 6} // Hàng 1 }; cout << "Mang simpleMatrix da khoi tao:" << endl; // Để in ra, chúng ta cần duyệt qua mảng (sẽ nói chi tiết hơn sau) for (int i = 0; i < 2; ++i) { // Duyệt qua các hàng for (int j = 0; j < 3; ++j) { // Duyệt qua các cột cout << setw(4) << simpleMatrix[i][j]; // setw để căn chỉnh cho đẹp } cout << endl; // Hết một hàng thì xuống dòng } return 0; }
Giải thích:
simpleMatrix
được khai báo và khởi tạo đồng thời.{1, 2, 3}
là danh sách các giá trị cho hàng 0.{4, 5, 6}
là danh sách các giá trị cho hàng 1.- Chúng ta sử dụng vòng lặp
for
lồng nhau để in ra các giá trị đã được khởi tạo, cho thấy cấu trúc bảng của nó.setw(4)
giúp các số được căn chỉnh trong 4 ký tự, làm cho bảng dễ đọc hơn.
Khởi tạo bằng danh sách phẳng: Bạn có thể cung cấp tất cả các giá trị trong một danh sách duy nhất. Trình biên dịch sẽ tự động điền vào mảng theo thứ tự từng hàng một.
#include <iostream> #include <iomanip> int main() { // Khởi tạo một mảng 3x2 bằng danh sách phẳng int flatMatrix[3][2] = {10, 20, 30, 40, 50, 60}; cout << "Mang flatMatrix da khoi tao:" << endl; for (int i = 0; i < 3; ++i) { // 3 hàng for (int j = 0; j < 2; ++j) { // 2 cột cout << setw(4) << flatMatrix[i][j]; } cout << endl; } return 0; }
Giải thích:
- Các giá trị
10, 20, 30, 40, 50, 60
sẽ được gán lần lượt vàoflatMatrix[0][0]
,flatMatrix[0][1]
,flatMatrix[1][0]
,flatMatrix[1][1]
,flatMatrix[2][0]
,flatMatrix[2][1]
.
- Các giá trị
Khởi tạo một phần: Nếu bạn cung cấp ít giá trị hơn tổng số phần tử, các phần tử còn lại sẽ được khởi tạo về giá trị 0 (đối với kiểu số) hoặc giá trị mặc định (đối với các kiểu dữ liệu khác).
#include <iostream> #include <iomanip> int main() { // Khởi tạo một mảng 3x3, chỉ cung cấp một vài giá trị int partialMatrix[3][3] = { {1, 1}, // Hàng 0: 1, 1, 0 {2}, // Hàng 1: 2, 0, 0 {0, 0, 3} // Hàng 2: 0, 0, 3 }; cout << "Mang partialMatrix da khoi tao mot phan:" << endl; for (int i = 0; i < 3; ++i) { // 3 hàng for (int j = 0; j < 3; ++j) { // 3 cột cout << setw(4) << partialMatrix[i][j]; } cout << endl; } return 0; }
Giải thích:
- Các giá trị không được cung cấp rõ ràng sẽ mặc định là 0. Ví dụ, hàng 0 chỉ có
{1, 1}
nên phần tử thứ 3 (partialMatrix[0][2]
) sẽ là 0. Hàng 1 chỉ có{2}
nênpartialMatrix[1][1]
vàpartialMatrix[1][2]
sẽ là 0.
- Các giá trị không được cung cấp rõ ràng sẽ mặc định là 0. Ví dụ, hàng 0 chỉ có
Bỏ qua số hàng khi khởi tạo đầy đủ: Nếu bạn cung cấp danh sách khởi tạo lồng nhau đầy đủ, bạn có thể bỏ qua việc chỉ định số hàng. Trình biên dịch sẽ tự động tính toán số hàng dựa trên danh sách khởi tạo. Tuy nhiên, bạn vẫn PHẢI chỉ định số cột.
```cpp #include <iostream> #include <iomanip>
int main() {
// Bỏ qua số hàng, trình bien dich tu tinh: 2 hàng int autoRowsMatrix[][4] = { {100, 200, 300, 400}, {500, 600, 700, 800} }; // Kích thước thực tế: 2 hàng, 4 cột const int deducedRows = sizeof(autoRowsMatrix) / sizeof(autoRowsMatrix[0]); const int cols = sizeof(autoRowsMatrix[0]) / sizeof(autoRowsMatrix[0][0]); cout << "Mang autoRowsMatrix (tu dong tinh so hang) da khoi tao:" << endl; cout << "So hang thuc te: " << deducedRows << endl; cout << "So cot: " << cols << endl;
for (int i = 0; i < deducedRows; ++i) {
for (int j = 0; j < cols; ++j) {
cout << setw(6) << autoRowsMatrix[i][j];
}
cout << endl;
}
return 0;
}
```
*Giải thích:*
* Khi `autoRowsMatrix[][4]` được khởi tạo với hai cặp `{}` lồng nhau, trình biên dịch biết rằng có 2 hàng, mỗi hàng có 4 cột.
* Chúng ta có thể tính toán số hàng thực tế bằng cách lấy tổng kích thước của mảng chia cho kích thước của một hàng (`sizeof(autoRowsMatrix[0])`). Số cột được biết trước (4).
Truy cập các phần tử
Để truy cập (đọc hoặc ghi) một phần tử cụ thể trong mảng 2 chiều, bạn sử dụng tên mảng theo sau là hai cặp ngoặc vuông []
, một cho chỉ số hàng và một cho chỉ số cột:
ten_mang[chi_so_hang][chi_so_cot]
Giống như mảng 1 chiều, các chỉ số (indices) bắt đầu từ 0.
chi_so_hang
đi từ0
đếnso_hang - 1
.chi_so_cot
đi từ0
đếnso_cot - 1
.
Ví dụ:
#include <iostream>
int main() {
int gameBoard[4][4] = {
{0, 0, 0, 0},
{0, 1, 0, 0},
{0, 0, 1, 0},
{0, 0, 0, 0}
}; // Ví dụ một bản đồ 4x4
// Truy cập phần tử ở hàng 1, cột 1 (vị trí thứ 2 trong hàng 2)
cout << "Phan tu o hang 1, cot 1 la: " << gameBoard[1][1] << endl; // Output: 1
// Thay đổi giá trị của phần tử ở hàng 3, cột 0 (vị trí đầu tiên trong hàng 4)
gameBoard[3][0] = 9;
cout << "Phan tu o hang 3, cot 0 sau khi thay doi: " << gameBoard[3][0] << endl; // Output: 9
// Truy cập phần tử ở hàng 0, cột 3
cout << "Phan tu o hang 0, cot 3 la: " << gameBoard[0][3] << endl; // Output: 0
return 0;
}
Giải thích:
gameBoard[1][1]
truy cập phần tử ở hàng có chỉ số 1 và cột có chỉ số 1.gameBoard[3][0] = 9;
gán giá trị 9 vào phần tử ở hàng có chỉ số 3 và cột có chỉ số 0.
Cẩn thận với chỉ số: Truy cập mảng ngoài phạm vi (chi_so_hang >= so_hang
hoặc chi_so_cot >= so_cot
) sẽ gây ra lỗi runtime nghiêm trọng (undefined behavior) và có thể làm chương trình gặp sự cố.
Duyệt (lặp qua) mảng 2 chiều
Cách phổ biến nhất để xử lý tất cả các phần tử trong mảng 2 chiều là sử dụng hai vòng lặp for
lồng nhau: một vòng lặp bên ngoài để duyệt qua các hàng và một vòng lặp bên trong để duyệt qua các cột trong mỗi hàng.
#include <iostream>
#include <iomanip>
int main() {
const int ROWS = 3;
const int COLS = 5;
int matrix[ROWS][COLS];
// Gán giá trị cho mảng (ví dụ: chỉ số hàng * 10 + chỉ số cột)
for (int i = 0; i < ROWS; ++i) { // Vòng lặp ngoài: duyệt qua các hàng (0 đến ROWS - 1)
for (int j = 0; j < COLS; ++j) { // Vòng lặp trong: duyệt qua các cột (0 đến COLS - 1)
matrix[i][j] = i * 10 + j;
}
}
// In mảng ra màn hình
cout << "Noi dung mang 2 chieu:" << endl;
for (int i = 0; i < ROWS; ++i) { // Duyệt qua các hàng để in từng hàng
for (int j = 0; j < COLS; ++j) { // Duyệt qua các cột trong hàng hiện tại
cout << setw(4) << matrix[i][j]; // In phần tử và căn chỉnh
}
cout << endl; // Hết một hàng, xuống dòng
}
return 0;
}
Giải thích:
- Vòng lặp ngoài với biến
i
chạy từ 0 đếnROWS - 1
, đại diện cho chỉ số hàng hiện tại. - Với mỗi giá trị của
i
, vòng lặp trong với biếnj
chạy từ 0 đếnCOLS - 1
, đại diện cho chỉ số cột hiện tại trong hàngi
. - Bằng cách này, cặp chỉ số
[i][j]
sẽ truy cập tất cả các phần tử trong mảng một cách tuần tự, từ[0][0]
,[0][1]
, ... đến[0][COLS-1]
, rồi[1][0]
,[1][1]
, ... và cứ thế cho đến[ROWS-1][COLS-1]
.
Mảng 2 chiều và hàm
Khi truyền một mảng 2 chiều (kiểu C-style tĩnh) vào một hàm, bạn gặp một ràng buộc đặc biệt: Bạn phải chỉ định kích thước của tất cả các chiều trừ chiều đầu tiên (số hàng). Điều này là do cách C++ quản lý bộ nhớ cho mảng. Để trình biên dịch tính toán được vị trí của một phần tử [i][j]
, nó cần biết có bao nhiêu cột trong mỗi hàng.
Cú pháp truyền mảng 2 chiều vào hàm:
void ten_ham(kieu_du_lieu ten_bien_mang[][so_cot], int so_hang);
// Hoặc nếu bạn biết cả 2 kích thước cố định
void ten_ham(kieu_du_lieu ten_bien_mang[so_hang_co_dinh][so_cot_co_dinh]);
Ví dụ:
#include <iostream>
#include <iomanip>
// Hàm nhận một mảng 2 chiều 3x4 và in nó
void printMatrix(int arr[][4], int numRows) { // Phải chỉ định số cột (4), số hàng (numRows) truyền vào
const int numCols = 4; // Số cột đã được biết
cout << "--- Trong ham printMatrix ---" << endl;
for (int i = 0; i < numRows; ++i) {
for (int j = 0; j < numCols; ++j) {
cout << setw(4) << arr[i][j];
}
cout << endl;
}
cout << "-----------------------------" << endl;
}
// Hàm nhận một mảng 2 chiều với kích thước cố định 2x3
void processFixedMatrix(double fixedArr[2][3]) {
cout << "--- Trong ham processFixedMatrix (2x3) ---" << endl;
for (int i = 0; i < 2; ++i) {
for (int j = 0; j < 3; ++j) {
cout << setprecision(1) << fixed << setw(5) << fixedArr[i][j];
}
cout << endl;
}
cout << "------------------------------------------" << endl;
}
int main() {
int matrix1[3][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};
double matrix2[2][3] = {
{1.1, 2.2, 3.3},
{4.4, 5.5, 6.6}
};
// Gọi hàm printMatrix
printMatrix(matrix1, 3); // Truyền mảng và số hàng
// Gọi hàm processFixedMatrix
processFixedMatrix(matrix2);
// Lưu ý: Bạn KHÔNG thể truyền matrix1 cho processFixedMatrix vì kích thước khác nhau
return 0;
}
Giải thích:
- Hàm
printMatrix
được định nghĩa để nhận một mảng kiểuint
có số cột là 4 (int arr[][4]
). Số hàng được truyền qua tham sốnumRows
. - Hàm
processFixedMatrix
nhận một mảng kiểudouble
với kích thước cố định là 2 hàng và 3 cột (double fixedArr[2][3]
). - Trong
main
, chúng ta gọi các hàm này và truyền các mảng phù hợp. - Ràng buộc về kích thước cột khi truyền mảng 2 chiều C-style là một điểm cần lưu ý. Điều này làm cho mảng C-style kém linh hoạt hơn so với
vector
khi làm việc với các hàm cần xử lý mảng có kích thước khác nhau.
Một số ví dụ ứng dụng cơ bản
Hãy xem xét một vài ví dụ đơn giản về cách sử dụng mảng 2 chiều để thực hiện các tác vụ cơ bản.
Ví dụ 1: Tính tổng tất cả các phần tử
#include <iostream>
int main() {
const int ROWS = 3;
const int COLS = 3;
int matrix[ROWS][COLS] = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
long long totalSum = 0; // Sử dụng long long để tránh tràn số nếu tổng lớn
// Duyệt qua mảng và cộng dồn các phần tử
for (int i = 0; i < ROWS; ++i) {
for (int j = 0; j < COLS; ++j) {
totalSum += matrix[i][j];
}
}
cout << "Tong tat ca cac phan tu trong mang la: " << totalSum << endl; // Output: 45
return 0;
}
Giải thích:
- Chúng ta sử dụng hai vòng lặp lồng nhau để đi qua từng phần tử
matrix[i][j]
. - Mỗi lần duyệt đến một phần tử, giá trị của nó được cộng vào biến
totalSum
.
Ví dụ 2: Tìm phần tử lớn nhất
#include <iostream>
#include <limits> // Cho numeric_limits
int main() {
const int ROWS = 4;
const int COLS = 5;
int data[ROWS][COLS] = {
{10, -5, 20, 8, 15},
{3, 12, 2, 18, 7},
{-1, 9, 25, 6, 11},
{14, 4, 19, 1, 22}
};
// Khởi tạo max_value bằng giá trị rất nhỏ của kiểu int
int maxValue = numeric_limits<int>::min();
// Duyệt qua mảng để tìm giá trị lớn nhất
for (int i = 0; i < ROWS; ++i) {
for (int j = 0; j < COLS; ++j) {
if (data[i][j] > maxValue) {
maxValue = data[i][j];
}
}
}
cout << "Phan tu lon nhat trong mang la: " << maxValue << endl; // Output: 25
return 0;
}
Giải thích:
- Chúng ta khởi tạo
maxValue
bằng giá trị nhỏ nhất có thể của kiểuint
để đảm bảo bất kỳ phần tử nào trong mảng cũng sẽ lớn hơn nó (trừ khi mảng rỗng hoặc chỉ chứa giá trịmin
). - Vòng lặp lồng nhau duyệt qua từng phần tử. Nếu phần tử hiện tại lớn hơn
maxValue
, chúng ta cập nhậtmaxValue
.
Ví dụ 3: Tính tổng của một hàng cụ thể
#include <iostream>
int main() {
const int ROWS = 3;
const int COLS = 4;
int salesData[ROWS][COLS] = {
{100, 150, 120, 200}, // Hàng 0
{250, 180, 300, 220}, // Hàng 1
{110, 160, 140, 190} // Hàng 2
}; // Ví dụ: Doanh số theo quý (cột) của 3 chi nhánh (hàng)
int targetRow = 1; // Muốn tính tổng doanh số của chi nhánh thứ 2 (hàng 1)
int rowSum = 0;
// Duyệt qua các cột của hàng targetRow
if (targetRow >= 0 && targetRow < ROWS) { // Kiểm tra chỉ số hàng hợp lệ
for (int j = 0; j < COLS; ++j) {
rowSum += salesData[targetRow][j];
}
cout << "Tong doanh so cua chi nhanh " << targetRow + 1 << " (Hang " << targetRow << ") la: " << rowSum << endl; // Output: 950
} else {
cout << "Chi so hang khong hop le!" << endl;
}
return 0;
}
Giải thích:
- Chúng ta chọn một hàng cụ thể (
targetRow
). - Chỉ cần một vòng lặp để duyệt qua tất cả các cột (
j
) trong hàng đó (salesData[targetRow][j]
). - Thêm kiểm tra
if
để đảm bảo chỉ số hàng truy cập là hợp lệ.
Ví dụ 4: Nhập dữ liệu từ người dùng
Bạn cũng có thể sử dụng vòng lặp lồng nhau để đọc dữ liệu nhập từ người dùng và lưu vào mảng 2 chiều.
#include <iostream>
int main() {
const int ROWS = 2;
const int COLS = 3;
int userMatrix[ROWS][COLS];
cout << "Nhap " << ROWS * COLS << " so nguyen cho mang " << ROWS << "x" << COLS << ":" << endl;
// Vòng lặp để đọc dữ liệu nhập
for (int i = 0; i < ROWS; ++i) {
cout << "Nhap cac phan tu cho hang " << i + 1 << ": ";
for (int j = 0; j < COLS; ++j) {
cin >> userMatrix[i][j];
}
}
// In lại mảng để kiểm tra
cout << "\nMang ban vua nhap la:" << endl;
for (int i = 0; i < ROWS; ++i) {
for (int j = 0; j < COLS; ++j) {
cout << userMatrix[i][j] << " ";
}
cout << endl;
}
return 0;
}
Giải thích:
- Chúng ta sử dụng vòng lặp lồng nhau tương tự như khi in, nhưng thay vì
cout
, chúng ta dùngcin
để đọc giá trị cho từng phần tửuserMatrix[i][j]
. - Thêm các thông báo để người dùng biết cần nhập gì.
Bài tập ví dụ: C++ Bài 11.A1: Ma trận chia hết
Viết chương trình nhập vào ma trận số nguyên gồm \(n\) dòng \(m\) cột. Đếm số lượng các số chia hết cho \(3\) có trong ma trận đó.
INPUT FORMAT
Dòng đầu là hai số nguyên dương \(n, m\) \((1 \leq n, m \leq 1000)\)
Các dòng tiếp theo là ma trận số nguyên \(A\).
OUTPUT FORMAT
In ra số lượng đếm được
Ví dụ:
Input
3 4
1 3 4 6
8 4 2 9
4 2 8 6
Output
4
Giải thích ví dụ mẫu
Đếm số lượng phần tử chia hết cho 3 trong ma trận.
<br>
Đọc kích thước ma trận: Đầu tiên, bạn cần đọc hai số nguyên
n
vàm
từ đầu vào. Đây là số dòng và số cột của ma trận.Khởi tạo bộ đếm: Tạo một biến kiểu số nguyên (ví dụ:
count
) và khởi tạo nó bằng0
. Biến này sẽ dùng để lưu số lượng các phần tử chia hết cho 3 mà bạn tìm thấy.Duyệt qua từng phần tử của ma trận: Vì bạn cần kiểm tra tất cả các phần tử trong ma trận, cách thông thường và hiệu quả nhất là sử dụng hai vòng lặp lồng nhau:
- Vòng lặp ngoài chạy từ
0
đếnn-1
(hoặc1
đếnn
tùy cách bạn quy ước, nhưng0
đếnn-1
phổ biến trong C++). Vòng lặp này đại diện cho các dòng. - Vòng lặp trong chạy từ
0
đếnm-1
(hoặc1
đếnm
). Vòng lặp này đại diện cho các cột trong mỗi dòng.
- Vòng lặp ngoài chạy từ
Đọc và kiểm tra từng phần tử: Bên trong vòng lặp trong cùng (sau khi đã chọn được dòng và cột hiện tại), bạn sẽ:
- Đọc một số nguyên từ đầu vào. Đây là giá trị của phần tử ma trận tại vị trí hiện tại. Bạn có thể đọc nó vào một biến tạm thời (ví dụ:
element
). - Kiểm tra xem số nguyên vừa đọc có chia hết cho
3
hay không. Phép toán%
(modulo) rất hữu ích cho việc này: một số nguyênx
chia hết cho3
nếux % 3 == 0
. - Nếu số đó chia hết cho
3
, tăng giá trị của biếncount
lên1
.
- Đọc một số nguyên từ đầu vào. Đây là giá trị của phần tử ma trận tại vị trí hiện tại. Bạn có thể đọc nó vào một biến tạm thời (ví dụ:
Kết thúc và in kết quả: Sau khi cả hai vòng lặp hoàn thành (tức là bạn đã đọc và kiểm tra tất cả
n * m
phần tử của ma trận), biếncount
sẽ chứa tổng số các phần tử chia hết cho 3. Bạn chỉ cần in giá trị của biếncount
ra màn hình.
Lưu ý quan trọng:
- Với kích thước ma trận tối đa
1000x1000
, bạn không nhất thiết phải lưu toàn bộ ma trận vào bộ nhớ (ví dụ dùngvector<vector<int>>
). Bạn có thể đọc từng phần tử, kiểm tra và cập nhật bộ đếm ngay lập tức, sau đó bỏ qua phần tử đó. Cách này giúp tiết kiệm bộ nhớ đáng kể. - Hãy sử dụng các hàm nhập/xuất chuẩn trong thư viện
iostream
của C++ (cin
,cout
). Để chương trình chạy nhanh hơn với dữ liệu lớn, bạn có thể thêm dòngios_base::sync_with_stdio(false); cin.tie(NULL);
ở đầu hàmmain
.
Comments