Tải bản đầy đủ (.pdf) (81 trang)

SKKN Lớp các bài toán cơ bản trên mảng một chiều lập trình bằng ngôn ngữ C++

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (414.77 KB, 81 trang )

MỤC LỤC
ĐẶT VẤN ĐỀ ....................................................................................................... 1 1.
Lý do chọn đề tài........................................................................................... 2 2. Cấu
trúc nội dung.......................................................................................... 2 3. Mục đích
nghiên cứu..................................................................................... 2 4. Phương pháp
nghiên cứu............................................................................... 3 5. Giới hạn phạm vi
nghiên cứu của đề tài ........................................................ 3
NỘI DUNG............................................................................................................ 4
PHẦN 1. KIẾN THỨC VỀ MẢNG MỘT CHIỀU.............................................. 4 I.
Khái niệm................................................................................................... 4 II. Cách
khai báo .............................................................................................. 4 III. Cách truy
nhập đến phần tử mảng .............................................................. 4 IV. Cách nhập/xuất
mảng................................................................................. 5 V. Một số thuật toán cơ bản
trên mảng một chiều ............................................ 5 PHẦN II. BÀI
TẬP........................................................................................... 12
1. Bài tập chủ đề tìm giá trị nhỏ nhất, lớn nhất ............................................... 12 2.
Bài tập chủ đề sắp xếp mảng ...................................................................... 17 3.
Bài tập chủ tìm kiếm trên mảng.................................................................. 24 4.
Bài tập chủ đề tìm đoạn con dài nhất của thỏa mãn điều kiện cho trước. .... 36 5.
Bài tập chủ đề cắt mảng thành K đoạn thỏa mãn điều kiện cho trước ......... 42
KẾT QUẢ ÁP DỤNG.......................................................................................... 44
KẾT

LUẬN..........................................................................................................

44

TÀI LIỆU THAM KHẢO ................................................................................... 45
PHỤ LỤC: HƯỚNG DẪN VÀ CHƯƠNG TRÌNH MẪU ................................... 46
1. Bài tập chủ đề tìm giá trị nhỏ nhất, lớn nhất .................................................. 46 2.
Bài tập chủ đề sắp xếp mảng ......................................................................... 53 3.


Bài tập chủ đề tìm kiếm trên mảng ................................................................ 60 4.
Bài tập chủ đề tìm đoạn con dài nhất thỏa mãn điều kiện cho trước. ............. 80 5.
Bài tập chủ đề cắt mảng thành K đoạn thỏa mãn điều kiện cho trước ............ 89

ĐẶT VẤN ĐỀ

1


1. Lý do chọn đề tài
Mảng 1 chiều là cấu trúc dữ liệu đầu tiên và cũng là cấu trúc dữ liệu đơn giản và
phổ biến nhất. Mảng 1 chiều giúp giải quyết được nhiều lớp bài tốn. Vì vậy, nó được
sử dụng nhiều trong các kỳ thi học sinh giỏi Tin học.
Với nhiều năm tham gia giảng dạy, bồi dưỡng học sinh giỏi và việc nghiên cứu
các vấn đề về lập trình theo từng dạng bài tập từ cơ bản đến phức tạp của ngơn ngữ
lập trình C++, các tài liệu về phương pháp giảng dạy phục vụ cho việc học tập, ôn thi
học sinh giỏi của học sinh cũng như giảng dạy của giáo viên. Từ đó, tơi viết sáng kiến
kinh nghiệm với đề tài “Lớp các bài tốn cơ bản trên mảng một chiều lập trình
bằng ngơn ngữ C++”. Với mong muốn phần nào giúp học sinh cũng như giáo viên
có tài liệu tham khảo phục vụ cho việc học tập và giảng dạy.
2. Cấu trúc nội dung
Phần 1. Kiến thức về Mảng 1 chiều
1. Khái niệm về mảng một chiều
2. Khai báo mảng
3. Truy nhập phần tử mảng
4. Nhập/xuất mảng
5. Một số thuật toán cơ bản trên mảng 1 chiều
Phần 2. Bài tập
1. Tìm giá trị nhỏ nhất, giá trị lớn nhất
2. Sắp xếp trên mảng

3. Tìm kiếm trên mảng
4. Tìm đoạn con dài nhất thỏa mãn điều kiện cho trước
5. Cắt mảng thành K đoạn thỏa mãn điều kiện cho trước
3. Mục đích nghiên cứu
Trong q trình nghiên cứu và giảng dạy, tơi nhận thấy ngơn ngữ lập trình C++
cung cấp nhiều thư viện nên rất tiện lợi trong quá trình lập trình giải các bài toán,
đồng thời lớp các bài toán trên mảng 1 chiều cũng được vận dụng nhiều trong lập
trình. Vì vậy, tơi viết đề tài này với mục đích:
- Thứ nhất, trao đổi cùng với các đồng nghiệp về việc vận dụng ngơn ngữ C++
trong việc lập trình.
- Thứ hai, là tài liệu cho giáo viên phục vụ giảng dạy, bồi dưỡng HSG.

4. Phương pháp nghiên cứu.
Kinh nghiệm bản thân, thảo luận, sưu tầm tài liệu, thử nghiệm thực tế, rút kinh
nghiệm từ các tiết dạy trên lớp.

2


5. Giới hạn phạm vi nghiên cứu của đề tài
Đề tài chủ yếu nghiên cứu hệ thống lớp các bài tốn cơ bản trên mảng 1 chiều và
lập trình bằng ngơn ngữ C++.
Đề tài có khả năng áp dụng rộng rãi vào giảng dạy, bồi dưỡng học sinh giỏi Tin
học cho giáo viên và học sinh THCS, THPT trên địa bàn toàn tỉnh Nghệ An.

