[Lập trình C] Bài tập lập trình C 1

Posted on January 2nd, 2021

Bài viết này giới thiệu với bạn một số bài tập lập trình C từ cơ bản đến nâng cao để ôn tập những kiến thức về: Flowchart - sơ đồ thuật toán, biến và kiểu dữ liệu, toán tử và biểu thức, nhập xuất dữ liệu, điều kiện rẽ nhánh, vòng lặp - loop. Bạn chú ý áp dụng những kiến thức đã học để giải các bài toán sau.

Bài 1

Nhập vào số nguyên N (0 <= N <= 10). Tính N giai thừa (N!).

Phân tích bài toán

  • N! được tính theo công thức là:
    • Nếu N = 0 thì N! = 1
    • Nếu N > 0 thì N! = N _ (N - 1) _ (N -2) *...1
  • Do đó, nếu nhập N = 0 thì in ra luôn kết quả 0! = 1
  • Trường hợp còn lại, sử dụng vòng lặp for từ N về 1 để tính dồn tích của các số để ra N!

Code

#include <stdio.h>

int main() {
	int N, giaiThua, i;

	printf("Nhap N: ");
	scanf("%d", &N);

	if (N < 0 || N > 10) {
		printf("Ban da nhap sai");
	}
	else if (N == 0) {
		printf("Ket qua 0! la: 1");
	}
	else {
		giaiThua = 1;
		for (i = N; i >= 1; i--) {
			giaiThua *= i;
		}
		printf("Ket qua %d! la: %d", N, giaiThua);
	}

	return 0;
}

Bài 2

Nhập vào số tự nhiên N (N <= 1000000000). Kiểm tra xem N có phải là số chính phương hay không.

Phân tích bài toán

  • Số chính phương là số tự nhiên có căn bậc hai là số tự nhiên, hay nói cách khác là nó được viết dưới dạng i^2 với i cũng là số tự nhiên.
  • Do đó, để kiểm tra xem 1 số có phải là số chính phương hay không ta có thể sử dụng 1 vòng lặp for với i chạy từ 1 đến N để tính i^2.
    • Nếu tồn tại số i thỏa mãn i^2 = N thì suy ra N là số chính phương
    • Nếu không tồn tại số i thỏa mãn i^2 = N thì N không phải số chính phương
  • Tuy nhiên, có một chú ý ở đây là ta không cần cho i chạy từ 1 đến N mà thực chất chỉ cần cho i chạy từ 1 đến giá trị mà i^2 > N là dừng lại. Vì lúc đó i^2 đã lớn hơn N rồi nên nếu i tiếp tục tăng, giá trị i^2 càng lớn hơn N.

Code

#include <stdio.h>

int main() {
	int N, i, laSoChinhPhuong;

	printf("Nhap N: ");
	scanf("%d", &N);

	if (N < 1 || N > 1000000000) {
		printf("Ban da nhap sai");
	} else {
		laSoChinhPhuong = 0;
		for (i = 1; i*i <= N; i++) {
			if (i*i == N) {
				laSoChinhPhuong = 1;
				break;
			}
		}
		if (laSoChinhPhuong)
			printf("%d la so chinh phuong", N);
		else
			printf("%d khong la so chinh phuong", N);
	}

	return 0;
}

Bài 3

Nhập vào số tự nhiên N (N <= 100). Thực hiện các yêu cầu sau:

  • In ra màn hình tất cả các ước số của N
  • Tính tổng giá trị các ước số lẻ của N
  • Đếm số lượng các ước số chẵn của N

Phân tích bài toán

  • Số K được gọi là ước số của N nếu N chia hết cho K, hay nói cách khác là số dư của N cho K bằng 0
  • Để in ra tất cả các ước số của N ta có thể sử dụng vòng lặp for với i chạy từ 1 đến N. Tại mỗi bước, kiểm tra số dư r của N cho i, nếu r = 0 thì i chính là ước số của N. Suy ra in ra i.
  • Để tính tổng giá trị các ước số lẻ, ta cần kiểm tra thêm điều kiện i phải là số lẻ. Tương tự để đếm số lượng các ước số chẵn, ta cần thêm điều kiện i phải là số chẵn.
  • Để kiểm tra 1 số i là số chẵn, ta kiểm tra số dư của i cho 2. Nếu số dư đó bằng 0 thì i là số chẵn, ngược lại i là số lẻ.

Code

#include <stdio.h>

int main() {
	int N, i, tongUocLe = 0, soLuongUocChan = 0;

	printf("Nhap N: ");
	scanf("%d", &N);

	if (N < 1 || N > 100) {
		printf("Ban da nhap sai");
	} else {
		// In ra man hinh tat ca uoc so cua N
		printf("Tat ca cac uoc so la: ");
		for (i = 1; i <= N; i += 1) {
			if (N % i == 0) printf("%d ", i);
		}
		printf("\n");

		// Tinh tong gia tri cac uoc so le cua N
		for (i = 1; i <= N; i += 1) {
			if (N % i == 0 && i % 2 == 1) tongUocLe += i;
		}
		printf("Tong gia tri cac uoc so le la: %d\n", tongUocLe);

		// Dem so luong gia tri cac uoc so chan cua N
		for (i = 1; i <= N; i += 1) {
			if (N % i == 0 && i % 2 == 0) soLuongUocChan += 1;
		}
		printf("So luong cac uoc so chan la: %d\n", soLuongUocChan);
	}

	return 0;
}

