Xử lý chi tiết lập trình thi đấu: Từ vòng lặp đến STL

1. Xử lý khoảng trắng và xuống dòng trong vòng lặp in đa dòng

Khi cần in ra nhiều dòng số, mỗi dòng chứa dãy số từ 1 đến n, ta phải xử lý riêng biệt ký tự ngăn cách (khoảng trắng) và ký tự kết thúc dòng (xuống dòng).

Xem mã nguồn
#include <cstdio>

int main() {
    int limit;
    scanf("%d", &limit);
    for (int row = 0; row < limit; ++row) {
        for (int col = 1; col <= limit; ++col) {
            printf("%d", col);
            if (col != limit) printf(" ");
            else printf("\n");
        }
    }
    return 0;
}

2. Các hàm tiện ích trong thư viện algorithm

  • swap(x, y): Hoán đổi giá trị hai biến.
  • sort(begin, end): Sắp xếp đoạn [begin, end), mặc định dùng quicksort.
  • reverse(begin, end): Đảo ngược thứ tự phần tử trong đoạn [begin, end).

3. Sự khác biệt giữa string C++ và mảng char

Đầu vào/ra:

  • string: Chỉ dùng với cin/cout.
  • char[]: Dùng được cả scanf/printf, gets/puts.

Chuyển đổi qua lại:

Xem mã nguồn
// string → char[]
std::string text = "hello";
const char* cstr = text.c_str();

// char[] → string
char buffer[100];
scanf("%s", buffer);
std::string str = buffer;

So sánh và nối chuỗi:

Xem mã nguồn
// So sánh string
if (str1 > str2) { ... }

// So sánh char[]
if (strcmp(arr1, arr2) > 0) { ... }

// Nối string
result = str1 + str2;

// Nối char[]
strcat(dest, src);

4. Ký tự khoảng trắng trước %c trong scanf

Thêm dấu cách trước %c giúp bỏ qua các ký tự trắng (khoảng trắng, tab, newline) còn sót lại trong bộ đệm đầu vào.

5. Điều kiện while với scanf

while(scanf("%d%d", &a, &b) == 2 && a && b) chỉ tiếp tục khi đọc thành công 2 số nguyên và cả hai đều khác 0.

6. sscanf — phân tích chuỗi theo định dạng

Xem mã nguồn
#include <iostream>
#include <cstdio>
using namespace std;

int main() {
    char input[100];
    cin.getline(input, 100);
    int x, y, z;
    if (sscanf(input, "%d > %d", &x, &y) == 2) {
        cout << (x > y ? "Đúng" : "Sai");
    } else if (sscanf(input, "%d = %d + %d", &x, &y, &z) == 3) {
        cout << (x == y + z ? "Đúng" : "Sai");
    } else {
        cout << "Không rõ";
    }
    return 0;
}

7. Toán tử -> và . trong struct

  • .: Truy cập thành viên của biến struct.
  • ->: Truy cập thành viên thông qua con trỏ struct.

8. Sử dụng getchar() để xóa bộ đệm

Dùng getchar() sau scanf() để loại bỏ ký tự newline thừa trước khi gọi getline() hoặc gets().

9. So sánh số thực — tránh sai số dấu phẩy động

Xem mã nguồn
#include <cmath>
const double EPS = 1e-8;

bool isEqual(double a, double b) {
    return abs(a - b) < EPS;
}

bool isGreater(double a, double b) {
    return a - b > EPS;
}

10. Xử lý nhiều test case bằng while

Xem mã nguồn
int cases;
scanf("%d", &cases);
while (cases--) {
    int a, b;
    scanf("%d %d", &a, &b);
    printf("%d\n", a + b);
}

11. Tổng quan về STL

vector

  • push_back(), insert(), erase()
  • Không có find() — dùng std::find(v.begin(), v.end(), val)

set

  • Tự động sắp xếp và loại bỏ trùng lặp.
  • Duyệt bằng iterator: for (auto it = s.begin(); it != s.end(); ++it)

string

  • length(), clear(), substr(), find(), replace()
  • Hỗ trợ toán tử +, ==, >, <

map

  • Lưu trữ cặp key-value.
  • Truy cập: mp[key], kiểm tra tồn tại: mp.find(key) != mp.end()

queue & stack

  • Queue: push(), front(), pop()
  • Stack: push(), top(), pop()

priority_queue

  • Mặc định là max-heap: priority_queue<int>
  • Min-heap: priority_queue<int, vector<int>, greater<int>>

pair

Xem mã nguồn
pair<string, int> item = make_pair("apple", 5);
cout << item.first << " " << item.second;

algorithm

  • max(), min(), abs() (chỉ cho int), fabs() (cho float/double)
  • reverse(), next_permutation(), fill(), sort()
  • lower_bound(), upper_bound(): Tìm kiếm nhị phân trong dãy đã sắp.

Thẻ: C++ STL competitive-programming

Đăng vào ngày 21 tháng 6 lúc 21:49