NỘI DUNG
Việc nắm vững lý thuyết về mảng một chiều và các bài toán cơ bản trên mảng

3



một chiều là điều rất quan trọng, đó là cơ sở để các em học sinh vận dụng và giải
quyết các bài toán phức tạp và nâng cao. Sau đây, tơi xin trình bày các kiến thức và
các bài tập cơ bản về mảng 1 chiều sử dụng ngôn ngữ lập trình C++ mà tơi đã tìm
hiểu và vận dụng có hiệu quả trong q trình giảng dạy.
PHẦN 1. KIẾN THỨC VỀ MẢNG MỘT CHIỀU
I. Khái niệm
Mảng một chiều là dãy hữu hạn các phần tử có cùng kiểu dữ liệu. Khi nói đến
mảng ta cần xác định được:
- Kiểu dữ liệu của các phần tử mảng .
- Số phần tử của mảng.
II. Cách khai báo
1. Khai báo khơng có khởi tạo
<Tên kiểu dữ liệu> <Tên biến mảng> [Số phần tử];
Ví dụ: int a[5]; float b[10];
2. Khai báo có khởi tạo
<Tên kiểu dữ liệu> <Tên biến mảng> [Số phần tử] = {dãy giá trị};
Hoặc: <Tên kiểu dữ liệu> <Tên biến mảng>[ ] = {dãy giá trị} ;
(Lưu ý: Trong trường hợp khơng khai báo số phần tử mảng thì mảng vừa đủ lớn
để giữ các giá trị được khởi tạo)
trúc.

Trong đó: - Tên kiểu dữ liệu: là các kiểu dữ liệu cơ bản hoặc kiểu dữ liệu có cấu
- Tên biến mảng: do người dùng đặt theo quy tắc đặt tên.
- Số phần tử: kích thước mảng.
Ví dụ: float x[5]={3,5,7,2,1};
int a[ ] = {0, 2, 4, 6, 8};
III. Cách truy nhập đến phần tử mảng
<Tên biến mảng> [Chỉ số]
Ví dụ: int a[5] 0 1 2 3 4

1

3

5

7

9

a[1] = 3; a[3]= 7;
Lưu ý: - Mảng trong C++ được đánh số bắt đầu từ 0

4


- Khi khai báo mảng cần khai báo số phần tử thừa ra.
IV. Cách nhập/xuất mảng
4.1. Nhập mảng
Cách 1: Biết số phần tử của mảng
cin>>n;
for (int i = 1 ; i < n; i++) cin>>a[i];
Cách 2: Chưa biết số phần tử của mảng
int x, n = 0;
while (cin >> x)
{
n++;
a[n] = x;
}
4.2. Xuất mảng:

for (int i=1 ; i <=n; i++) cout << a[i];
V. Một số thuật toán cơ bản trên mảng 1 chiều
5.1. Tìm giá trị nhỏ nhất, lớn nhất
Bài tốn: Tìm Min, Max của mảng A gồm N phần tử.
Ý tưởng:
- Gán Min = A[1] (Max= A[1]).
- Ta duyệt từ phần tử thứ 2 đến cuối mảng, gặp phần tử A[i] nào bé hơn Min (lớn
hơn Max) gán lại Min = A[i]( Max = A[i]).
Thuật toán:
Cách 1:
Min = A[1]; Max = A[1];
for (i = 2 ; i <= N; i++)
{
if (Min > A[i]) Min = A[i];
if (Max < A[i]) Max = A[i];
}
Cout << “Min =” << Min << “ Max ”<< Max;

Cách 2: Sử dụng hàm min, max
Min = INT_MAX; Max = INT_MIN;
for (i = 1; i < N; i++)

5


{
Min = min (Min, A[i]);
Max = max (Max, A[i])
}
Cout << Min <

5.2. Sắp xếp trên mảng
Bài toán: Cho mảng A gồm N phần tử, sắp xếp mảng theo thứ tự tăng dần
5.2.1. Thuật toán sắp xếp đơn giản (Selection Sort)
Ý tưởng thuật tốn:
Duyệt mảng từ vị trí đầu đến hết mảng, nếu gặp phần tử nào của mảng bằng X
thì in ra vị trí, nếu duyệt hết mảng mà khơng tìm thấy thì thơng báo khơng tìm thấy.
Chia mảng A thành hai mảng: Mảng chưa sắp(CS) và mảng đã sắp (DS). Khởi tạo: CS chính là mảng A, DS bằng rỗng.
- Lấy phần tử đầu tiên của tập chưa sắp (CS), so sánh với mọi phần tử đứng sau
nó, nếu thấy phần tử nào khơng thõa mãn điều kiện thì tráo đổi hai phần tử đó cho
nhau. Đưa phần tử đầu tiên của mảng CS này vào mảng DS.
- Lặp lại cho đến phần tử cuối cùng của mảng CS.
Cuối cùng ta được mảng đã sắp xếp chính là mảng DS.
Thuật toán:
for (i=1; i<= N-1; i++)
for (j = i+1; j<= N; j++)
if (A[i] > A[j]) swap(A[i], A[j]);
for (i=1; i<= N;i++) cout << A[i]<< “ ”;
5.2.2. Thuật toán sắp xếp nhanh( Quick sort)
Ý tưởng thuật toán:
Chọn phần tử x ở giữa của dãy làm chuẩn để so sánh. Ta phân hoạch dãy này
thành 3 dãy con liên tiếp nhau:
- Dãy con thứ nhất gồm phần tử có khố nhỏ hơn x.key.
- Dãy con thứ hai gồm các phần tử có khố bằng x.key.
- Dãy con thứ ba gồm các phần tử có khố lớn hơn x.key.
Sau đó áp dụng giải thuật phân hoạch này cho dãy con thứ nhất nhất và dãy con
thứ ba, nếu các dãy con có nhiều hơn một phần tử.
Cụ thể là xét một doạn của dãy từ thành phần L đến thành phần thứ H. -

