Chuyển tới nội dung chính

Bài tập C++: biến, rẽ nhánh, vòng lặp

Luyện nền tảng: khai báo biến, nhập/xuất, điều kiện và vòng lặp. Tự làm trước, bí thì mở Gợi ý.

Bài 1: chu vi và diện tích hình tròn

Nhập bán kính r (số thực), in ra chu vi và diện tích hình tròn.

Gợi ý

Dùng double r;cin >> r;. Chu vi 2 * 3.14159 * r, diện tích 3.14159 * r * r. Chọn kiểu double để giữ phần thập phân. Xem lại bài Biến, kiểu và nhập/xuất.

Bài 2: chẵn hay lẻ

Nhập một số nguyên, in ra "Chan" nếu chẵn, "Le" nếu lẻ.

Gợi ý

Phép chia lấy dư: n % 2 == 0 thì chẵn. Dùng if/else. Xem lại bài Rẽ nhánh.

Bài 3: xếp loại điểm

Nhập điểm trong khoảng [0, 10], in xếp loại: từ 8 trở lên "Gioi", từ 6.5 "Kha", từ 5 "Trung binh", còn lại "Yeu".

Gợi ý

Dùng chuỗi if / else if / else, kiểm tra từ ngưỡng cao xuống thấp. Nhánh đúng đầu tiên sẽ chạy, các nhánh sau bỏ qua. Xem lại bài Rẽ nhánh.

Bài 4: tổng từ 1 đến n

Nhập số nguyên dương n, tính tổng 1 + 2 + ... + n.

Gợi ý

Khởi tạo tong = 0 trước vòng lặp, rồi for (int i = 1; i <= n; i++) tong += i;. Xem lại bài Vòng lặp.

Bài 5: giai thừa

Nhập n, tính n! = 1 * 2 * ... * n.

Gợi ý

Giống tổng nhưng dùng phép nhân, và biến tích phải khởi tạo bằng 1 (không phải 0). Cẩn thận n! lớn rất nhanh, có thể dùng long long. Xem lại bài Vòng lặp.

Bài 6: bảng cửu chương

Nhập một số k từ 1 đến 9, in bảng cửu chương của nó (k x 1 đến k x 10).

Gợi ý

Một vòng for (int i = 1; i <= 10; i++) in ra k, dấu nhân, i, dấu bằng, k * i. Xem lại bài Vòng lặp.

Bài 7: đếm số chữ số

Nhập một số nguyên dương n, đếm xem nó có bao nhiêu chữ số (ví dụ 2025 có 4 chữ số).

Gợi ý

Khởi tạo biến đếm bằng 0, rồi lặp chia n /= 10 cho tới khi n bằng 0, mỗi lần chia tăng biến đếm lên 1. Với phép chia số nguyên, 2025 / 10 cho 202. Xem lại bài Vòng lặp.

Bài 8: giá trị lớn nhất của dãy

Nhập số nguyên dương n, rồi nhập tiếp n số nguyên, in ra số lớn nhất trong dãy.

Gợi ý

Đọc số đầu tiên và gán vào biến maxV, rồi trong vòng lặp đọc các số còn lại, mỗi khi số mới lớn hơn maxV thì cập nhật. Đừng khởi tạo maxV = 0 vì dãy có thể toàn số âm. Xem lại các bài Vòng lặpRẽ nhánh.

Bài 9: kiểm tra năm nhuận

Nhập một năm, in "Nhuan" nếu là năm nhuận, ngược lại in "Khong". Năm nhuận là năm chia hết cho 4 nhưng không chia hết cho 100, hoặc chia hết cho 400.

Gợi ý

Ghép điều kiện bằng toán tử logic: (nam % 4 == 0 && nam % 100 != 0) || nam % 400 == 0. Dùng dấu ngoặc để nhóm cho rõ thứ tự. Xem lại bài Rẽ nhánh.

Bài 10: thống kê một dãy số

Nhập số nguyên dương n, rồi nhập n số nguyên vào một vector, in ra giá trị nhỏ nhất, lớn nhất và trung bình cộng của dãy.

Gợi ý

Đọc dữ liệu vào vector rồi duyệt một lượt để vừa tìm min, max, vừa cộng tổng. Ép tổng sang double trước khi chia cho n để giữ phần thập phân.

