You are on page 1of 12

Chuyên đề cụm Đông Hà

“Một số kỹ thuật trên mảng một chiều thường gặp trong các bài toán về dãy số ”.

Nguyễn Thần Phong


THPT Chuyên Lê Quý Đôn

Mục Lục
1. Mở đầu .....................................................................................................................................2
2. Nội dung chuyên đề..................................................................................................................3
a) Mảng cộng dồn (Prefix Sum) ...............................................................................................3
Bài toán 1: ............................................................................................................................3
Bài toán 2: ............................................................................................................................4
b) Đếm phân phối (Distribution Counting)..............................................................................5
Bài toán 1: ............................................................................................................................6
Bài toán 2: ............................................................................................................................8
c) Kỹ thuật hai con trỏ (two-pointer) .......................................................................................9
Bài toán 1: ............................................................................................................................9
Bài toán 2: ..........................................................................................................................10
d) Bài tập ứng dụng................................................................................................................12
3. Kết luận ................................................................................................................................122
1. Mở đầu
Bài toán trong tin học là bài toán xuất phát từ bài toán thực tế, việc xây dựng giải thuật
để giải bài toán tin học bằng máy tính phải bảo đảm những tính chất cơ bản của thuật toán, trong
các tính chất chất cơ bản đó thì yêu cầu về thuật toán sau khi đã được cài đặt chương trình trên
máy tính bằng ngôn ngữ lập trình thì thuật toán phải chạy nhanh, tốn ít thời gian và bộ nhớ.
Khi tiếp cận với một bài toán, tùy theo trình độ của từng học sinh mà mỗi học sinh có cách
phân tích bài toán và lựa chọn thuật toán khác nhau để giải nó. Đối với những học sinh có trình
độ chưa cao, chưa có khả năng phân tích bài toán tốt thường lựa chọn những thuật toán đơn
giản, có độ phức tạp tính toán lớn đồng nghĩa với số điểm nhận được thấp. Để có kết quả tốt
hơn, đòi hỏi học sinh phải có trình độ cao hơn, kỹ năng phân tích bài toán tốt hơn để tìm ra
những thuật toán tốt có độ phức tạp tính toán nhỏ.
Trong những năm học vừa qua phong trào học tập Tin học ngày một sôi nổi, hăng say. Các
em học sinh quan tâm hơn với bộ môn Tin học, thầy cô siêng năng trong việc bồi dưỡng, nghiên
cứu các kiến thức nhằm nâng cao kĩ năng và kiến thức chuyên môn phục vụ tốt hơn trong việc
dạy học của mình.
Các bài toán trên dãy số là một trong những dạng bài tập thường gặp nhất trong các kì thi
học sinh giỏi các cấp. Trong nội dung chuyên đề này tôi trình bày “Một số kỹ thuật trên mảng
một chiều thường gặp trong các bài toán về dãy số ”.
2. Nội dung chuyên đề
a) Mảng cộng dồn (Prefix Sum)
Prefix Sum: là một trong những kỹ thuật thường dùng để giảm độ phức tạp tính toán trên mảng
một chiều với các bài toán truy vấn tính tổng trên các đoạn [𝑙, 𝑟] cho trước, tăng đoạn [𝑙, 𝑟] lên
một giá trị 𝑥.
Bài toán 1: Cho dãy số 𝑎1 , 𝑎2 , … , 𝑎𝑛 . Tính tổng 𝑇 đoạn [l, r] với 1 ≤ 𝑛, 𝑇 ≤ 106 , 1 ≤ 𝑙 ≤
𝑟 ≤ 𝑛.
Thuật toán 1:
Xử lí đơn giản bằng cách duyệt các đoạn [𝑙, 𝑟] để tính tổng với độ phức tạp 𝑂(𝑇 ∗ 𝑛):
cin>>T;
while (T--)
{ long long ans=0;
cin>>l>>r;
for (int i=l; i<= r; ++i) ans= ans +a[i];
cout<<ans<<’\n’;
}
Thuật toán 2:
- Sử dụng mảng cộng dồn để cộng dồn để tính tổng các phần tử trong mảng.
for (int i=1; i<= n; ++i) a[i]= a[i-1] + a[i];
- Với mỗi truy vấn tổng [𝑙, 𝑟] thực hiện truy vấn 𝑎[𝑟] − 𝑎[𝑙 − 1] trong 𝑂(1).
- Ví dụ cho dãy số 4, 7, −3, 8, 2.
𝑖 0 1 2 3 4 5
𝑎 0 4 7 -3 8 2
𝑎 0 4 11 8 16 18
Tính tổng [2, 4] = 𝑎[4] − 𝑎[1] = 16 – 4 = 12.
Chương trình sử dụng kỹ thuật Prefix Sum:
cin>>n;
for (int i=1; i<= n; ++i)
{cin>>a[i]; a[i] = a[i-1] + a[i];}
cin>>T;
while (T--)
{
int l, r;
cin>>l >>r;
cout<<a[r] – a[l-1]<<’\n’;
}. Độ phức tạp 𝑂(𝑚𝑎𝑥(𝑛 , 𝑇)).
Bài toán 2: Đoạn con chia hết cho 𝐾. (Tin học trẻ TP Đông Hà 2019)
Cho dãy số 𝑎1 , 𝑎2 , … , 𝑎𝑛 . và số nguyên K. với hai số L, R cho trước (1 ≤ L ≤ R ≤ N) kiểm
tra xem trong đoạn [L, R] có bao nhiêu số chia hết cho K. ví dụ như cho dãy 2 5 -3 8 6 và K=2,
L=1, R=5 thì có ba số 2, 8, 6 chia hết cho K, với L=2, R=3 thi không có số nào chia hết cho K.
Yêu cầu: cho dãy số 𝑎1 , 𝑎2 , … , 𝑎𝑛 . và số nguyên K, với T đoạn L, R cho trước đếm xem trong
mỗi đoạn đó có bao nhiêu số chia hết cho K.
Dữ liệu vào SEGMENT.INP có cấu trúc như sau:
- Dòng 1 có ba số 𝑁, 𝐾, 𝑇 (N số phần tử của dãy A, T số đoạn con L, R, trong đó |K|≤109);
- Dòng tiếp theo chứa dãy 𝑎1 , 𝑎2 , … , 𝑎𝑛 . (trong đó|ai|≤109);
- T dòng tiếp theo mỗi dòng chứa hai số nguyên dương L, R.
Kết quả vào ghi vào file SEGMENT.OUT gồm có 𝑇 dòng mỗi dòng ghi số lượng phần tử của
đoạn [𝐿, 𝑅] chia hết cho 𝐾.
Ví dụ:
SEGMENT.INP SEGMENT.OUT
521 3
2 5 -3 8 6
15
Ràng buộc:
- 80% test có 𝑁 ≤ 10000, 𝑇 ≤ 10 tương ứng 80% số điểm.
- 20% test có 𝑁 ≤ 1000000, 𝑇 ≤ 1000000 tương ứng 20% số điểm.
Thuật toán 1:
cin>>n>>k>>t;
for (int i=1; i<=n; ++i)
cin>>a[i];
while (t--)
{ cin>>l>>r;
int ans=0;
for (int i=l; i<=r; ++i)
if (a[i]%k==0) ans++;
cout<<ans;}
Thuật toán trên có độ phức tạp 𝑂(𝑛 ∗ 𝑡).
Thuật toán 2:
Để cải tiến độ phức tạp thuật toán về 𝑂(𝑛) ta sử dụng kỹ thuật cộng dồn và tính trước như sau:
for (int i=1; i<=n; ++i)
{
int x; cin>>x;
if (x%k==0) a[i]=a[i-1]+1;
else a[i]=a[i-1];
}
Khi đó mỗi truy vấn đoạn [l, r] thực hiện như sau:
while (t--)
{ int l, r;
cin>>l>>r;
cout<<a[r] – a[l-1];
}
Chương trình giải bài toán trên với độ phức tạp 𝑂(𝑛)
cin>>n>>k>>t;
for (int i=1; i<=n; ++i)
{
int x; cin>>x;
if (x%k==0) a[i]=a[i-1]+1;
else a[i]=a[i-1];
}
while (t--)
{ int l, r;
cin>>l>>r;
cout<<a[r] – a[l-1];
}