6



Lấy giá trị của thành phần thứ (L+H) Div 2 gán vào biến X.
- Cho i ban đầu là L.
- Cho j ban đầu là H.
- Lặp lại.

∙ Chừng nào cịn A[i] < X thì tăng i.
∙ Chừng nào cịn A[j] > X thì giảm j.
∙ i<=j thì
+ Hốn vị A[i] và A[j]
+ Tăng i
+ Giảm j
Cho đến khi i>j
+ Sắp xếp đoạn từ A[L] đến A[j]
+ Sắp xếp đoạn từ A[i] đến A[H]
Thuật toán
1. #include <bits/stdc++.h>
2. using namespace std;
3. void quicksort(long a[],long l,long h)
4. {
5. long i=l,j=h,x=a[(l+h)/2];
6. do
7. {
8. while (a[i]<x) i++; while (a[j]>x) j--;
9. if(i<=j) {
10. swap(a[i],a[j]);
11. i++;
12. j--;}
13. }
14. while(i<=j);

15. if (l16. if(i17. }

7


18. int main()
19. {
20. int n, i; int a[100000];
21. cin>> a[i];
22. quicksort(a,1,n);
23. for(long i=1;i<=9;i++) cout<24. return 0;
25. }
5.2.3. Sử dụng hàm sort trong C++
* Sắp xếp tăng
Sort (tên mảng + chỉ số đầu, tên mảng + chỉ số cuối +1);
Ví dụ:
+) Sắp xếp n phần tử tăng từ a[1] đến a[n]:
Sort (a +1, a+ n + 1);
+) Sắp xếp n phần tử tăng từ a[0] đến a[n - 1]:
Sort (a , a+ n);
* Sắp xếp giảm:
Sort (tên mảng + chỉ số đầu, tên mảng + chỉ số cuối +1, greater < int >( ) );
Ví dụ:
+) Sắp xếp n phần tử giảm từ a[1] đến a[n]:
Sort (a +1, a+ n + 1, greater < int >( ));
+) Sắp xếp n phần tử giảm từ a[0] đến a[n - 1]:
Sort (a , a+ n, greater < int >( ));

5.3. Tìm kiếm trên mảng một chiều
5.3.1. Tìm kiếm tuần tự
Bài tốn: Cho mảng A gồm N phần tử và phần tử X. Tìm kiếm xem phần tử X
có xuất hiện trong mảng A hay khơng? Nếu có thì xuất hiện ở những vị trí nào?
Thuật tốn:
Timthay = false;
for (i = 1; i<= N; i++)
if (X = A[i])
{

8


Cout << “xuất hiện ở vị trí:”<< i;
timthay=true;
}
if not (timthay) cout<< “Khong tim thay”;
Trong trường hợp chỉ cần xuất ra vị trí của một phần tử ta cải tiến lại chương
trình để chương trình thực hiện nhanh hơn.
Timthay = false;
for (i = 1; i<= N; i++)
if (X = A[i])
{
Cout << “xuất hiện ở vị trí:”<< i;
timthay=true;
break;
}
if not (timthay) cout<< “Khong tim thay”;
5.3.2. Tìm kiếm nhị phân
a. Thuật tốn tìm kiếm nhị phân cơ bản

Bài toán: Với mảng A đã được sắp xếp tăng dần, độ phức tạp của tìm kiếm tuần
tự không đổi. Tận dụng thông tin của mảng đã được sắp xếp để giới hạn vị trí của giá
trị cần tìm trong mảng.
Ý tưởng: Thuật tốn tìm kiếm nhị phân
So sánh x với phần tử chính giữa của mảng A.
Nếu x là phần tử giữa thì dừng
Nếu khơng, xác định xem x có thể thuộc nửa trái hay nửa phải của A.
Lặp lại 2 bước trên với nửa đã xác định.

Thuật toán:
int binarySearch(int A[], int key, int left, int right)
{
int mid, l=left, r=right;
while(l < r){
mid = (l + r) / 2;

9


if(A[mid] == key) return mid;
if(A[mid] > key) r = mid - 1;

else

l = mid + 1;
}
return 0;
}
b. Thuật toán toán tìm kiếm một phần tử có giá trị gần bằng x *
Tìm kiếm phần tử lớn nhất nhưng nhỏ hơn hoặc bằng x

int binarySearch(int A[], int key, int left, int right)
{
int mid, l=left, r=right; int kq=0;
while(l <= r)
{
mid = (l + r) / 2;
if (A[mid] <= key)
{
Kq = mid;
l = mid + 1;
}
else
r = mid - 1;
}
return kq;
}
* Tìm kiếm phần tử nhỏ nhất nhưng lớn hơn hoặc bằng x
int binarySearch(int A[], int key, int left, int right)
{
int mid, l=left, r=right; int kq=0;
while(l <= r)
{
mid = (l + r) / 2;
(A[mid] >= key) {
Kq = mid; r=mid - 1;
}
else
l = mid + 1;
}
return kq;

}

10
if


11

PHẦN II. BÀI TẬP
1. Bài tập chủ đề tìm giá trị nhỏ nhất, lớn nhất
Bài 1: Cho dãy số gồm n phần tử a1, a2, ... , an.
Tìm giá trị lớn nhất của biểu thức (aj - ai) với (1<= i < j <=n)
Dữ liệu: Vào từ file văn bản Seq1.inp
- Dòng đầu nhập số nguyên dương n.
- Dòng thứ 2 nhập n số nguyên a1, a2, ... ,an.
Kết quả: Ghi ra file văn bản Seq1.out
Giá trị lớn nhất của biểu thức
Ví dụ:
Seq1.inp
7

