Một vài lỗi sai khi code C++ trong các kì thi HSG Tin học (phần 2)
Tiếp nối phần trước, ta tiếp tục điểm qua một vài lỗi sai thường gặp khi code C++ nhé.
6. Map operator []
#include <bits/stdc++.h> using namespace std; int main(){ map<int, int> m; vector<int> v = {1, 7, 4, 3, 2, 1}; for (auto &x : v) m[x]++; for (int i = 1; i <= 10; i++){ cout << m[i] << " "; } cout << endl; cout << m.size() << endl; }
Bạn đang mong muốn đoạn code này sẽ cho ra kết quả
2 1 1 1 0 0 1 0 0 0 5
Tuy nhiên thực chất kết quả là
2 1 1 1 0 0 1 0 0 0 10
Điều này xảy ra bởi khi sử dụng operator [] trong map, dù key không tồn tại trong map thì vẫn sẽ thêm key mới vào. Ta không muốn điều này xảy ra trong hầu hết trường hợp, điều này có thể sẽ gây tràn bộ nhớ không mong muốn.
Để khắc phục, trước tiên ta sẽ kiểm tra xem liệu key có tồn tại trong map không rồi mới sử dụng operator []
#include <bits/stdc++.h> using namespace std; int main(){ map<int, int> m; vector<int> v = {1, 7, 4, 3, 2, 1}; for (auto &x : v) m[x]++; for (int i = 1; i <= 10; i++){ if (m.find(i) != m.end()) cout << m[i] << " "; else cout << 0 << " "; } cout << endl; cout << m.size() << endl; }
7. pow
Ta không bao giờ nên sử dụng hàm pow để tính lũy thừa cho cơ số nguyên. Hàm pow thực chất nhận và trả về kiểu dữ liệu double nên đôi khi có thể gây sai số. Vì vậy, thay thì sử dụng hàm pow, ta nên sử dụng for để tìm ra lũy thừa.
8. sqrt
Tương tự hàm pow, hàm sqrt cũng có thể gây sai số. Với đa số trường hợp cần sử dụng hàm này, ta nên dùng sqrtl bởi độ chính xác cao hơn.
Đây là một cách tương đối an toàn để tìm sqrt
#include <bits/stdc++.h> using namespace std; int main(){ long long x = 1e18; long long v = sqrtl(x); while (v * v < x) v++; while (v * v > x) v--; cout << v << endl; }
9. size overflow
Tiếp tục chạy thử đoạn code sau
#include <bits/stdc++.h> using namespace std; int main(){ vector<int> v = {1}; cout << v.size() - 2 << endl; }
Đáp án lẽ ra là -1, nhưng cũng giống như các trường hợp tràn số ở trên, kết quả lại cho ra một số nguyên dương có vẻ ngẫu nhiên và không liên quan.
Lí do xảy ra tràn số là vì hàm size() sẽ trả về kiểu dữ liệu unsigned nên không thể mang giá trị âm. Điều này cực kì nguy hiểm nếu bạn sử dụng đoạn code trên trong vòng for, bởi nó sẽ khiến đoạn code chạy vô hạn. Các khắc phục dễ nhất là ép kiểu.
#include <bits/stdc++.h> using namespace std; int main(){ vector<int> v = {1}; cout << (int)v.size() - 2 << endl; }
10. multiset erase
Ở đây, ta muốn xóa đi một phần tử có giá trị là \(3\).
#include <bits/stdc++.h> using namespace std; int main(){ multiset<int> v = {1, 1, 2, 3, 3, 3, 4, 5, 5}; v.erase(3); for (auto &x : v) cout << x << " "; }
Tuy nhiên với đoạn code trên, ta đã xóa đi tất cả các phần tử có giá trị là \(3\). Lí do là vì nếu sử dụng hàm erase trong multiset với tham số là một giá trị, nó sẽ xóa đi tất cả các phần tử mang giá trị đó. Còn nếu sử dụng hàm erase với tham số là một iterator, nó sẽ chỉ xóa phần tử tại iterator đó.
#include <bits/stdc++.h> using namespace std; int main(){ multiset<int> v = {1, 1, 2, 3, 3, 3, 4, 5, 5}; v.erase(v.find(3)); for (auto &x : v) cout << x << " "; }
Lời kết
Trong 2 phần của bài viết này, chúng ta đã điểm qua một số lỗi thường gặp khi code C++ trong các kì thi HSG Tin học. Những sai sót này có thể xuất hiện do thiếu kiến thức cơ bản, không kỹ lưỡng trong quá trình viết code, hoặc do hậu quả của áp lực trong cuộc thi.
Để tránh những lỗi không đáng có và nâng cao hiệu quả trong lập trình, học sinh cần thực hành thường xuyên và hiểu rõ các khái niệm cơ bản của ngôn ngữ C++. Ngoài ra, việc đọc và hiểu đề bài một cách kỹ lưỡng, thiết kế thuật toán logic trước khi viết code, và thử nghiệm kỹ lưỡng trước khi nộp bài cũng rất quan trọng.
Cuối cùng, hãy luôn luôn giữ tinh thần tự tin và kiên nhẫn. Các kì thi HSG Tin học không chỉ đo đạc khả năng lập trình của bạn mà còn rèn luyện kỹ năng tư duy logic và sự sáng tạo. Và dù kết quả như thế nào, quan trọng nhất là bạn đã cống hiến hết mình và rút ra những bài học bổ ích từ mỗi kỳ thi.
Chúc các bạn thành công trong các kì thi sắp tới và luôn trân trọng chặng đường học tập, không chỉ trong lập trình mà còn trong cuộc sống!
Xem thêm tại: https://www.facebook.com/codedreamedu và https://codedream.edu.vn/hoc-thuat-toan/