Kỹ thuật cộng dồn trên mảng một chiều là một trong những kĩ năng cơ bản cần thiết nhất
đối với mọi học sinh khi tiếp cận với các bài toán lập trình trên mảng đặc biệt là các thao tác
truy vấn liên quan đến các đoạn [𝑙, 𝑟].
b) Đếm phân phối (Distribution Counting)
Kỹ thuật đếm phân phối trên mảng một chiều là một trong những kỹ thuật giảm độ phức
tạp tính toán cũng như không gian bộ nhớ lưu trữ về 𝑂(𝑛). Với dãy số 𝑎1 , 𝑎2 , … , 𝑎𝑛 là các số
nguyên nằm trong đoạn từ 0 tới 𝑘 ta có thuật toán đơn giản và hiệu quả như sau: Xây dựng dãy
C[0], C[1] ,…, C[k], trong đó C[v] (1 ≤ v ≤ k) là số lần xuất hiện khoá v trong dãy.
Ví dụ với dãy có 10 phần tử với dãy khóa: 2, 1, 2, 4, 3, 5, 1, 2, 4, 3
Ta có mảng C như sau:
C[0] C[1] C[2] C[3] C[4] C[5]
0 2 3 2 2 1
Dãy khóa sau khi sắp xếp là: 1, 1, 2, 2, 2, 3, 3, 4, 4, 5
Kỹ thuật đếm phân phối như sau:
cin>>n; memset(C, 0, sizeof(C)); //khởi tạo mảng C có các
giá trị bằng 0.
for (int i=1; i <=n; ++i)
{int x; cin>>x; C[x]++; }
Độ phức tạp của thuật toán là O(max(n,k)).
Bài toán 1: Những con bò (Tuyển sinh chuyên 2019)
Người ta nuôi 𝑁 con bò được đánh số từ 1 đến 𝑁 trong một dãy gồm 𝑁 chuồng đánh số từ
1 đến 𝑁, mỗi chuồng nuôi một con bò. Mỗi con bò được nuôi với một chế độ dinh dưỡng khác
nhau nên người ta chuẩn bị 𝑁 buồng ăn khác nhau, các buồng ăn cũng được đánh số từ 1 đến
𝑁, mỗi buồng sẽ là vị trí ăn của một con bò. Người ta quy định một con bò ở tại một chuồng
phải ăn tại một buồng nào đó cố định. Biết quy định đó của mỗi con bò, bạn hãy viết chương
trình tìm khoảng cách di chuyển hay số chuồng phải đi qua lớn nhất của các con bò khi đi đến
buồng ăn?