Seq1.out
11

8 2 4 -2 1 -3

Giải thích: 2 số ai, aj là ( -2, 9).
Sub1: n <= 5000

Sub2 : n <= 106

Bài 2. Thủ khoa
Kỳ thi học sinh giỏi tỉnh mơn Tin học năm nay có N học sinh tham gia. Số điểm
của học sinh i là một số thực ai (1 < i < N).
Yêu cầu: Hãy cho biết điểm cao nhất (thủ khoa) là bao nhiêu.
Dữ liệu: Vào từ file văn bản Thukhoa.inp
- Dòng 1 chứa số nguyên dương N (N < 100).
- Dòng 2 chứa N số thực a1, ..., an (0 < ai < 20).
Kết quả: Ghi ra file văn bản Thukhoa.out
- Chỉ một dòng duy nhất chứa một số thực là điểm thủ khoa. (lấy đến 2 chữ số ở
phần thập phân).
5

Ví dụ:
Thukhoa.inp

10 15 12 15 11
Thukhoa.out

15.00


Giải thích test ví dụ: Điểm cao nhất (thủ khoa) là 15.
Bài 3. Ngôi sao

12

Một em bé khi rảnh rỗi ngồi xếp n ngôi sao (2 <= n <= 100) rồi xếp thành mơt
hàng có đánh sồ thứ tự. Do không chia đúng tỉ lệ trước khi xếp sao và trong lúc xếp
khơng tỉ mỉ nên kích thước của các ngôi sao to nhỏ khác nhau. Em bé lại chơi trị tìm
ngơi sao có kích thước nhỏ nhất và lớn nhất. Sau khi tìm xong em lấy ngơi sao nhỏ

nhất đổi chỗ cho ngôi sao lớn nhất rồi xâu chúng thành một vòng tròn.
Hãy giúp em xếp lai chiếc vòng như em muốn. Nếu có nhiều ngơi sao nhỏ nhất
và lớn nhất thì đổi chỗ ngơi sao lớn nhất có chỉ số nhỏ nhất với ngơi sao nhỏ nhất có
chỉ số lớn nhất.
Dữ liệu: Vào từ file văn bản Ngoisao.inp
- Dòng đầu nhập số nguyên dương n.
- Dòng thứ 2 nhập n số nguyên a1, a2, ... , an.
Kết quả: Ghi ra file văn bản Ngoisao.out: Các ngôi sao đã được đổi chỗ.
Ví dụ:
Ngoisao.inp
9

Ngoisao.out
438456368

433456868

Bài 4. Giá trị nhỏ nhất
Cho dãy số nguyên A = (a1, a2, ..., an) và một số nguyên dương k ≤ n. Với mỗi
giá trị i (1 ≤ i ≤ n – k + 1 ).
Hãy xác định giá trị nhỏ nhất trong phần tử liên tiếp: ai, ai+1, ..., ai+k-1.
Dữ liệu: Vào từ file văn bản Minimum.inp
- Dòng 1 chứa hai số nguyên dương n và k, trong đó 1 ≤ k ≤ n ≤ 1000, cách nhau
bởi dấu cách.
- Dòng 2 chứa n số nguyên dương (a1, a2, ..., an) cách nhau bởi dấu cách
Kết quả: Ghi ra file văn bản Minimum.out
Ghi ra màn hình n–k+1 dịng, dịng thứ i ghi giá trị nhỏ nhất trong các phần tử
Ví dụ:
Minimum.inp


Minimum.out


53

1

21534

1
3

13
Giải thích test đề bài: 3 số đầu tiên là 2 1 5 số nhỏ nhất là 1, 3 số tiếp theo 1 5 3
số nhỏ nhất là 1, 3 số cuối cùng là 5 3 4 số nhỏ nhất là 3.
Bài 5. Đoạn con
9

5

Cho dãy số nguyên a1, a2,..., aN (|ai| < 10 , N < 10 ). Một tập hợp khác rỗng các
số hạng liên tiếp {ai, ai+1,..., ak} (i ≤ k) gọi là một đoạn con của dãy đó. Với mỗi đoạn
con ta tính tổng tất cả các số hạng của nó.
u cầu: Tìm giá trị lớn nhất trong số các tổng của các đoạn con của dãy đã cho.
Dữ liệu: Vào từ file văn bản Subseq.inp
Dòng đầu chứa số N, dòng thứ i trong N dòng tiếp theo chứa số ai.
Kết quả: Ghi ra file văn bản Subseq.out
Một số nguyên là giá trị tổng đoạn con lớn nhất tìm được.
Ví dụ:
Subseq.inp

7

Subseq.out
8

1
-2
-1
4

(Giải thích: đoạn con
tổng lớn nhất là:
4 – 1 + 5 = 8)

-1
5
-2

(60% số test có N < 3000)
Bài 6. Lập trình
Trong cuộc thi lập trình có N bài thi giải đúng yêu cầu đặt ra. Ban tổ chức quyết
định trao phần thưởng đặc biệt cho bài thi tốt nhất, đó là bài thi có thời gian chạy
chương trình ít nhất. Cho biết bài thi thứ i (1< i < N) có thời gian chạy là một số


nguyên ai (tính theo đơn vị centisecond, 1centisecond = 1/100 giây).
Yêu cầu: Hãy cho biết thời gian của bài thi được trao thưởng và có bao nhiêu
bài thi được trao thưởng.
Dữ liệu: Vào từ file văn bản Laptrinh.inp
- Dòng 1 chứa số nguyên dương N (N < 100).