Bài 4

Nhập vào 2 số tự nhiên a và b (a, b <= 1000000). Tìm ước chung lớn nhất của 2 số a và b.

Phân tích bài toán

  • Số K được gọi là ước số của N nếu N chia hết cho K, hay nói cách khác là số dư của N cho K bằng 0
  • Ước số lớn nhất của 1 số là chính số đó. Vì vậy, để tìm ước số chung lớn nhất của 2 số ta có thể làm như sau:
    • Kiểm tra và tìm ra số nhỏ hơn trong 2 số, giả sử là M
    • Dùng vòng lặp for với i chạy từ M về 1 để kiểm tra đến khi nào gặp 1 số i mà cả 2 số a và b đều chia hết thì i chính là ước số chung lớn nhất của a và b.

Code

#include <stdio.h>

int main() {
	int a, b, Min, i, USCLN;

	printf("Nhap a: ");
	scanf("%d", &a);

	printf("Nhap b: ");
	scanf("%d", &b);

	if (a < 1 || a > 1000000 || b < 1 || b > 1000000) {
		printf("Ban da nhap sai");
	} else {
		// Tim min cua 2 so
		Min = a < b ? a : b;

		// Tim USCLN
		for (i = Min; i >= 1; i--) {
			if (a % i == 0 && b % i == 0) {
				USCLN = i;
				break;
			}
		}
		printf("USCLN cua %d va %d la: %d", a, b, USCLN);
	}

	return 0;
}

Bài 5

Nhập vào số tự nhiên N (N <= 50000), tính giá trị của biểu thức:

S(N) = 1^2 + 2^2 + ... + N^2

Chú ý:

  • Toán tử ^ hiểu là toán tử mũ trong toán học, không phải toán tử XOR bit
  • Sử dụng kiến thực lập trình đã học, không sử dụng hàm có sẵn, không dùng toán học để chuyển đổi về biểu thức rút gọn

Phân tích bài toán

  • Để tính giá trị của biểu thức trên, ta chỉ cần dùng 1 vòng lặp for với i chạy từ 1 đến N, với mỗi giá trị của i ta tính i*i rồi cộng dồn vào giá trị tổng.
  • Chỉ có 1 chú ý ở đây là N <= 50000, mà 50000*50000=2500000000. Do đó, ta không thể dùng biến kiểu int để lưu giá trị của tổng mà phải dùng kiểu long long int.

Code

#include <stdio.h>

int main() {
	int i, N;
	long long int tong = 0;

	printf("Nhap N: ");
	scanf("%d", &N);

	if (N < 1 || N > 50000) {
		printf("Ban da nhap sai");
	} else {
		for (i = 1; i <= N; i += 1) {
			tong += i*i;
		}
		printf("Tong la: %lld", tong);
	}

	return 0;
}

Bài 6

Nhập vào số tự nhiên N (N <= 50000), tính giá trị của biểu thức:

S(N) = 1 + 1/3 + + 1/5 + ... + 1/(2N + 1)

Chú ý:

  • Các phép chia bên trên được hiểu là phép chia toán học (lấy giá trị chính xác), không phải phép chia nguyên.
  • Kết quả cuối cùng làm tròn đến 4 chữ số sau dấu phẩy
  • Sử dụng kiến thực lập trình đã học, không sử dụng hàm có sẵn, không dùng toán học để chuyển đổi về biểu thức rút gọn

Phân tích bài toán

  • Để tính giá trị biểu thức, ta dùng vòng lặp for với i chạy từ 0 đến N, với mỗi giá trị của i ta tính 1/(2*i + 1) rồi cộng dồn vào biến lưu kết quả.
  • Chú ý:
    • Trong toán học, 1/(2*i + 1) sẽ cho kết quả là 1 số thực
    • Trong lập trình, 1/(2*i + 1) sẽ cho kết quả là 1 số nguyên. Vì vậy, ta cần phải ép kiểu tử số hoặc mẫu số của phép chia về số thực để thu được kết quả như mong muốn.
    • Ngoài ra, để hiển thị kết quả làm tròn 4 chữ số thập phân, ta dùng format %.4f

Code

#include <stdio.h>

int main() {
	int i, N;
	float tong = 0;

	printf("Nhap N: ");
	scanf("%d", &N);

	if (N < 1 || N > 50000) {
		printf("Ban da nhap sai");
	} else {
		for (i = 0; i <= N; i += 1) {
			tong += 1.0 / (2 * i + 1);
		}
		printf("Tong la: %.4f", tong);
	}

	return 0;
}

Bài 7

Nhập vào số tự nhiên N (N <= 10), tính giá trị của biểu thức:

S(N) = 2^1 + 2^2 + ... + 2^N

