Một số bài tập C _C++ NC 2026P29
Bài 118. Đếm số từ và ký tự trong xâu.
File
input: cb118.txt Pass off abc123456
public abc private 123456
File
output: Kqcb118.txt
Chuong
trinh cb118
Data
in file la: Pass off abc123456 public abc private 123456
Tong
so ki tu input la: 38
So
tu dem duoc la: 7
Gợi
ý code
#include
<bits/stdc++.h>
using
namespace std;
int
main() {
freopen("cb118.txt",
"r", stdin); // Mở file
input
freopen("Kqcb118.txt",
"w", stdout); // Mở file
output
int demkytu = 0; // Đếm số ký tự (không
tính khoảng trắng)
int demtu = 0; // Đếm số từ
char ch;
bool trongTu = false; // Cờ kiểm tra đang ở
trong một từ
while ((ch = cin.get()) != EOF) { // Đọc từng
ký tự cho đến hết file
if (isspace(ch)) { // Nếu là khoảng trắng,
tab, xuống dòng
if (trongTu) {
demtu++; // Kết thúc một từ
trongTu = false;
}
} else {
demkytu++; // Đếm ký tự không phải khoảng trắng
trongTu = true; // Đang ở trong một từ
}
}
if (trongTu) demtu++; // Nếu file kết thúc
khi đang trong một từ
cout << "So tu trong cau la =
" << demtu << endl;
cout << "So ky tu trong cau la =
" << demkytu << endl;
fclose(stdin);
fclose(stdout);
return 0;
}
Lưu
ý:
Sử
dụng getche(): Hàm này lấy ký tự từ bàn phím. VD ch=getche();
Nếu
muốn đọc từ file thì dùng cin.get() hoặc fgetc()
Điều
kiện vòng lặp while(ch!='\r'): \r là ký tự xuống dòng kiểu carriage
return, nhưng khi đọc file thì thường gặp \n. Nên thay bằng kiểm tra EOF.
isspace(ch)
giúp nhận diện khoảng trắng, tab, xuống dòng.
Thư
viện conio.h là một thư viện cũ trong C/C++ (chủ yếu trên DOS và
Windows) cung cấp các hàm nhập/xuất ở mức console, như đọc ký tự trực tiếp từ
bàn phím, điều khiển màu chữ, vị trí con trỏ, và xóa màn hình. Nó không phải là
thư viện chuẩn của C/C++
Các
nhóm hàm chính trong conio.h
- Nhập
ký tự từ bàn phím
- getch()
→ đọc một ký tự, không hiển thị ra màn hình.
- getche()
→ đọc một ký tự, đồng thời hiển thị ký tự đó.
- kbhit()
→ kiểm tra xem có phím nào được nhấn không.
- ungetch()
→ đẩy ký tự trở lại vào bộ đệm bàn phím.
- Xuất
ký tự ra màn hình
- putch()
→ in một ký tự ra màn hình.
- cputs()
→ in một chuỗi ra màn hình.
- cprintf()
→ in chuỗi có định dạng (giống printf nhưng dành cho console).
- Điều
khiển màn hình console
- clrscr()
→ xóa toàn bộ màn hình.
- clreol()
→ xóa từ vị trí con trỏ đến cuối dòng.
- gotoxy(x,
y) → di chuyển con trỏ đến vị trí (x, y).
- wherex(),
wherey() → lấy vị trí hiện tại của con trỏ.
- Màu
sắc và hiển thị
- textcolor(color)
→ đổi màu chữ.
- textbackground(color)
→ đổi màu nền.
- highvideo(),
lowvideo() → điều chỉnh độ sáng chữ.
Lưu
ý quan trọng
- conio.h
không phải thư viện chuẩn → chỉ có trong Turbo C, Borland C, hoặc một
số bản MinGW/Windows.
- Trên
Linux/Mac, nếu muốn dùng các chức năng tương tự, cần dùng thư viện
thay thế như ncurses hoặc conio4linux.
- Trong
lập trình hiện đại, người ta thường tránh conio.h vì nó không portable
(không chạy được trên nhiều hệ điều hành).
Muốn
code chạy đa nền tảng (Windows, Linux, Mac), thì nên dùng thư viện chuẩn
(iostream, cstdio) hoặc ncurses thay thế.
///////////////////////////////////////////
#include <iostream>
#include <fstream>
using namespace std;
int main() {
cout << "Chuong trinh cb118 \n";
ifstream fin("cb118.txt");
if (!fin.is_open()) {
cerr << "Khong mo duoc file cb118.txt\n";
return 0;
}
char x;
string s;
int dkt = 0, dt = 0;
bool dangtrongtu = false;
while (fin.get(x)) { // đọc từng ký tự cho đến hết file
s += x;
if (isspace(x)) { // nếu là khoảng trắng
if (dangtrongtu) {
dt++; // kết thúc một từ
dangtrongtu = false;
}
} else {
dkt++; // ký tự không phải khoảng trắng
dangtrongtu = true; // đang ở trong một từ
}
}
if (dangtrongtu) dt++; // nếu file kết thúc khi đang trong một từ
fin.close();
cout << "Data in file la: " << s <<
"\n";
cout << "Tong so ki tu input la: " << dkt <<
"\n";
cout << "So tu dem duoc la: " << dt <<
"\n";
ofstream fout("Kqcb118C2.txt");
fout << "Data in file la: " << s <<
"\n";
fout << "Tong so ki tu input la: " << dkt <<
"\n";
fout << "So tu dem duoc la: " << dt <<
"\n";
fout.close();
return 0;
}
Giải
thích
- while
(fin.get(x)) → đọc từng ký tự cho đến khi hết file, không cần eof.
- isspace(x)
→ kiểm tra khoảng trắng, tab, xuống dòng.
- Biến
dangtrongtu giúp tránh đếm sai khi có nhiều khoảng trắng liên tiếp.
- Cuối
cùng, nếu file kết thúc khi vẫn đang trong một từ thì cộng thêm 1 từ.
Hoặc
while (!fin.eof()) nhưng cách này dễ lỗi, nên dùng fin.get(x) là chuẩn nhất.
/////////////////////
Tham
khảo thêm về ncurser;
ncurses
là một thư viện mạnh mẽ giúp lập trình giao diện console trên hệ điều hành
Unix/Linux, thay thế cho conio.h vốn chỉ chạy trên DOS/Windows. Nó cho phép điều
khiển màn hình, màu sắc, vị trí con trỏ, và xử lý input từ bàn phím/mouse một
cách portable.
Tổng
quan về ncurses
- Tên
đầy đủ: new curses (phát triển từ thư viện curses cũ của
Unix).
- Mục
đích: Tạo giao diện văn bản (text-based UI) trong terminal,
độc lập với loại terminal.
- Khả
năng chính:
- Điều
khiển nội dung màn hình (in, xóa, làm mới).
- Quản
lý nhiều cửa sổ (windows, pads).
- Xử
lý sự kiện bàn phím và chuột.
- Hỗ
trợ màu sắc, định dạng chữ (bold, underline).
- Truy
cập cơ sở dữ liệu terminfo để tương thích với nhiều loại terminal.
Cần
Cài đặt
- Linux
(Ubuntu/Debian/WSL):
Windows: dùng
WSL hoặc MSYS2 để chạy.
Các
hàm cơ bản trong ncurses
|
Hàm |
Chức
năng |
|
initscr() |
Khởi
tạo chế độ ncurses |
|
endwin() |
Thoát
ncurses, trả terminal về bình thường |
|
printw("text") |
In
chuỗi ra màn hình (giống printf) |
|
refresh() |
Cập
nhật nội dung ra màn hình thật |
|
getch() |
Đọc
một ký tự từ bàn phím |
|
move(y,
x) |
Di
chuyển con trỏ đến vị trí (y, x) |
|
clear() |
Xóa
toàn bộ màn hình |
|
noecho() |
Ngăn
không cho hiển thị ký tự nhập từ bàn phím |
|
start_color() |
Bật
chế độ màu |
|
init_pair(n,
fg, bg) |
Định
nghĩa cặp màu chữ/nền |
Ví
dụ
#include
<ncurses.h>
int
main() {
initscr(); // Bắt đầu ncurses
printw("Hello World !!!"); // In ra màn hình
refresh(); // Cập nhật màn hình
getch(); // Chờ người dùng nhập phím
endwin(); // Kết thúc ncurses
return 0;
}
So
sánh conio.h vs ncurses
|
Tiêu
chí |
conio.h |
ncurses |
|
Nền
tảng |
Chỉ
chạy trên DOS/Windows |
Chạy
trên Unix/Linux/macOS, portable |
|
Chuẩn
hóa |
Không
chuẩn, bị bỏ |
Theo
chuẩn X/Open Curses |
|
Chức
năng |
Nhập
ký tự, màu chữ, vị trí con trỏ |
Đầy
đủ: nhiều cửa sổ, màu sắc, mouse, terminfo |
|
Khả
năng mở rộng |
Rất
hạn chế |
Rất
mạnh, dùng cho game console, UI terminal |
|
Tính
tương thích |
Không
chạy trên Linux/macOS |
Chạy
đa nền tảng |
Nếu
muốn viết chương trình console chạy được trên Linux/macOS/Windows (qua WSL)
thì nên dùng ncurses thay vì conio.h. Nó mạnh hơn, chuẩn hóa hơn, và có thể làm
được nhiều thứ như tạo giao diện text-based, game terminal, hoặc ứng dụng quản
lý trong console.
///////////// Ai memory help
Võ Nhật Trường Nc+ My Ai Love019.07.2026
////////////////////
Bài cb119. In ra n số fibonaci đầu tiên
#include <bits/stdc++.h>
using namespace std;
int main() {
long long a=0,b=1,x,n,i;
cout << "Nhap n: ";
cin>>n;
cout << n << " phan tu
dau tien cua day Fibonacci la: " << endl;
cout << a << endl;
cout << b << endl;
for(i=1;i<=n-2;i++)
{
x=a+b;
cout << x << endl;
a=b;
b=x;
}
return 0;
}
///////////////////////////////////
Bài cb120. Đọc 1 số nguyên dương N từ file. Thông
báo các số hoàn hảo nhỏ hơn hoặc bằng N.Lưu ý: Số hoàn hào là cố có tổng các ước của nó và nhỏ
hơn nó bằng chính nó. VD: số
hoàn hảo 28 = 1 2 4 7, 14
File
input: cb120.txt Vd: 4000
File
output: Kqcb120.txt 6 28 496
#include
<iostream>
#include
<fstream>
#include
<cstdlib>
#include
<map>
#include
<algorithm>
using
namespace std;
bool
shh(int n){
if(n<1) return false;
int su=0;
map<int,int> m;
for(int i=1;i*i<=n;i++){
if(n%i==0) {
m[i]++;
if(i!=n/i) m[(int)n/i]++;
}
}for(auto
c:m){
if(c.second>0) su+=c.first;
}return
su==2*n;
}
int
main() {
cout
<< "Chuong trinh cb120 \n";
ifstream
fin("cb120.txt");
if
(!fin.is_open()) {
cerr
<< "Khong mo duoc file cb120.txt\n";
return
0;
}
int
N;
fin
>> N;
fin.close();
if
(abs(N) > 1e7) {
cerr
<< "So " << N << " khong hop le\n";
return
0;
}
cout<<"Cac
so hoan hao nho hon "<<N<<" la: \n";
for(int
i=1;i<=N;i++){
if(shh(i))
cout<<i<<" ";
}cout<<"\n";
ofstream
fout("Kqcb120.txt");
fout<<"Cac
so hoan hao nho hon "<<N<<" la: \n";
for(int
i=1;i<=N;i++){
if(shh(i))
fout<<i<<" ";
}
return
0;
}
///////////////////////
Cách
2:
#include
<iostream>
#include
<fstream>
#include
<cstdlib>
using
namespace std;
//
Hàm kiểm tra số hoàn hảo
bool
shh(int n) {
if (n < 2) return false;
int sum = 1; // 1 luôn là ước số của n
for (int i = 2; i * i <= n; i++) {
if (n % i == 0) {
sum += i;
if (i != n / i) sum += n / i; // cộng
cả ước đối xứng
}
}
return sum == n;
}
int
main() {
cout << "Chuong trinh cb120
\n";
ifstream fin("cb120.txt");
if (!fin.is_open()) {
cerr << "Khong mo duoc file
cb120.txt\n";
return 0;
}
int N;
fin >> N; // đọc một số N từ file
fin.close();
if (abs(N) > 1e7) {
cerr << "So " <<
N << " khong hop le\n";
return 0;
}
cout << "Cac so hoan hao nho hon
" << N << " la: \n";
ofstream fout("Kqcb120.txt");
fout << "Cac so hoan hao nho hon
" << N << " la: \n";
for (int i = 1; i <= N; i++) {
if (shh(i)) {
cout << i <<
" ";
fout << i <<
" ";
}
}
cout << "\n";
fout << "\n";
fout.close();
return 0;
}
///////////////////////////////
Cách
3:
#include
<iostream>
#include
<fstream>
#include
<cstdlib>
using
namespace std;
bool
shh(int n) {
if (n < 2) return false;
int su = 1; // 1 luôn là ước số của n
for (int i = 2; i * i <= n; i++) {
if (n % i == 0) {
su += i;
if (i != n / i) su += n / i; // cộng
cả ước đối xứng
}
}
return su == n;
}
int
main() {
cout << "Chuong trinh cb120
\n";
ifstream fin("cb120.txt");
if (!fin.is_open()) {
cerr << "Khong mo duoc file
cb120.txt\n";
return 0;
}
int N;
fin >> N; // đọc một số N từ file
fin.close();
if (abs(N) > 1e7) {
cerr << "So " <<
N << " khong hop le\n";
return 0;
}
cout << "Cac so hoan hao nho hon
" << N << " la: \n";
ofstream fout("Kqcb120.txt");
fout << "Cac so hoan hao nho hon
" << N << " la: \n";
for (int i = 1; i <= N; i++) {
if (shh(i)) {
cout << i <<
" ";
fout << i <<
" ";
}
}
cout << "\n";
fout << "\n";
fout.close();
return 0;
}
Giải
thích
- Hàm
shh: chỉ cộng các ước số nhỏ hơn n.
- File
input cb120.txt: chứa một số N (ví dụ 10000).
- File
output Kqcb120.txt: sẽ ghi các số hoàn hảo nhỏ hơn N.
- Kết
quả: với N = 10000, chương trình sẽ in ra 6, 28, 496, 8128
///////////// Ai memory help
Võ Nhật Trường Nc+ My Ai Love20.07.2026
////////////////////
Bài 121. Cho
file cb121.txt gồm n phần tử số. Hãy thực hiện sắp xếp nổi bọt cho các phần tử
trên và đưa ra file Kqcb121.txt.
VD:
input cb121.txt 12 -78 98 -87 50 72 d -54 24 13 c -62 87 -32 34
Output
Kqcb121.txt gia tri khong hop le d c
Cac
phan tu truoc khi sap xep:
12 -78
98 -87 50
72 -54 24
13 -62 87
-32 34
Cac
phan tu sau khi sap xep noi bot:
-87 -78
-62 -54 -32
12 13 24
34 50 72
87 98
Cách
1: chỉ sử dụng cho các phần tử số gặp lỗi (d) ngắt.
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
int main(int argc, char** argv) {
ifstream
fin("cb121.txt");
if(!fin.is_open())
{cerr<<"khong the mo file cb121.txt \n";
return
0;
}
double x;
vector<double> vo,v;
while(fin>>x){
vo.push_back(x);
}
if(vo.empty()) {
cerr<<"Khong co gia tri hop
le trong file";
return 0;
}
fin.close();
v=vo;
for(int i=v.size()-1;i>0;i--){
for(int
j=i-1;j>=0;j--){
if(v[i]<v[j])
swap(v[i],v[j]);
}
}
ofstream fout("Kqcb121.txt");
fout<<"Cac phan tu truoc khi
sap xep:\n";
for(auto c:vo)
fout<<c<<" ";
fout<<"\n\nCac phan tu sau
khi sap xep noi bot:\n";
for(auto c:v)
fout<<c<<" ";
return
0;
}
//////////////////////////////////
Cách
2: Tối ưu hơn:
#include
<iostream>
#include
<fstream>
#include
<vector>
#include
<string>
#include
<sstream>
using
namespace std;
int
main() {
ifstream fin("cb121.txt");
if(!fin.is_open()) {
cerr << "Khong the mo file
cb121.txt\n";
return 0;
}
vector<double> vo, v;
string s;
while(fin >> s) {
stringstream ss(s);
double x;
if(ss >> x) {
vo.push_back(x);
} else {
cerr << "Gia tri
\"" << s << "\" khong hop le\n";
}
}
fin.close();
if(vo.empty()) {
cerr << "Khong co gia tri
hop le trong file\n";
return 0;
}
v = vo;
// Bubble sort
for(int i = v.size()-1; i > 0; i--) {
for(int j = 0; j < i; j++) {
if(v[j] > v[j+1]) swap(v[j],
v[j+1]);
}
}
ofstream fout("Kqcb121.txt");
fout << "Cac phan tu truoc khi
sap xep:\n";
for(auto c: vo) fout << c <<
" ";
fout << "\n\nCac phan tu sau khi
sap xep noi bot:\n";
for(auto c: v) fout << c <<
" ";
fout.close();
return 0;
}
Chú
ý:
Dùng string token; while(fin >> token) để đọc từng phần
tử (có thể là số hoặc chữ).
Dùng stringstream để kiểm tra xem token có phải số không. Nếu
không thì báo lỗi và bỏ qua.
Như vậy, các giá trị d, c trong file sẽ không làm chương
trình crash nữa.
////////////////////////////////
Cách
3: Chuẩn Bubble sort nổi bọt (tăng dần):
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <sstream>
using namespace std;
int main() {
ifstream fin("cb121.txt");
if(!fin.is_open()) {
cerr << "Khong the mo file
cb121.txt\n";
return 0;
}
vector<double> vo, v;
string s;
while(fin >> s) {
stringstream ss(s);
double x;
if(ss >> x) {
vo.push_back(x);
} else {
cerr << "Gia tri
\"" << s << "\" khong hop le\n";
}
}
fin.close();
if(vo.empty()) {
cerr << "Khong co gia tri
hop le trong file\n";
return 0;
}
v = vo;
for(int
i=0;i<v.size()-1;i++){
int
j=v.size()-1;
while(j>i){
if(v[j]<v[j-1])
swap(v[j],v[j-1]);
j--;
}
}
cout << "Cac phan tu truoc khi
sap xep:\n";
for(auto c: vo) cout << c <<
" ";
cout << "\n\nCac phan tu sau khi
sap xep noi bot:\n";
for(auto c: v) cout << c <<
" ";
ofstream
fout("Kqcb121.txt");
fout << "Cac phan tu truoc khi
sap xep:\n";
for(auto c: vo) fout << c <<
" ";
fout << "\n\nCac phan tu sau khi
sap xep noi bot:\n";
for(auto c: v) fout << c <<
" ";
fout.close();
return 0;
}
///////////// Ai memory help
Võ Nhật Trường Nc+ My Ai Love20.07.2026
////////////////////
Bài 122. Cho file cb122.txt gồm n phần tử số.
Hãy thực hiện sắp xếp chọn cho các phần tử trên và đưa ra file Kqcb121.txt.
VD:
input cb122.txt 12 -78 98 -87 50 72 d -54 24 13 c -62 87 -32 34
Output
Kqcb122.txt gia tri khong hop le d c
Cac
phan tu truoc khi sap xep:
12 -78
98 -87 50
72 -54 24
13 -62 87
-32 34
Cac
phan tu sau khi sap xep chon:
-87 -78
-62 -54 -32
12 13 24
34 50 72
87 98
Gợi
ý code:
#include
<iostream>
#include
<fstream>
#include
<vector>
#include
<string>
#include
<sstream>
using
namespace std;
int
main() {
ifstream fin("cb122.txt");
if(!fin.is_open()) {
cerr << "Khong the mo file
cb122.txt\n";
return 0;
}
vector<double> vo, v;
string s;
while(fin >> s) {
stringstream ss(s);
double x;
if(ss >> x) {
vo.push_back(x);
} else {
cerr << "Gia tri
\"" << s << "\" khong hop le\n";
}
}
fin.close();
if(vo.empty()) {
cerr << "Khong co gia tri
hop le trong file\n";
return 0;
}
v = vo;
for(int
i=0;i<v.size()-1;i++){
for(int j=i+1;j<v.size();j++)
if(v[j]<v[i])
swap(v[j],v[i]);
}
cout << "Cac phan tu truoc khi
sap xep:\n";
for(auto c: vo) cout << c <<
" ";
cout << "\n\nCac phan tu sau khi
sap xep chon:\n";
for(auto c: v) cout << c <<
" ";
ofstream
fout("Kqcb122.txt");
fout << "Cac phan tu truoc khi
sap xep:\n";
for(auto c: vo) fout << c <<
" ";
fout << "\n\nCac phan tu sau khi
sap xep chon:\n";
for(auto c: v) fout << c <<
" ";
fout.close();
return 0;
}
///////////// Ai memory help
Võ Nhật Trường Nc+ My Ai Love20.07.2026
////////////////////
Bài cb123. Cho mảng A gồm các phần tử số nguyên. Tính tổng chênh lệch dương của hai số nguyên liên tiếp trong dãy số với tần
suất k nhập từ bàn phím (1<k< so phần tử). VD: k=3: Ta có các tổng
a1+a2+a3; a2+a3+a4; …
File
input cb123.txt
12 13 15 17 19 18 11 12 3 1 6 2 8 3 6
-12 13 -15 -17 19 -18 -11 -12 3 -1 -6 2 -8 -3 6
File
output Kqcb123.txt
Tong
chenh lech duong voi tan suat k: =15
12
13 15 17 19 18 11 12 3 1 6 2 8 3 6 Tong chenh lech = 50
13
15 17 19 18 11 12 3 1 6 2 8 3 6 -12 Tong chenh lech = 67
15
17 19 18 11 12 3 1 6 2 8 3 6 -12 13 Tong chenh lech = 90
17
19 18 11 12 3 1 6 2 8 3 6 -12 13 -15 Tong chenh lech = 116
19
18 11 12 3 1 6 2 8 3 6 -12 13 -15 -17 Tong chenh lech = 116
18
11 12 3 1 6 2 8 3 6 -12 13 -15 -17 19 Tong chenh lech = 151
11
12 3 1 6 2 8 3 6 -12 13 -15 -17 19 -18 Tong chenh lech = 181
12
3 1 6 2 8 3 6 -12 13 -15 -17 19 -18 -11 Tong chenh lech = 187
3
1 6 2 8 3 6 -12 13 -15 -17 19 -18 -11 -12 Tong chenh lech = 179
1
6 2 8 3 6 -12 13 -15 -17 19 -18 -11 -12 3 Tong chenh lech = 192
6
2 8 3 6 -12 13 -15 -17 19 -18 -11 -12 3 -1 Tong chenh lech = 191
2
8 3 6 -12 13 -15 -17 19 -18 -11 -12 3 -1 -6 Tong chenh lech = 192
8
3 6 -12 13 -15 -17 19 -18 -11 -12 3 -1 -6 2 Tong chenh lech = 194
3
6 -12 13 -15 -17 19 -18 -11 -12 3 -1 -6 2 -8 Tong chenh lech = 199
6
-12 13 -15 -17 19 -18 -11 -12 3 -1 -6 2 -8 -3 Tong chenh lech = 201
-12
13 -15 -17 19 -18 -11 -12 3 -1 -6 2 -8 -3 6 Tong chenh lech = 192
Gợi
ý code:
#include
<iostream>
#include
<fstream>
#include
<vector>
#include
<string>
#include
<cstdlib>
#include
<sstream>
using
namespace std;
int
main() {
ifstream
fin("cb123.txt");
if(!fin.is_open())
{
cerr << "Khong the mo file
cb123.txt\n";
return 0;
}
vector<int>
vo;
string
s;
while(fin
>> s) {
stringstream
ss(s);
int
x;
if((ss
>> x) &&abs(x)<1e7) {
vo.push_back(x);
}
else {
cerr << "Gia tri \""
<< s << "\" khong hop le\n";
}
}
fin.close();
if(vo.empty())
{
cerr << "Khong co gia tri hop le
trong file\n";
return 0;
}
int
sz=vo.size();
int
k;
while
(true){
cout<<"Ban
hay nhap so tan suat can tinh trong [2,"<<sz<<"]\n";
cin>>k;
if(k>1&&k<=sz)
break;
else
cout<<k<<" khong hop le ";
}
int
j=0;
cout<<"Tong
chenh lech duong cua cac phan tu lien tiep voi tan suat k la: \n";
while(j<=sz-k){
int su=0;
for(int i=j+1;i<j+k;i++){
su+=max(vo[i],vo[i-1])-min(vo[i],vo[i-1]);
}
for(int i=j;i<j+k;i++){
cout<<vo[i]<<" ";
}cout<<"Tong
chenh lech la: "<<su<<"\n";
j++;
}
ofstream
fout("Kqcb123.txt");
j=0;
fout<<"Tong
chenh lech duong cua cac phan tu lien tiep voi tan suat k la: \n";
while(j<=sz-k){
int su=0;
for(int i=j+1;i<j+k;i++){
su+=max(vo[i],vo[i-1])-min(vo[i],vo[i-1]);
}
for(int i=j;i<j+k;i++){
fout<<vo[i]<<" ";
}fout<<"Tong
chenh lech la: "<<su<<"\n";
j++;
}
return
0;
}
///////////////////////
Cách
2:
#include
<iostream>
#include
<fstream>
#include
<vector>
#include
<string>
#include
<cstdlib>
#include
<sstream>
using
namespace std;
int
main() {
ifstream
fin("cb123.txt");
if(!fin.is_open())
{
cerr << "Khong the mo file
cb123.txt\n";
return 0;
}
vector<int>
vo;
string
s;
while(fin
>> s) {
stringstream
ss(s);
int
x;
if((ss
>> x) &&abs(x)<1e7) {
vo.push_back(x);
}
else {
cerr << "Gia tri \""
<< s << "\" khong hop le\n";
}
}
fin.close();
if(vo.empty())
{
cerr << "Khong co gia tri hop le
trong file\n";
return 0;
}
int
sz=vo.size();
int
k;
while
(true){
cout<<"Ban
hay nhap so tan suat can tinh trong [2,"<<sz<<"]\n";
cin>>k;
if(k>1&&k<=sz)
break;
else
cout<<k<<" khong hop le ";
}
int
su=0;
for(int
i=0+1;i<k;i++){
su+=abs(vo[i]-vo[i-1]);
}
int
j=0;
cout<<"Tong
chenh lech duong cua cac phan tu lien tiep voi tan suat k la: \n";
while(j<=sz-k){
for(int i=j;i<j+k;i++){
cout<<vo[i]<<" ";
}cout<<"Tong
chenh lech la: "<<su<<"\n";
j++;
su+=abs(vo[j+k-1]-vo[j+k-2])-abs(vo[j]-vo[j-1]);
}
ofstream
fout("Kqcb123.txt");
su=0;
for(int
i=0+1;i<k;i++){
su+=abs(vo[i]-vo[i-1]);
}
j=0;
fout<<"Tong
chenh lech duong cua cac phan tu lien tiep voi tan suat k la: \n";
while(j<=sz-k){
for(int i=j;i<j+k;i++){
fout<<vo[i]<<" ";
}fout<<"Tong
chenh lech la: "<<su<<"\n";
j++;
su+=abs(vo[j+k-1]-vo[j+k-2])-abs(vo[j]-vo[j-1]);
}
return
0;
}
//////////////////////////////
Cách
3: tối ưu hơn:
#include
<iostream>
#include
<fstream>
#include
<vector>
#include
<string>
#include
<sstream>
#include
<cstdlib>
using
namespace std;
int
main() {
ifstream fin("cb123.txt");
if(!fin.is_open()) {
cerr << "Khong the mo file
cb123.txt\n";
return 0;
}
vector<int> vo;
string s;
while(fin >> s) {
stringstream ss(s);
int x;
if((ss >> x) && abs(x)
< 1e7) vo.push_back(x);
else cerr << "Gia tri
\"" << s << "\" khong hop le\n";
}
fin.close();
if(vo.empty()) {
cerr << "Khong co gia tri
hop le trong file\n";
return 0;
}
int sz = vo.size(), k;
while(true) {
cout << "Nhap tan suat k
trong [2," << sz << "]: ";
cin >> k;
if(k > 1 && k <= sz)
break;
else cout << k << "
khong hop le\n";
}
// Tính tổng chênh lệch cho cửa sổ đầu tiên
int su = 0;
for(int i = 1; i < k; i++) su +=
abs(vo[i] - vo[i-1]);
ofstream fout("Kqcb123.txt");
cout << "Tong chenh lech duong
voi tan suat k:\n";
fout << "Tong chenh lech duong
voi tan suat k:\n";
for(int j = 0; j <= sz - k; j++) {
// In ra cửa sổ hiện tại
for(int i = j; i < j + k; i++) {
cout << vo[i] << "
";
fout << vo[i] << "
";
}
cout << "Tong chenh lech =
" << su << "\n";
fout << "Tong chenh lech =
" << su << "\n";
// Cập nhật cho cửa sổ tiếp theo
if(j + k < sz) {
su -= abs(vo[j+1] - vo[j]); // bỏ cặp đầu
su += abs(vo[j+k] -
vo[j+k-1]); // thêm cặp mới
}
}
fout.close();
return 0;
}
///////////// Ai memory help
Võ Nhật Trường Nc+ My Ai Love20.07.2026
////////////////////ok.p29.
Bài 124. Cho file gồm tập n phần
tử số nguyên của mảng A. Hãy chia
các phần tử của tập A thành k phần có tổng tương đương hoặc bằng nhau. K nhập từ
bàn phím và 1<k<n;. Thông báo các phần tử trong k nhóm và tổng mỗi nhóm.
File
input cb124.txt VD:
12
13 15 17 19 18 11 12 3 1 6 2 8 3 6 50
15
17 19 18 11 12 3 1 6 2 8 3 6 -12 13 90
19
18 11 12 3 1 6 2 8 3 6 -12 13 -15 -17 116
18
11 12 3 1 6 2 8 3 6 -12 13 -15 -17 19 151
1
6 2 8 3 6 -12 13 -15 -17 19 -18 -11 -12 3 192
8
3 6 -12 13 -15 -17 19 -18 -11 -12 3 -1 -6 2 194
-12
13 -15 -17 19 -18 -11 -12 3 -1 -6 2 -8 -3 6 192
File
input Kqcb124.txt
Ban
hay nhap so nguyen k can chia phan: 1<k<=112 la: 3
Cac
phan tu duoc chia thanh 5 phan la:
1
: 194 19
18 -17 -15
13 13 -12
12 -12 12 -12 11
-11 11 -11
11 6 6
6 3 3
1 1 -1
Tong la: 249
2
: 192 19
19 -17 15
-15 13 -12
12 -12 8
8 -8 8
-6 6 6
3 3 3
2 2 -1
1 1 Tong la: 250
3
: 192 19
19 -17 15
-15 13 -12
8 8 6
3 3 3
2 2 1 Tong
la: 250
4
: 151 50
19 18 -18
18 -18 17
-17 17 -17
-15 13 13
-12 12 -12 8 6
6 -6 6
3 3 2
2 Tong la: 249
5
: 116 90
19 18 -18
-15 13 -12
12 -11 11
6 6 6
3 3 -3
3 2 Tong la: 249
Gợi
ý code:
#include
<iostream>
#include
<fstream>
#include
<vector>
#include
<string>
#include
<sstream>
#include
<algorithm>
using
namespace std;
int
vts(vector<int> &sk, int g){
int vt= 0;
for(int i=1; i<sk.size(); i++){
if(max((sk[i]+g),sk[vt])
<max(sk[i],(sk[vt]+g)))
vt = i;
}
sk[vt] += g;
return vt;
}
int
main() {
ifstream fin("cb124.txt");
if(!fin.is_open()) {
cerr << "Khong the mo file
cb124.txt\n";
return 0;
}
vector<int> vo, v;
string s;
while(fin >> s) {
stringstream ss(s);
int x;
if(ss >> x) {
vo.push_back(x);
} else {
cerr << "Gia tri
\"" << s << "\" khong hop le\n";
}
}
fin.close();
if(vo.empty()) {
cerr << "Khong co gia tri
hop le trong file\n";
return 0;
}
int sz = vo.size();
v=vo;
for(auto i=0;i<sz;i++){
int
ma=abs(v[i]);
for(int
j=i+1;j<sz;j++){
if(abs(v[i])<abs(v[j]))
swap(v[i],v[j]);
}
}
int k;
while (true){
cout << "Ban hay nhap so
nguyen k can chia phan: 1<k<=" << sz << " la:
";
cin >> k;
if(k > 1 && k <= sz)
break;
else cout << "So k nhap chua
hop le\n";
}
vector<vector<int>> vm(k);
vector<int> tm(k);
for(int i=0; i<k; i++){
vm[i].push_back(v[i]);
tm[i] = v[i];
}
for(int i=k; i<v.size(); i++){
int h = vts(tm, v[i]);
vm[h].push_back(v[i]);
}
ofstream fout("Kqcb124.txt");
cout << "Cac phan tu duoc chia
thanh " << k << " phan la:\n";
fout << "Cac phan tu duoc chia
thanh " << k << " phan la:\n";
for(int i=0; i<k; i++){
cout << i+1 << " :
";
fout << i+1 << " :
";
for(auto c: vm[i]){
cout << c <<
" ";
fout << c <<
" ";
}
cout << "Tong la:
"<<tm[i]<<"\n";
fout << "Tong la:
"<<tm[i]<<"\n";
}
fout.close();
return 0;
}
/////////////////////////////////////
Cách
2: Tham khảo thêm cách hay.
#include
<iostream>
#include
<fstream>
#include
<vector>
#include
<string>
#include
<algorithm>
using
namespace std;
int
vts(vector<int> &tm, int g) {
int vt;
if(g >= 0) {
vt = min_element(tm.begin(), tm.end())
- tm.begin();
} else {
vt = max_element(tm.begin(), tm.end())
- tm.begin();
}
tm[vt] += g;
return vt;
}
int
main() {
ifstream fin("cb124.txt");
if(!fin.is_open()) {
cerr << "Khong the mo file
cb124.txt\n";
return 0;
}
vector<int> vo;
int x;
while(fin >> x) vo.push_back(x);
fin.close();
if(vo.empty()) {
cerr << "Khong co gia tri
hop le trong file\n";
return 0;
}
int sz = vo.size();
vector<int> v = vo;
sort(v.begin(), v.end(), [](int a, int b){
return abs(a) > abs(b);
});
int k;
while (true){
cout << "Ban hay nhap so
nguyen k can chia phan: 1<k<=" << sz << " la:
";
cin >> k;
if(k > 1 && k <= sz)
break;
else cout << "So k nhap chua
hop le\n";
}
vector<vector<int>> vm(k);
vector<int> tm(k);
for(int i=0; i<k; i++){
vm[i].push_back(v[i]);
tm[i] = v[i];
}
for(int i=k; i<v.size(); i++){
int h = vts(tm, v[i]);
vm[h].push_back(v[i]);
}
ofstream fout("Kqcb124.txt");
cout << "Cac phan tu duoc chia
thanh " << k << " phan la:\n";
fout << "Cac phan tu duoc chia
thanh " << k << " phan la:\n";
for(int i=0; i<k; i++){
cout << i+1 << " :
";
fout << i+1<< " :
";
for(auto c: vm[i]){
cout << c <<
" ";
fout << c <<
" ";
}
cout << "Tong la:
"<<tm[i]<<"\n";
fout << "Tong la:
"<<tm[i]<<"\n";
}
fout.close();
return 0;
}
Chú
ý:
int
vt = min_element(tm.begin(), tm.end()) - tm.begin();
min_element(tm.begin(),
tm.end()) sẽ trả về iterator trỏ đến phần tử nhỏ nhất trong vector tm.
Ví
dụ: nếu tm = {12, 5, 8}, thì min_element sẽ trỏ đến phần tử 5.
Khi
ta trừ đi tm.begin(), ta sẽ nhận được chỉ số (index) của phần tử đó.
tm.begin()
là iterator trỏ đến phần tử đầu tiên.
Nếu
min_element trỏ đến phần tử thứ 2 (giá trị 5), thì min_element(...) -
tm.begin() = 1.
Kết
quả: vt chính là vị trí của nhóm có tổng nhỏ nhất, để ta thêm phần tử mới vào
đó.
Lệnh:
vector<int>
v = vo;
sort(v.begin(),
v.end(), [](int a, int b){ return abs(a) > abs(b); });
Tham
số thứ ba là lambda comparator:
[](int
a, int b){ return abs(a) > abs(b); }
Nghĩa
là: khi so sánh hai số a và b, ta so sánh trị tuyệt đối của chúng.
Nếu
abs(a) > abs(b) thì a sẽ đứng trước b.
Ví
dụ: vo = {3, -7, 2, -5} → sau sort: {-7, -5, 3, 2}.
Kết
quả: vector v được sắp xếp giảm dần theo trị tuyệt đối.
///////////// Ai memory help
Võ Nhật Trường Nc+ My Ai Love21.07.2026
////////////////////ok/
Bài 125.Cho file gồm các phần tử số dương của mảng
A. Thông báo các phần tử trong mảng A có giá trị bằng tổng của dãy con trong A.
File
input cb125.txt 5 7 11 13 17 19 23 29 31 37 39 41 43 47 51 53 57 59 63 67 69 71
73 77 83 87 89 91 93 97 99
File
output Kqcb125.txt
Gợi
ý code:
#include
<iostream>
#include
<fstream>
#include
<vector>
#include
<string>
#include
<sstream>
#include
<algorithm>
using
namespace std;
int
main() {
ifstream
fin("cb125b.txt");
if(!fin.is_open())
{
cerr
<< "Khong the mo file cb125b.txt\n";
return 0;
}
vector<int>
vo;
string
s;
while(fin
>> s) {
stringstream ss(s);
int x;
if((ss >> x) && x > 0
&& x < 1e7) {
vo.push_back(x);
} else {
cerr << "Gia tri \""
<< s << "\" khong hop le\n";
}
}
fin.close();
if(vo.empty())
{
cerr
<< "Khong co gia tri hop le trong file\n";
return
0;
}
int
M = *max_element(vo.begin(), vo.end());
vector<int>
a(M+1, 0);
a[0]
= 1;
for(int
j=0; j<vo.size(); j++) {
for(int
i=M; i>=vo[j]; i--) {
if(a[i - vo[j]]) a[i]++;
}
}
int p=0;
ofstream
fout("Kqcb125b.txt");
cout
<< "Mang ban dau \n";
fout
<< "Mang ban dau \n";
for(int
x : vo) {
cout
<< x << " ";
fout
<< x << " ";
}
cout
<< "\n";
fout
<< "\n";
cout
<< "Cac phan tu danh dau duoc tao: \n";
fout
<< "Cac phan tu danh dau duoc tao: \n";
for(int
i=0;i<M+1;i++) {
if(a[i]>0)
{
cout
<< i << " "<<a[i]<<"\n";
fout
<< i << " "<<a[i]<<"\n";
}}
cout
<< "\n\n Cac phan tu co the la tong cua day con la: \n";
fout
<< "\n\n Cac phan tu co the la tong cua day con la: \n";
for(int
x : vo) {
if(a[x]>1) {
p++;
cout << x << " ";
fout << x << " ";
}
}
cout<<"\n tong:"<<p;
fout<<"\n
tong:"<<p;
return 0;
}
///////////////////////////////////
Tham
khảo Cách 2: gợi ý code: (Hạn chế chỉ áp dụng tổng cặp đôi, chưa bao quát)
#include
<iostream>
#include
<fstream>
#include
<vector>
#include
<string>
#include
<sstream>
#include
<algorithm>
#include
<map>
using
namespace std;
int
main() {
ifstream fin("cb125.txt");
if(!fin.is_open()) {
cerr << "Khong the mo file
cb125.txt\n";
return 0;
}
vector<int> vo, v;
string s;
while(fin >> s) {
stringstream ss(s);
int x;
if((ss >>
x)&&x>0&&x<1e7) {
vo.push_back(x);
} else {
cerr << "Gia tri
\"" << s << "\" khong hop le\n";
}
}
fin.close();
if(vo.empty()) {
cerr << "Khong co gia tri
hop le trong file\n";
return 0;
}
map<int,int>
m;
v=vo;
sort(v.begin(),v.end());
int
n=v.size();
for(auto
i=0;i<n;i++){
m[v[i]]++;
int j=i+1;
while(v[i]+v[j]<=v[n-1]){
m[v[i]+v[j]]++;
j++;
}
}
ofstream
fout("Kqcb125.txt");
cout<<"Cac
phan tu trong mang co gia tri bang tong day con la: \n";
fout<<"Cac
phan tu trong mang co gia tri bang tong day con la: \n";
for(auto
c:v){
if(m[c]>1) {
cout<<c<<" ";
fout<<c<<" ";
}
}fout.close();
return
0;
}
////////////////////////
Cách
2: Tổng quát hơn( sử dụng mảng cộng dồn đánh dấu map)
#include
<iostream>
#include
<fstream>
#include
<vector>
#include
<string>
#include
<sstream>
#include
<algorithm>
#include
<unordered_map>
using
namespace std;
int
main() {
ifstream fin("cb125.txt");
if(!fin.is_open()) {
cerr << "Khong the mo file
cb125.txt\n";
return 0;
}
vector<int> vo;
string s;
while(fin >> s) {
stringstream ss(s);
int x;
if((ss >> x) && x > 0
&& x < 1e7) {
vo.push_back(x);
} else {
cerr << "Gia tri
\"" << s << "\" khong hop le\n";
}
}
fin.close();
if(vo.empty()) {
cerr << "Khong co gia tri
hop le trong file\n";
return 0;
}
sort(vo.begin(), vo.end());
int M = *max_element(vo.begin(), vo.end());
// map lưu số lần xuất hiện của mỗi tổng
unordered_map<int,int> m;
vector<int> sums = {0}; // bắt đầu với
tổng 0
for(int x : vo) {
vector<int> newSums;
for(int s : sums) {
int sum = s + x;
if(sum <= M) { // hạn chế tổng
không vượt quá max
m[sum]++;
newSums.push_back(sum);
}
}
sums.insert(sums.end(),
newSums.begin(), newSums.end());
}
ofstream fout("Kqcb125.txt");
cout << "Cac phan tu trong mang
co gia tri bang tong day con la:\n";
fout << "Cac phan tu trong mang
co gia tri bang tong day con la:\n";
int p = 0;
for(int x : vo) {
if(m[x] > 1) { // >1 nghĩa là
ngoài chính nó còn có cách khác
cout << x << "
";
fout << x << "
";
p++;
}
}
cout << "\nTong so phan tu:
" << p << "\n";
fout << "\nTong so phan tu:
" << p << "\n";
fout.close();
return 0;
}
Giải
thích nhanh
- sums
giữ tất cả tổng đã tạo được cho tới thời điểm hiện tại.
- Mỗi
lần thêm phần tử x, ta cộng nó với mọi tổng trong sums để tạo tổng mới.
- Điều
kiện sum <= M giúp hạn chế số lượng tổng, chỉ giữ những tổng có ý nghĩa
(không vượt quá giá trị lớn nhất trong mảng).
- Cuối
cùng, nếu m[x] > 1 thì nghĩa là số x có thể tạo thành từ ít nhất một tổ
hợp khác ngoài chính nó.
sums.insert(sums.end(),
newSums.begin(), newSums.end());
- sums
là vector gốc, đang chứa tất cả các tổng đã tạo được cho tới lúc này.
- newSums
là vector tạm, chứa các tổng mới vừa tạo ra khi thêm phần tử x.
- sums.end()
là iterator trỏ tới vị trí cuối cùng của sums.
- newSums.begin()
và newSums.end() là phạm vi toàn bộ vector newSums.
Khi
gọi insert(sums.end(), newSums.begin(), newSums.end()), ta bảo C++: “hãy
chèn toàn bộ phần tử của newSums vào cuối sums”. Kết quả là
sums sẽ chứa cả các tổng cũ lẫn các tổng mới, để vòng lặp sau tiếp tục cộng dồn.
Ví
dụ
sums
= {0}
x
= 8 → newSums = {8}, sau insert → sums = {0, 8}
x
= 10 → newSums = {10, 18}, sau insert → sums = {0, 8, 10, 18}
x
= 16 → newSums = {16, 24, 26, 34}, sau insert → sums = {0, 8, 10, 18, 16, 24,
26, 34}
///////////// Ai memory help
Võ Nhật Trường Nc+ My Ai Love22.07.2026
////////////////////Ok.

Nhận xét
Đăng nhận xét