- Dòng 2 chứa N số nguyên a1, ..., an (0 < ai < 100).
Kết quả: Ghi ra file văn bản Laptrinh.out

14

- Dòng thứ nhất chứa một số nguyên là thời gian ít nhất tìm được - Dịng
thứ hai chứa một số ngun là số bài thi cùng đạt thời gian ít nhất. Ví dụ.
Laptrinh.inp

Laptrinh.out

5

8

10 8 12 8 11

2

Bài 7. Dãy số
Cho dãy số nguyên a1, a2, …, an . với 9 5

ai ≤10 ,n ≤10

1. Tìm số nguyên tố lớn nhất của dãy
2. Số nào xuất hiện nhiều nhất trong dãy.
Dữ liệu: Vào từ file văn bản Primemax.inp
- Dòng đầu tiên là số n
- Dòng thứ hai là n số nguyên mỗi số cách nhau bởi một dấu cách.
Kết quả: Ghi ra file văn bản Primemax.inp

- Dòng thứ nhất là số nguyên tố lớn nhất của dãy, nếu khơng có số ngun tố thì
in ra 0.
- Dịng thứ hai là số xuất hiện nhiều nhất trong dãy, nếu có nhiều số có số lần
xuất hiện bằng nhau thì in ra số đầu tiên.
Ví dụ:
Primemax.inp

Primemax.out

16

0

0 0 0 0 1 1 1 1 -1 -1 -1 -1 4 4 4 4

0


4

5737

11873 5737 9269 7956

11873

Bài 8. Khoảng cách xa nhất
Cho dãy số ngun A kích thước N. Tìm khoảng cách xa nhất giữa hai phần tử
bằng nhau trong A.
Dữ liệu: Vào từ file văn bản Kcmax.inp

Dòng đầu tiên chứa số nguyên T là số bộ dữ liệu kiểm tra. Mỗi bộ dữ liệu gồm: Dòng đầu chứa số nguyên dương N là số phần tử của A.

- Dòng sau chứa N số nguyên cách nhau bởi dấu cách biểu diễn dãy A.

15

Ràng buộc:
0 < T < 100; 0 < N < 10

4

4

0 < A[i] < 10 ; (0 < i < N)
Kết quả: Ghi ra file văn bản Kcmax.out
Gồm T dòng/ mỗi dòng chứa một số nguyên là kết quả bài tốn.
Ví dụ:
Kcmax.inp

Kcmax.out

2

5

6

10

112221

12
321214586742

Giải thích:
Test 1: Hai phần tử a[1] và a[6] đều bằng 1 cách nhau xa nhất với khoảng cách
bằng 5
Test 2: Hai phần tử a[2] và a[12] đều bằng 2 cách nhau xa nhất với khoảng cách
bằng 10.
Bài 9. Biểu thức nhân, cộng


Cho ฀฀số nguyên dương ฀฀฀฀,฀฀=1..฀฀, bạn phải đặt giữa ฀฀số nguyên
dương này 2 phép nhân và ฀฀−3phép cộng sao cho kết quả biểu thức là lớn nhất.
Ví dụ: với ฀฀=5và dãy ฀฀฀฀là 4, 7, 1, 5, 3 thì bạn có thể có các biểu
thức: 4 + 7 * 1 + 5 * 3
4 * 7 *1 + 5 + 3

Chú ý: Không được thay đổi thứ tự xuất hiện của ฀฀฀฀,฀฀=1..฀฀trong biểu
thức thu được.
Dữ liệu: Vào từ file văn bản Express.inp

- Dòng 1 chứa số nguyên dương ฀฀(4≤฀฀≤1.000)

- N dòng tiếp theo, dòng thứ ฀฀+1chứa số nguyên dương ฀฀฀฀(1≤฀฀฀฀≤
10.000,฀฀=1..฀฀)
Kết quả: Ghi ra file văn bản Express.out

Ghi 1 số nguyên dương duy nhất là giá trị lớn nhất của biểu thức thu được.

16


Ví dụ:
Express.inp
5

Express.out
44

4
7

Giải thích
Biểu thức thu được
là:
4 * 7 + 1 + 5*3

1
5
3

Bài 10. Minima
Cho dãy số nguyên dương X= x1, x2, ..., xN. Hãy tìm số nguyên A sao cho biểu
thức sau đây nhận giá trị nhỏ nhất: S =1
x A − +2
x A− + ...+ N
xA−.
Dữ liệu: Vào từ file văn bản minima.inp
- Dòng đầu là số N(0 < N ≤ 50000).
- Các dòng sau chứa N số nguyên dương mô tả dãy số X(0 ≤ xi ≤ 30000).
Kết quả: Ghi ra file văn bản minima.out

Gồm một dòng chứa số S tìm được.


Ví dụ:
Minima.inp
4

Minima.out
2

1223

2. Bài tập chủ đề sắp xếp mảng
Bài 11. Khối hình chữ nhật
Một viên gạch có dạng khối hộp chữ nhật với ba kích thước là a, b, c. Người ta
muốn biết: có thể đưa viên gạch đó qua lỗ hổng hình chữ nhật có kích thước x, y hay
không?
Dữ liệu: Vào từ file văn bản Khoihcn.input
Các số nguyên dương a, b, c, x và y.
Kết quả: Ghi ra file văn bản Khoihcn.output
Đưa ra chuỗi thông báo "CO", nếu có thể đưa viên gạch qua lỗ hổng; ngược lại,
in ra chuỗi thơng báo "KHONG".
Ví dụ:
17
Khoihcn.input

Khoihcn.output

74345


CO

54335

KHONG