Chú ý:

  • Toán tử ^ hiểu là toán tử mũ trong toán học, không phải toán tử XOR bit
  • Sử dụng kiến thực lập trình đã học, không sử dụng hàm có sẵn, không dùng toán học để chuyển đổi về biểu thức rút gọn

Phân tích bài toán

  • Để tính giá trị biểu thức, ta cần dùng 2 vòng lặp for lồng nhau
    • Vòng lặp for bên ngoài sẽ có i chạy từ 1 đến N để cộng tổng các giá trị 2^j lại với nhau
    • Vòng lặp for bên trong sẽ có j chạy từ 1 đến i để tính giá trị 2^j

Code

#include <stdio.h>

int main() {
	int i, j, N, temp, tong = 0;

	printf("Nhap N: ");
	scanf("%d", &N);

	if (N < 1 || N > 10) {
		printf("Ban da nhap sai");
	} else {
		// Cong tong: 2^1 + 2^2 + ... + 2^N
		for (i = 1; i <= N; i += 1) {
			temp = 1;
			// Tinh gia tri: 2^i
			for (j = 1; j <= i; j += 1) {
				temp *= 2;
			}
			tong += temp;
		}
		printf("Tong la: %d", tong);
	}

	return 0;
}

Bài 8

Viết chương trình máy tính đơn giản thỏa mãn những yêu cầu sau:

Ban đầu hiển thị ra menu:

Menu:
0. Thoat chuong trinh
1. Tinh tong 2 so thuc: a + b
2. Tinh hieu 2 so thuc: a - b
3. Tinh tich 2 so thuc: a * b
4. Tinh thuong 2 so thuc: a / b

Ban muon lam gi tiep theo:

Khi người dùng nhập vào số với giá trị khác số 0, 1, 2, 3, 4 thì hiển thị Ban da nhap sai rồi hiển thị Ban muon lam gi tiep theo: để yêu cầu người dùng nhập lại.

Khi người dùng nhập vào số 0 thì thoát chương trình.

Khi người dùng nhập vào 1 trong các số 1, 2, 3, 4 (giả sử là số t) thì hiển thị Nhap vao gia tri 2 so: để người dùng lần lượt nhập vào 2 số a và b.

  • Nếu t = 1 thì tính tổng 2 số (giả sử là tong) rồi hiển thị Tong 2 so la: tong
  • Nếu t = 2 thì tính hiệu 2 số (giả sử là hieu) rồi hiển thị Hieu 2 so la: hieu
  • Nếu t = 3 thì tính tích 2 số (giả sử là tich) rồi hiển thị Tich 2 so la: tich
  • Nếu t = 4 thì tính thương 2 số (giả sử là thuong) rồi hiển thị Thuong 2 so la: thuong. Chú ý: trong trường hợp này, nếu người dùng nhập vào giá trị của b = 0 thì hiển thị Thuong 2 so la: vo cung

Sau khi thực hiện mỗi lệnh thì lại hiển thị menu như ban đầu.

#include <stdio.h>

int main()
{
	float a, b;
	int lenh, inMenu = 1;
	int nhapHopLe;

	while (1) {
		// In ra menu
		if (inMenu == 1) {
			printf("\nMenu:\n");
			printf("0. Thoat chuong trinh\n");
			printf("1. Tinh tong 2 so thuc: a + b\n");
			printf("2. Tinh hieu 2 so thuc: a - b\n");
			printf("3. Tinh tich 2 so thuc: a * b\n");
			printf("4. Tinh thuong 2 so thuc: a / b\n");
		}
		printf("\nBan muon lam gi tiep theo: ");

		// Nhap lenh
		nhapHopLe = scanf("%d", &lenh);
		if (nhapHopLe != 1) {
			printf("\nBan da nhap sai");
			inMenu = 0;
			fflush(stdin);
			continue;
		}

		// Nhap lenh va kiem tra lenh khong hop le
		if (lenh != 0 && lenh != 1 && lenh != 2 && lenh != 3 && lenh != 4) {
			printf("\nBan da nhap sai");
			inMenu = 0;
			continue;
		}

		// Kiem tra dieu kien thoat chuong trinh
		if (lenh == 0) {
			break;
		}

		printf("Nhap vao gia tri 2 so: ");

		// Nhap va kiem tra a
		nhapHopLe = scanf("%f", &a);
		if (nhapHopLe != 1) {
			printf("\nBan da nhap sai");
			inMenu = 0;
			fflush(stdin);
			continue;
		}

		// Nhap va kiem tra b
		nhapHopLe = scanf("%f", &b);
		if (nhapHopLe != 1) {
			printf("\nBan da nhap sai");
			inMenu = 0;
			fflush(stdin);
			continue;
		}

		// Tinh ket qua
		if (lenh == 1) {
			printf("Tong 2 so la: %g", a + b);
		} else if (lenh == 2) {
			printf("Hieu 2 so la: %g", a - b);
		} else if (lenh == 3) {
			printf("Tich 2 so la: %g", a * b);
		} else if (b == 0) {
			printf("Thuong 2 so la: vo cung");
		} else {
			printf("Thuong 2 so la: %g", a / b);
		}

		printf("\n");
		inMenu = 1;
	}

	return 0;
}