Dữ liệu vào từ tệp văn bản COWS.INP gồm:

- Dòng đầu tiên ghi số nguyên dương 𝑁 (2 ≤ 𝑁 ≤ 100000);


- Dòng thứ hai ghi 𝑁 số nguyên dương 𝑎1 , 𝑎2 , … , 𝑎𝑁 . Với nghĩa con bò 𝑎𝑖 (1 ≤ 𝑎𝑖 ≤ 𝑁) ở
tại chuồng 𝑖 (𝑖 = 1, 2, … , 𝑁);
- Dòng thứ ba ghi 𝑁 số nguyên dương 𝑏1 , 𝑏2 , … , 𝑏𝑁 . Với nghĩa con bò 𝑏𝑖 (1 ≤ 𝑏𝑖 ≤ 𝑁) ăn
tại buồng 𝑖 (𝑖 = 1, 2, … , 𝑁).

Kết quả: ghi ra tệp văn bản COWS.OUT gồm một dòng ghi khoảng cách di chuyển lớn nhất của
các con bò khi đi ăn.

Ví dụ:
COWS.INP COWS.OUT
5 4
2 1 5 4 3
3 5 2 4 1
Giải thích: Con bò số hiệu 2 ở chuồng số 1 và ăn tại buồng số 3, …, con bò số hiệu 3 ở
chuồng số 5 và ăn tại buồng số 1, đó cũng là con bò phải đi xa nhất, qua 4 chuồng.

Ràng buộc:

- Thời gian thực hiện một test không quá một giây.
- 50% số tests tương ứng với 50% số điểm của bài có 𝑁 ≤ 1000.
Thuật toán:
- Với mỗi con bò thứ i xác định chuồng đang ở và buồng ăn phải di chuyển đến;
- Đếm phân phối bằng kỹ thuật đánh dấu để đánh dấu vị trí chuồng bò đang ở và buồng ăn
cần phải di chuyển đến như sau:
𝑖 1 2 3 4 5
𝑎 2 1 5 4 3
𝑏 5 3 1 4 2
Vị trí con bò thứ 𝑖 đang ở chuồng 𝑎[𝑖] và phải di chuyển đến buồng ăn 𝑏[𝑖].
cin>>n;
for (int i = 1; i <= n; ++i)
{ int x; cin >> x;
a[x]:=i;
}
for (int i = 1; i <= n; ++i)
{ int x; cin >> x;
b[x]:=i;
}
- Khoảng cách di chuyển lớn nhất của các con bò tính như sau:
int ans=0;
for (int i=1; i <= n; ++i)
ans = max (ans, abs(a[i]-b[i]));
- Độ phức tạp của thuật toán 𝑂(𝑛).
Chương trình:
{
cin>>n;
for (int i = 1; i <= n; ++i)
{ int x; cin >> x;
a[x]:=i;
}
for (int i = 1; i <= n; ++i)
{ int x; cin >> x;
b[x]:=i;
}
int ans=0;
for (int i=1; i <= n; ++i)
ans = max (ans, abs(a[i]-b[i]));
return 0;
}
Bài toán 2: Giao điểm (Tin học trẻ THCS 2019 Quảng Trị)
Cho 𝑛 đoạn thẳng, đoạn thẳng thứ 𝑖 (1 ≤ 𝑖 ≤ 𝑛) bắt đầu từ vị trí 𝑎𝑖 và kết thúc tại vị trí 𝑏𝑖
(1 ≤ 𝑎𝑖 ≤ 𝑏𝑖 ≤ 1.000.000).
Yêu cầu: Đếm số điểm nguyên thuộc ít nhất hai đoạn thẳng trong số 𝑛 đoạn đã cho.
Dữ liệu vào: Đọc từ file GIAODIEM.INP có cấu trúc như sau:
- Dòng đầu ghi số nguyên dương 𝑛;
- 𝑛 dòng tiếp theo, dòng thứ 𝑖 ghi hai số nguyên 𝑎𝑖 và 𝑏𝑖 cách nhau ít nhất một dấu cách.
Kết quả: Ghi ra file GIAODIEM.OUT gồm một số duy nhất là số lượng các điểm thuộc ít nhất
hai đoạn trong số 𝑛 đoạn thẳng đã cho.
Ví dụ:
GIAODIEM.INP GIAODIEM.OUT
4 5
13
23
48
6 10
Ràng buộc:
- Có 60% test có 1 < n ≤ 1.000 tương ứng 60% số điểm;
- Có 40% test có 1.000 < n ≤ 100.000 tương ứng 40% số điểm.
Thuật toán :
- Đọc tọa độ mỗi điểm 𝑖(𝑥, 𝑦) đếm phân phối vào mảng 𝐹.
cin>>n;
for (int i=1;i<=n; ++i)
{ cin >>x >>y;ma=max(ma, y);
F[x]++; F[y+1]--;
}
- Sử dụng cộng dồn (Prefix Sum) từ 0 đến tọa độ lớn nhất.
for (int i=1;i<=ma; ++i)
F[i]=F[i]+F[i-1];
- Với mỗi giá trị 𝑖 nếu xuất hiện lớn hơn 2 lần thì đếm kết quả.
int ans=0;
for (int i = 0;i<= ma;++i)
if (F[i]>=2) ans++;
cout<<ans;
Chương trình giải bài toán giao điểm với độ phức tạp 𝑂(𝑚𝑎𝑥(𝑛, 𝑚𝑎)) với 𝑚𝑎 là vị trí 𝑦 lớn
nhất.
{
cin>>n;
for (int i=1;i<=n; ++i)
{ cin >>x >>y;ma=max(ma, y);
F[x]++; F[y+1]--;
}
for (int i=1;i<=ma; ++i)
F[i]=F[i]+F[i-1];
int ans=0;
for (int i = 0;i<= ma;++i)
if (F[i]>=2) ans++;
cout<<ans;
return 0;
}