Bài 12. Khoảng cách
Một du khách trúng một vé máy bay có thể bay đến bất kì thành phố nào trong
nước, xuất phát từ thủ đơ Hà Nội. Nhân dịp đó, người này muốn đi thêm các thành
phố lân cận, nhưng vì lo lắng khơng đủ chi phí nên ơng chỉ muốn tìm những thành
phố gần nhau nhất . Tuy nhiên, hãng hàng không chỉ cho ông biết thông tin về khoảng
cách giữa các thành phố so với thủ đô Hà Nội. Giả sử rằng tất cả các thành phố đề
nằm trên một đường thẳng bắt đầu từ thủ đô Hà Nội, hãy giúp người này tìm ra
khoảng cách ngắn nhất để có thể tính tốn chi phí cho chuyến đi.
Dữ liệu: Vào từ file văn bản Khoangcach.inp
Dữ liệu của vào bao gồm một vài bộ test. Mỗi bộ test bao gồm:


6

Dòng đầu tiên là số lượng thành phố N (1N dòng tiếp theo chứa khoảng cách của thành phố so với thủ đô.
Kết quả: Ghi ra file văn bản Khoangcach.out
Với mỗi bộ test, là một số nguyên - Khoảng cách ngắn nhất tìm được.
Ví dụ:
Khoangcach.inp
3

Khoangcach.out
78


347
269
112
7

10

34
56
78
90
12
139
100

18

Bài 13. Bút màu

Tí nhờ mẹ đi mua bút màu để chuẩn bị cho giờ vẽ tranh trên lớp. Tí dặn mẹ mua
4 bút màu khác nhau, nhưng mẹ Tí lại quên mất, chỉ nhớ là mua 4 cái bút màu cho Tí.
Về đến nhà, Tí bắt đền mẹ vì đã khơng mua đủ 4 màu cho Tí. Tí địi mẹ ra hiệu
sách mua thêm, để có đủ 4 màu vẽ cho ngày mai.
Các bạn hãy tính xem mẹ Tí cần mua thêm ít nhất bao nhiêu chiếc bút màu?
Dữ liệu: Vào từ file văn bản Butmau.inp
9

Một dòng duy nhất gồm 4 số nguyên s1, s2, s3, s4 (1<= s1, s2, s3, s4 <= 10 ) thể
hiện màu của 4 chiếc bút mà mẹ vừa mới mua cho Tí.

Kết quả: Ghi ra file văn bản Butmau.out
Số lượng bút màu ít nhất cần mua thêm cho Tí.


Ví dụ:
Butmau.inp
1733

Butmau.out
1

Butmau.inp
7777

Butmau.out
3

Bài 14. Vắt sữa bị
Vào một buổi sáng nơng dân John sắp một đàn bò gồm n con bò để vắt sữa. Ơng
dự kiến là vào sáng hơm đó, con bị thứ i có khả năng sẽ vắt được ai lít sữa. Tuy nhiên
đàn bị của ơng có đặc tính là cứ mỗi lần vắt sữa một con, những con cịn lại trơng
thấy sợ q nên sẽ bị giảm sản lượng mỗi con 01 lít sữa. Nếu vắt sữa con bò thứ nhất,
n-1 con còn lại bị giảm sản lượng. Sau đó vắt sữa con bị thứ hai thì n-2 con còn lại bị
giảm sản lượng.... Bạn hãy giúp nơng dân John tính xem thứ tự vắt sữa bị như thế nào
để số lượng sữa vắt được là nhiều nhất nhé.
Dữ liệu: Vào từ file văn bản Milk.inp
- Dòng thứ nhất là số nguyên n (1 ≤ n ≤ 100) là số lượng con bò.
- Dòng thứ hai gồm n số nguyên a1, a2,..., an (1 ≤ ai ≤ 1000) là sản lượng sữa
của các con bò.
Kết quả: Ghi ra file văn bản Milk.out

Là một số nguyên xác định số lít sữa nhiều nhất mà anh Bo có thể vắt được.
Milk.inp
4

Milk.out
10

4444

19
4

6

2143

Giải thích
- Trong test 1: vắt sữa con bị 1 (được 4), lượng sữa còn lại là 3 3 3; vắt sữa con
bò 2 (được 3), lượng sữa còn lại là 2 2, vắt sữa con bò 3 (được 2) và con bò 4 (được
1), tổng cộng 10.
- Trong test 2: vắt sữa con bò 1 (được 2), lượng sữa còn lại là 0 3 2; vắt sữa con
bò 3 (được 3) và vắt sữa con bò 4 (được 1) tổng cộng 6.


Bài 15. Cấp số cộng.
Dãy cấp số cộng là một dãy tăng dần, trong đó số đứng sau hơn số đứng trước
một giá trị d, d được gọi là công sai.
Ví dụ: 1 4 7 10 là một dãy cấp số cộng 4 phần tử công sai là 3
2 6 10 14 18 là một dãy cấp số cộng 5 phần tử công sai là 4
3 5 7 10 không phải là dẫy cấp số cộng 4 phần tử vì 7 – 5 ≠ 10 – 7.

Trong giờ kiểm tra Tốn, Tý đã tìm được đáp án của một bài toán là 4 số tạo
thành một cấp số cộng, theo yêu cầu của đề bài. Tèo ngồi bên cạnh, không chép được
bài của Tý nên tìm cách chơi xỏ Tý. Lợi dụng lúc Tý không để ý Tèo dùng bút xóa
xóa đi 4 số của Tý rồi viết lại 3 số nhưng không theo thứ tự ban đầu.
Tý xem lại bài thấy bài mình mất 1 số nên đã nhờ bạn giúp Tý khôi phục lại số
bị thiếu ban đầu.
Dữ liệu: Vào từ file văn bản Capsocong.inp
Gồm 3 số nguyên có giá trị tuyệt đối nhỏ hơn 1000, cả 3 số được viết trên 1
dịng.
Dữ liệu vào ln được đảm bảo có đáp án.
Kết quả: Ghi ra file văn bản Capsocong.out
Số còn lại bị thiếu trong cấp số cộng. Nếu có nhiều đáp án, hãy in ra số lớn nhất.
Ví dụ:
Capsocong.inp

Capsocong.out

468

10

10 1 7

4

Giải thích: Test 1: có 2 kết quả là 2 và 10, nhưng đề bài yêu cầu đưa ra số lớn
nhất nên kết quả là 10.
Bài 16. Biểu thức

20


Một dãy gồm n số nguyên không âm a1, a2,…, an được viết thành một hàng
ngang, giữa hai số liên tiếp có một khoảng trắng, như vậy có tất cả (n-1) khoảng trắng.
Người ta muốn đặt k dấu cộng và (n-1-k) dấu trừ vào (n-1) khoảng trắng đó để nhận
được một biểu thức có giá trị lớn nhất.
Ví dụ, với dãy gồm 5 số nguyên 28, 9, 5, 1, 69 và k = 2 thì cách đặt 28+9-51+69 là biểu thức có giá trị lớn nhất.
Yêu cầu: Cho dãy gồm n số nguyên không âm a1, a2,…, an và số nguyên dương
k, hãy tìm cách đặt kdấu cộng và (n-1-k) dấu trừ vào (n-1) khoảng trắng để nhận được


một biểu thức có giá trị lớn nhất.
Dữ liệu: Vào từ file văn bản Bieuthuc.inp
- Dòng đầu chứa hai số nguyên dương n, k (k < n);
6

- Dòng thứ hai chứa n số nguyên không âm a1, a2,…, an (an ≤ 10 )
Kết quả: Ghi ra file văn bản Bieuthuc.out
Một số nguyên là giá trị của biểu thức đạt được.
Ví dụ:
Bieuthuc.inp

Bieuthuc.out

5 2 28 9 5 1 69

100

Ghi chú:
5


- Có 50% số test ứng với 50% số điểm có n ≤ 10 và k = 1;
5

- Có 50% số test cịn lại ứng với 50% số điểm có n ≤ 10 ;
Bài 17. Quyết chiến
Có một cuộc quyết chiến giữa 2 phe Radiant và Dire. Mỗi phe có N chiến binh,
mỗi chiến binh đều biết chỉ số sức mạnh của mình. Cuộc quyết chiến giữa 2 phe phải
được tuân thủ luật sau:
Có N vịng đấu, mỗi vịng đấu Radiant và Dire cử ra 1 chiến binh để quyết chiến
với bên kia. Chiến binh của bên nào thắng thì bên đó sẽ được 1 điểm, bên thua cuộc
được 0 điểm.
Trước khi cuộc quyết chiến diễn ra, thủ lĩnh của cả 2 phe đều biết được thực lực
các chiến binh của đối phương. Thủ lĩnh Dire là 1 người tài trí hơn người, ông ta biết
cách sắp xếp thứ tự thi đấu sao cho bên mình có thể đạt được nhiều điểm nhất có thể.
Bạn hãy đốn xem với danh sách 2 đội đã cho trước, Dire có thể có tối đa bao nhiêu
điểm.

Dữ liệu: Vào từ file văn bản Quyetchien.inp

21

5

- Dòng đầu tiên chứa số N (1 ≤ n ≤ 2*10 ).
- Dòng thứ 2 gồm n số nguyên dương a[1], a[2], …, a[n] là chỉ số sức mạnh của
các chiến binh phe Radiant.
- Dòng thứ 3 gồm n số nguyên dương b[1], b[2], …, b[n] là chỉ số sức mạnh của
các chiến binh phe Dire.
(1 ≤ ai, bi ≤ 2*N).



Giả sử rằng chỉ số sức mạnh của tất cả các chiến binh 2 phe đều khác nhau.
Kết quả: Ghi ra file văn bản Quyetchien.out
Số điểm tối đa Dire có thể đạt được.
Ví dụ:
Quyetchien.inp
3
345
126

Quyetchien.out
1

Quyetchien.inp

Quyetchien.out

4
4562
1738

3

Bài 18. Chạy đua Maratong
John cho các con bị của mình chạy đua marathon! Thời gian bị N (1 <= N <=
100000) về đích được biểu diễn theo dạng Số giờ (0 <= Số giờ <= 99), Số phút (0 <=
Số phút <= 59), và số giây (0 <= Số giây <= 59). Để xác định nhà vô địch, John phải
sắp xếp các thời gian (theo số giờ, số phút, và số giây) theo thứ tự tăng dần, thời gian
ít nhất xếp đầu tiên.
Dữ liệu: Vào từ file văn bản maratong.inp

- Dòng 1: Số nguyên N
- Dòng 2..N+1: Dịng i+1 chứa thời gian bị i được mơ tả bởi 3 số nguyên cách
bởi dấu cách: Số Giờ , Số Phút, Số giây.
Kết quả: Ghi ra file văn bản maratong.out
Mỗi dòng chứa thời gian của 1 con bò là 3 số nguyên cách nhau bởi dấu cách sau
khi đã sắp xếp.
Ví dụ:
Maratong.inp

Bài 19. Phân nhóm

3
11 20 20
Maratong.out
11 15 12
14 20 14

11 15 12
11 20 20
14 20 14

22

Pudge là một anh chàng rất thích hù dọa những người hay đi lẻ trong rừng. Một
người được gọi là đi lẻ nếu như chênh lệch chiều cao với những người khác lớn hơn
K. Một người được xếp chung nhóm với nhau nếu như trong nhóm đó, có một người
khác có chênh lệch chiều cao với người đó khơng vượt q K.
Ví dụ: với tập N = 5 người có các chiều cao: 6, 7, 3, 4, 9 và K = 1 thì ta sẽ có các
mối quan hệ sau :



- Người thứ 1 và 2 chung một nhóm (chiều cao 6, 7)
- 3 và 4 chung một nhóm (chiều cao 3, 4)
- 5 đi lẻ (chiều cao 9)
Vậy ta sẽ có 3 nhóm: {1, 2}, {3, 4} và {5}
Bạn hãy giúp Pudge tính xem có bao nhiêu nhóm trong rừng để anh còn biết mà
hù dọa.
Dữ liệu: Vào từ file văn bản Phannhom.inp
5

6

- Dòng đầu chứa 2 số nguyên N, K (0 ≤ N ≤ 10 , 1 ≤ K ≤ 10 ).
- Dòng thứ hai trong chứa N số nguyên dương – chiều cao của mỗi người (giá trị
6
không vượt quá 10 ).
Kết quả: Ghi ra file văn bản Phannhom.out
Dịng duy nhất chứa số nhóm trong rừng.
Ví dụ:
Phannhom.inp
712617349

Phannhom.out
3

Giải thích test:
Nhóm 1 những người có chiều cao: 2 1 3 4
Nhóm 2 gồm: 6 7
Nhóm 3 gồm: 9
Bài 20. Thời gian

Có n bệnh nhân chờ được khám bệnh tại một phịng khám chỉ có một bác sỹ (tại
một thời điểm chỉ khám được cho 1 bệnh nhân :D). Bệnh nhân thứ i đến phòng khám
tại thời điểm ti và nếu được khám bệnh, anh (cô) ta sẽ phải mất thời gian là di. Hãy
tính xem thời điểm nhỏ nhất mà vị bác sỹ nọ trong phòng khám khám xong cho n
bệnh nhân nói trên.
Dữ liệu: Vào từ file văn bản Thoigian.inp
+ Dòng đầu tiên ghi n (n ≤ 100)
+ n dòng tiếp theo, mỗi dòng ghi hai số lần lượt là thời điểm đến khám và thời
gian khám của bệnh nhân
Kết quả: Ghi ra file văn bản Thoigian.out
Một số nguyên duy nhất là đáp số tìm được.

23


Ví dụ:
Thoigian.inp

Thoigian.out
157

8
91 12
56 24
53 44
24 8
66 3
67 5
42 10
33 26


3. Bài tập chủ để tìm kiếm trên mảng
Bài 21. Số thân thiện
Số tự nhiên có rất nhiều tính chất thú vị. Ví dụ với số 23, số đảo ngược của nó là
32. Hai số này có ước chung lớn nhất là 1. Những số như thế được gọi là số thân
thiện, tức là số 23 được gọi là số thân thiện, số 32 cũng được gọi là số thân thiện.
Hãy nhập vào 2 số nguyên a,b (10≤a≤b≤30000). Hãy đếm xem trong khoảng từ
a đến b (kể cả a và b) có bao nhiêu số thân thiện.
Dữ liệu: Vào từ file văn bản Thanthien.inp
Bao gồm một dòng chứa 2 số a,b. Hai số được cách nhau bằng một khoảng trắng
Kết quả: Ghi ra file văn bản Thanthien.out
Bao gồm một dòng là kết quả của bài tốn.
Ví dụ:
Thanthien.inp
20 30

Bài 22. Xây hàng rào

Thanthien.out
3

24

Vào cuối năm, một người thợ mộc dọn lại nhà kho của mình thì thấy trong kho
8
cịn thừa n cọc gỗ nhỏ (1<=n<=10 ). Để tiết kiệm, ông quyết định sử dụng số cọc đó


để xây hàng rào quanh vườn. Nhưng do độ dài các cọc chênh lệch nhau quá lớn nên
5

ông chỉ chọn ra 1 số cọc nằm trong khoảng [x;y] (x,y là những số thực và 0xây.
Yêu cầu : Hãy giúp người đó tính số cọc người đó chưa sử dụng.
Dữ liệu: Vào từ file văn bản sococ.inp
- Dòng đầu gồm 1 số nguyên n và 2 số thực x,y. Mỗi số cách nhau 1 dấu cách. Dòng tiếp theo gồm n số thực ai.
Mỗi số cách nhau 1 dấu cách.
Kết quả: Ghi ra file văn bản sococ.out
Xuất ra số cọc người đó chưa sử dụng.
Ví dụ:
Sococ.inp
5 0.2 0.8

Sococ.out
3

0.1 0.02 0.3 0.8 1

Bài 23. Số vé
Một rạp hát bán vé để chuẩn bị cho buổi diễn. Lần này cách kiểm vé của họ khác
với những lần trước. Trên mỗi vé họ bán ra có in một số bất kì khác 0. Những người
ngồi hàng ghế đầu thì số trên vé chia hết cho 3. Những người ngồi hàng ghế thứ 2 thì
số trên vé là số âm chẵn, những người ngồi hàng ghé cuối là các số còn lại. Do một
vài sơ suất người in vé đã in trên 1 số vé số vừa chia hết cho 3, vừa là số âm chẵn. Để
khắc phục thì những người có vé in các số đó đều được tính vào cả 2 hàng ghế.
Yêu cầu: Viết chương trình tìm số vé đã bán ra, số người ngồi hàng ghế đầu
và số người ngồi hàng ghế sau
Dữ liệu: Vào từ file văn bản Sove.inp
- Một dòng duy nhất ghi các số được in trên vé
Kết quả: Ghi ra file văn bản Sove.out
- Số vé bán được

- Số người ngồi ghế hàng 1
- Số người ngồi ghế hàng thứ 2
Ví dụ:

25


×