#include <iostream>
#include <vector>
using namespace std;

int main() {
int n;
cin >> n;
vector<int> a(n);
for (int i = 0; i < n; i++) cin >> a[i];
int mn = a[0], mx = a[0];
long long sum = 0;
for (int x : a) { // read-only copy is fine here
if (x < mn) mn = x;
if (x > mx) mx = x;
sum += x;
}
double avg = (double)sum / n; // cast to keep decimals
cout << mn << " " << mx << " " << avg << "\n";
return 0;
}

Xem lại bài Mảng và vector.

Bài 11: đếm số chẵn và số lẻ

Nhập n số nguyên, đếm xem có bao nhiêu số chẵn và bao nhiêu số lẻ, in ra hai con số.

Gợi ý

Giữ hai biến đếm, mỗi lần đọc một số thì kiểm tra x % 2 == 0 để tăng đúng biến đếm. Không cần lưu cả dãy nếu chỉ cần đếm.

#include <iostream>
using namespace std;

int main() {
int n;
cin >> n;
int chan = 0, le = 0;
for (int i = 0; i < n; i++) {
int x;
cin >> x;
if (x % 2 == 0) chan++;
else le++;
}
cout << chan << " " << le << "\n";
return 0;
}

Xem lại bài Vòng lặp.

Bài 12: đảo ngược một chuỗi

Nhập một dòng văn bản (có thể có dấu cách), in ra chuỗi đó theo thứ tự đảo ngược.

Gợi ý

Dùng getline(cin, s) để đọc cả dòng kể cả dấu cách. Có thể đảo tại chỗ bằng reverse(s.begin(), s.end()), hoặc duyệt từ cuối chuỗi về đầu và in từng ký tự.

#include <iostream>
#include <string>
#include <algorithm>
using namespace std;

int main() {
string s;
getline(cin, s);
reverse(s.begin(), s.end()); // reverse the string in place
cout << s << "\n";
return 0;
}

Xem lại bài Biến, kiểu và nhập/xuất.

Bài 13: lũy thừa bằng đệ quy

Viết hàm đệ quy luyThua(co, mu) tính comu (với mu nguyên không âm), rồi gọi nó trong main.

Gợi ý

Hàm đệ quy cần một trường hợp cơ sở để dừng: mu == 0 thì trả về 1. Trường hợp còn lại trả về co nhân với luyThua(co, mu - 1), mỗi lần gọi mu giảm đi một cho tới khi chạm cơ sở.

#include <iostream>
using namespace std;

long long luyThua(int co, int mu) {
if (mu == 0) return 1; // base case
return co * luyThua(co, mu - 1); // recursive step
}

int main() {
int co, mu;
cin >> co >> mu;
cout << luyThua(co, mu) << "\n";
return 0;
}

Xem lại bài Hàm.

Bài 14: tính tổng vector qua tham chiếu hằng

Viết hàm nhận một vector<int> và trả về tổng các phần tử, nhưng nhận tham số bằng tham chiếu hằng để không sao chép cả vector khi gọi.

Gợi ý

Với const vector<int>& v, hàm nhìn thẳng vào vector gốc nên không tốn chi phí sao chép, mà từ khóa const vẫn bảo đảm hàm không lỡ tay sửa dữ liệu. Bên trong chỉ cần cộng dồn các phần tử.

#include <iostream>
#include <vector>
using namespace std;

// const reference: no copy, and cannot modify v
long long tong(const vector<int>& v) {
long long s = 0;
for (int x : v) s += x;
return s;
}

int main() {
vector<int> a = {1, 2, 3, 4, 5};
cout << tong(a) << "\n";
return 0;
}

Xem lại bài Con trỏ và tham chiếu.

Câu hỏi tự kiểm

Kiểm tra nhanh0/4 đúngchưa trả lời
  1. 1Muốn giữ phần thập phân khi tính diện tích hình tròn, nên khai báo bán kính kiểu nào?
  2. 2Biểu thức nào cho kết quả đúng khi kiểm tra n là số chẵn?
  3. 3Khi tính tích (giai thừa) bằng vòng lặp, biến tích phải khởi tạo bằng mấy?
  4. 4Trong chuỗi if / else if / else kiểm tra ngưỡng, vì sao nên xét từ ngưỡng cao xuống thấp?