Đếm phân phối ngoài áp dụng cho các bài toán tính tần suất hoặc tăng giá trị một đoạn
[𝑥, 𝑦] lên một giá trị 𝑘 thì kỹ thuật đếm phân phối còn áp dụng cho những bài toán đánh dấu
hoặc kết hợp kĩ thuật cộng dồn nhằm giảm độ phức tạp thuật toán như bài toán Giao điểm ở
trên.
c) Kỹ thuật hai con trỏ (two-pointer)
Kỹ thuât hai con trỏ là kỹ thuật sử dụng hai biến song song 𝑖, 𝑗 trong quá trình duyệt trên
một mảng hay hai mảng một chiều giảm độ phức tạp tính toán cũng như không gian tính toán,
bộ nhớ sử dụng.
Bài toán 1: Cho một dãy số nguyên 𝑎1 , 𝑎2 , … , 𝑎𝑛 có 𝑛 phần tử, mảng này đã được sắp xếp
tăng dần. Hãy tìm hai vị trí khác nhau bất kỳ sao cho tổng của hai phần tử ở hai vị trí đó có giá
trị là 𝑥.
Giới hạn : 2 ≤ 𝑛 ≤ 106 , 0 ≤ 𝑎𝑖 , 𝑥 ≤ 106 .
Ví dụ cho dãy 𝑎 = [ 2, 5, 6, 8, 10, 12, 15] và 𝑥 = 16
Nhận xét: yêu cầu đề bài tìm hai vị trí 𝑖, 𝑗 sao cho 𝑎[𝑖] + 𝑎[𝑗] = 𝑥.
𝑎 = [ 2, 5, 𝟔, 8, 𝟏𝟎, 12, 15] ta có 𝑎[3] + 𝑎[5] = 𝑥 suy ra hai vị trí cần tìm là 3 và 5.
Xuất phát với 𝑖, 𝑗 (𝑖 < 𝑗) , dãy số 𝑎 tăng dần tìm kiếm hai vị trí có các trường hợp sau:
- 𝑎[𝑖] + 𝑎[𝑗] > 𝑥: tìm các phần tử trong đoạn [𝑖, 𝑗 − 1];
- 𝑎[𝑖] + 𝑎[𝑗] < 𝑥: tìm các phần tử trongđoạn [𝑖 + 1, 𝑗];
- 𝑎[𝑖] + 𝑎[𝑗] = 𝑥: tìm thấy hai vị trí 𝑖, 𝑗;
- 𝑖 = 𝑗 , 𝑗 < 𝑖 thì không tìm thấy 𝑖, 𝑗 thõa mãn yêu cầu của bài toán.
Từ những phân tích trên đưa ra giải pháp hai con trỏ như sau:
- Một con trỏ 𝑖 bắt đầu ở đầu dãy, con trỏ 𝑗 ở vị trí cuối dãy
- Tổng của 𝑎[𝑖] + 𝑎[𝑗] tại hai vị trí của hai con trỏ có giá trị:
++ Nếu lớn hơn 𝑥 thì vị trí con trỏ 𝑗 giảm đi 1;
++ Nếu bé hơn 𝑥 thì vị trí con trỏ 𝑖 tăng 1;
++ Lặp lại quá trình trên cho đến khi a[i] + a[j] = x hoặc i=j hoặc i>j thì dừng lại.
- Số lần tịnh tiến con trỏ 𝑖 và con trỏ 𝑗 không quá 𝑛 lần. Độ phức thuật toán là 𝑂(𝑛).
Chương trình:
{ cin >> n >> x;
for (int i=1;i<= n; ++i)
cin>>a[i];
int i=1, j=n;
while (i < j)
{ if (a[i] + a[j] <x)
i++;
else if (a[i] + a[j] > x) j--;
else { cout << i <<’ ’<<j;
return 0;}
}
cout<<” khong tim thay hai vi tri thoa man”;
return 0;
}
Bài toán 2: HỘP QUÀ (HSG Lớp 12 2021)
Hộp quà bí ẩn là một mặt hàng thú vị khi mua hàng trên các chợ trực tuyến. Cửa hàng
nhà Huy cũng đang tham gia bán loại hàng này. Cửa hàng đã nhập về 𝑵 món hàng, món thứ 𝒊
có giá là 𝑨𝒊 . Mỗi hộp quà bí ẩn cửa hàng sẽ chọn ra đúng 𝟑 món hàng sao cho mức chênh lệch
giá của món hàng đắt nhất và món hàng rẻ nhất trong số ba món được chọn không vượt quá 𝒅.
Yêu cầu: Hãy giúp cửa hàng đếm số cách khác nhau chọn ra một hộp quà bí ẩn đầu tiên. Hai
cách là khác nhau nếu có một món hàng trong cách này không có mặt trong cách kia.
Dữ liệu vào: Đọc từ tệp HOPQUA.INP có cấu trúc như sau:
- Dòng thứ nhất lần lượt là hai số nguyên 𝑁 và 𝑑 (0 ≤ 𝑑 ≤ 106 );
- Dòng thứ hai là dãy số nguyên 𝐴1 , 𝐴2 , … , 𝐴𝑁 (1 ≤ 𝐴𝑖 ≤ 106 ). Các số cách nhau một dấu cách.

Kết quả: Ghi ra tệp HOPQUA.OUT một số nguyên duy nhất là số cách đếm được.

Ví dụ:
HOPQUA.INP HOPQUA.OUT Giải thích
53 2 Hai cách chọn: {1,2,4}, {4,6,7}
61724
Ràng buộc:
- Có 60% số điểm tương ứng với 1 ≤ 𝑁 ≤ 200; 𝐴𝑖 ≤ 𝐴𝑖+1 với 1 ≤ 𝑖 < 𝑁;
- Có 20% số điểm tương ứng với 1 ≤ 𝑁 ≤ 104 ;
- Có 20% số điểm tương ứng với 1 ≤ 𝑁 ≤ 2 ∗ 106 .
Thuật toán:
- Chọn 3 món quà ở ba vị trí 𝑖, 𝑗, 𝑘 bất kì sao cho 𝑎[𝑖] + 𝑎[𝑗] + 𝑎[𝑘] ≤ 𝑑;
- Sắp xếp dãy số tăng dần theo giá trị. Xét mỗi đoạn [𝑖, 𝑗] thõa mãn 𝑎[𝑗] − 𝑎[𝑖] ≤ 𝑑;
- Với mỗi vị trí 𝑗 + 1 kiểm tra 𝑎[𝑗 + 1] – 𝑎[𝑖] ≤ 𝑑, nếu thỏa mãn thì ta tính số bộ ba thỏa
mãn khi thêm vị trí j+1 sau đó tịnh tiến con trỏ j lên 1, ngược lại tính tiến con trỏ i.
int i=1,j=3;
while (j<= n)
{
while (a[j]-a[i]<=d && j<= n)
{
ans=ans + 1LL*(j-i)*(j-i-1)/2;
j++;
}
i++;
}
- Số lần tăng 𝑖 và 𝑗 không quá 𝑛 lần. Khi tính số bộ ba thỏa mãn có độ phức tạp tính toán
𝑂(𝑛).
- Độ phức tạp của thuật toán trên 𝑂(𝑛𝑙𝑜𝑔𝑛).
Chương trình:
{ long long ans=0
int n,d;
cin>>n>>d;
for (int i=1; i<=n; ++i) cin>>a[i];
sort(a+1,a+n+1);
int i=1,j=3;
while (j<= n)
{
while (a[j]-a[i]<=d && j<= n)
{
ans=ans + 1LL*(j-i)*(j-i-1)/2;
j++;
}
i++;
}
cout<<ans;
return 0;
}
d) Bài tập ứng dụng
- Các bài tập trong các đề thi HSG Tỉnh Quảng Trị (2016 - nay).
- Các đề thi chọn đội tuyển quốc gia (2016 - nay).
- https://oj.vnoi.info/problem/nksgame
- https://codeforces.com/problemset/problem/1251/C
- https://lqdoj.edu.vn/problem/findpair
- https://lqdoj.edu.vn/problem/cntpair02
- https://oj.vnoi.info/problem/twosum
- https://oj.vnoi.info/problem/sopenp
- https://oj.vnoi.info/problem/vmquabeo
- https://codeforces.com/gym/100503/problem/D
- https://oj.vnoi.info/problem/ndccard
3. Kết luận
Trong chuyên đề này tôi trình bày những kỹ thuật cơ bản nhất khi làm việc với mảng một
chiều. Để tăng tốc độ thực hiện chương trình thì việc lựa chọn một thuật toán tối ưu kết hợp kỹ
thuật lập trình tốt thì sẽ giảm được độ phức tạp thuật toán, tiết kiệm được bộ nhớ máy tính cấp
phát và qua đó chương trình sẽ chạy nhanh hơn.
Mảng cộng dồn, đếm phân phối và kỹ thuật hai con trỏ là một trong những kỹ thuật được
sử dụng nhiều nhất trong các bài toán duyệt, mỗi kỹ thuật có những ưu nhược điểm khi sử dụng
nên trong quá trình giảng dạy quý thầy cô tùy vào từng bài toán cụ thể để áp dụng hiệu quả.
Những nội dung trình bày trong chuyên đề này chủ yếu qua kinh nghiệm giảng dạy và
nghiên cứu sách báo hoặc các trang Websites lập trình trực tuyến nên không thể tránh khỏi
những thiết sót, rất mong nhận được ý kiến góp ý phản hồi từ quý thầy cô để chuyên đề được
hoàn thiện hơn.
Xin chân thành cám ơn!

You might also like