Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 72 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
72
Dung lượng
521,26 KB
Nội dung
Thi HSG Quốc gia 2010 CCKLK: Dãy con chung không liền kề dài nhất Cho dãy số nguyên dương x = (x 1 , x 2 , , x n ). Dãy y = (x i1 , x i2 , , x ik ) được gọi là dãy con không liền kề của dãy x nếu 1 i1 < i2 1 < < ik 1 n. Cho 2 dãy số nguyên a gồm n phần tử và b gồm m phần tử. Xác định chiều dài k của dãy con chung không liền kề dài nhất của a và b. 2 m, n 1000, 1 ai, bi 10000. CCKLK.INP CCKLK.OUT Giải thích 5 6 1 5 3 8 2 2 1 3 4 2 6 2 CCKLK.INP: Dòng đầu: n m. Từ dòng thứ hai trở đi: Dãy số a, tiếp đến là dãy số b. CCKLK.OUT: k. Thuật toán Quy hoạch động. Gọi d(i,j) là đáp số của bài toán khi xét hai dãy a[1 i] và b[1 j]. Ta có: Nếu i ≤ 0 thì ta quy ước d(i,j) = 0, Nếu a[i] = b[j] thì d(i,j) = d(i−2,j−2), Nếu a[i] ≠ b[j] thì d(i,j) = max { d(i−1,j), d(i,j−1) }. Để cài đặt ta dùng 3 mảng một chiều x, y và z với ý nghĩa x[j] = d(i−2,j), y[j] = d(i−1,j) và z[j] = d(i,j). Khi đó hệ thức trên được viết là: Nếu i ≤ 0 thì ta quy ước d(i,j) = 0, Nếu a[i] = b[j] thì d(i,j) = d(i−2,j−2) ứng với z[j] = x[j−2], Nếu a[i] ≠ b[j] thì d(i,j) = max { d(i−1,j), d(i,j−1) } ứng với z[j] = max { y[j], z[j−1] }. Muốn tránh các phép copy dữ liệu từ y sang x; từ z sang y và từ x sang z ta chỉ cần tráo đổi các con trỏ mảng. Độ phức tạp O(n.m) Chương trình Pascal (* CCKLK.PAS k: chieu dai day con chung khong lien ke dai nhat cua hai day so nguyen duong a[1 n], b[1 m] *) const fn = 'ccklk.inp'; gn = 'ccklk.out'; bl = #32; nl = #13#10; mn = 1001; type int = integer; mi1 = array[0 mn] of int; var n, m: int; a, b: mi1; function Max(a,b: int): int; begin if a >= b then Max := a else Max := b; end; procedure Doc; var i: int; f: text; begin assign(f,fn); reset(f); read(f,n, m); writeln(n,bl,m); for i := 1 to n do read(f,a[i]); for i := 1 to m do read(f,b[i]); write(nl, 'a: '); for i := 1 to n do write(a[i],bl); write(nl, 'b: '); for i := 1 to n do write(b[i],bl); close(f); end; procedure Ghi(k: int); var g: text; begin assign(g,gn); rewrite(g); writeln(g,k); close(g); end; (* d(i,j) = dap so cua bai toan voi a[1 i], b[1 j] d(i,j) = d(i-2,j-2) + 1, if a[i] = b[j] = Max begin d(i,j-1), d(i-1,j) end;, elsewhere = 0, if i < 1 || j < 1 *) function QHD: int; var i, j, v: int; c: array[1 3] of mi1; x, y, z, t: int; begin x := 1; y := 2; z := 3; { Init i = 0 } fillchar(c[x],sizeof(c[x]), 0); { Init i = 1 } c[y][0] := 0; v := 0; for j := 1 to m do begin if (a[1] = b[j]) then v := 1; c[y][j] := v; end; v := 0; for i := 2 to n do begin c[z][0] := 0; if (a[i] = b[1]) then v := 1; c[z][1] := v; for j := 2 to m do if (a[i] = b[j]) then c[z][j] := c[x][j-2]+1 else c[z][j] := Max(c[z][j-1],c[y][j]); t := x; x := y; y := z; z := t; end; QHD := c[y][m]; end; BEGIN Doc; Ghi(QHD); write(nl,' Fini '); readln; END. Chương trình CPP /* DevC++ CCKLK.CPP k: chieu dai day con chung khong lien ke dai nhat cua hai day so nguyen duong a[1 n], b[1 m] */ #include <fstream> #include <iostream> using namespace std; // D A T A A N D V A R I A B L E const char * fn = "ccklk.inp"; const char * gn = "ccklk.out"; const int mn = 1001; int n, m; int a[mn],b[mn]; // P R O T O T Y P E S void Doc(); int QHD(); // Quy hoach dong void Ghi(int); int Max(int,int); // I M P L E M E N T A T I O N int main() { Doc(); Ghi(QHD()); cout << endl << " Fini "; cin.get(); return 0; } int Max(int a, int b) { return (a >= b) ? a : b; } void Doc() { int i; ifstream f(fn); f >> n >> m; cout << endl << n << " " << m; for (i = 1; i <= n; ++i) f >> a[i]; for (i = 1; i <= m; ++i) f >> b[i]; cout << endl << "a: "; for (i = 1; i <= n; ++i) cout << a[i] << " "; cout << endl << "b: "; for (i = 1; i <= m; ++i) cout << b[i] << " "; f.close(); } void Ghi(int k) { ofstream g(gn); g << k; g.close(); } /* d(i,j) = dap so cua bai toan voi a[1 i], b[1 j] d(i,j) = d(i-2,j-2) + 1, if a[i] = b[j] = Max { d(i,j-1), d(i-1,j) }, elsewhere = 0, if i < 1 || j < 1 */ int QHD() { int *x, *y, *z, *t; int i, j , m1 = m+1, v ; x = new int[m1]; y = new int[m1]; z = new int[m1]; // Init i = 0 memset(x,0,sizeof(int)*m1); // Init i = 1 y[0] = 0; v = 0; for (j = 1; j <= m; ++j) { if (a[1] == b[j]) v = 1; y[j] = v; } v = 0; for (i = 2; i <= n; ++i) { z[0] = 0; if (a[i]==b[1]) v = 1; z[1] = v; for (j = 2; j <= m; ++j) z[j] = (a[i] == b[j]) ? x[j-2]+1 : Max(z[j-1],y[j]); t = x; x = y; y = z; z = t; } v = y[m]; delete x; delete y; delete z; return v; } Ổn định Cho đồ thị có hướng gồm n đỉnh và m cung (u,v). Cho trước đỉnh s. Một đỉnh d ≠ s được gọi là ổn định đối với s nếu có ít nhất hai đường đi ngắn nhất từ s tới d. Hãy tính k là số lượng đỉnh ổn định đối với đỉnh s. 2 n 10000, 1 m 50000. ONDINH.INP ONDINH.OUT Giải thích 6 7 1 1 2 1 4 2 3 2 5 4 5 2 3 5 6 2 ONDINH.INP: Dòng đầu: n m s. Từ dòng thứ hai trở đi:m cung dạng u v. Có thể có các cung trùng nhau (dư thừa). ONDINH.OUT: k. Thí dụ cho biết: có 3 đỉnh ổn định đối với đỉnh 1 là các đỉnh 5 và 6. 1 → 2 → 5; 1 → 4→ 5; 1 → 2 → 5→ 6; 1 → 4→ 5→ 6. Thuật toán Dùng một biến thể của thuật toán Dijkstra. // Ondinh.CPP // HSG 2010 #include <string.h> #include <fstream> #include <iostream> //#include <mem.h> using namespace std; // D A T A A N D V A R I A B L E S char * fn = "ondinh.inp"; char * gn = "ondinh.out"; const int mn = 10001; const int mm = 50001; typedef struct { int a, b; } cung; cung c[mm]; int len[mn]; // len[i] chieu dai s => i char mark[mn]; // mark[i] danh dau dinh i: // Chua xet 0; Co trong hang doi q 1; Da xu li 2 int d[mn]; // d[i] so luong duong ngan nhat s => i int q[mn]; // hang doi int n, m, s ; // so dinh n, so cung m, dinh xuat phat s // P R O T O T Y P E S int main(); void Doc(); int XuLi(); int Min(int, int); int BinSearch(cung [], int, int, int); int Sanh(int,int,int,int); void Ghi(); int main(){ Doc(); XuLi(); Ghi(); cout << endl << " Fini"; cin.get(); return 0; } int Min(int a, int b) { return (a <= b) ? a : b; } void Ghi() { int i, k = 0; for (i = 1; i <= n; ++i) if (d[i] > 1) ++k; ofstream g(gn); g << k; g.close(); } int XuLi() { int i, j, k, v, r; v = 0; r = 0; memset(mark,0,sizeof(mark)); memset(d,0,sizeof(d)); len[s] = 0; d[s] = 1; q[++v] = s; while (r < v) { // 1 i = q[++r]; cout << endl << " Xet dinh " << i; mark[i] = 2; for (k = BinSearch(c,m,i,0); c[k].a == i; ++k) { // 2 j = c[k].b; // xet cac dinh j ke dinh i if (mark[j] == 0) { len[j] = len[i]+1; mark[j] = 1; d[j] = d[i]; q[++v] = j; } else if (mark[j] == 1) { if (len[i]+1 == len[j]) d[j]++; } } // 2 } // 1 for (i = 1; i <= n; ++i) cout << d[i] << " "; } int Sanh(int u1, int v1, int u2, int v2) { if (u1 < u2) return -1; if (u1 > u2) return 1; // u1 == u2 if (v1 < v2) return -1; if (v1 > v2) return 1; return 0; } int BinSearch(cung c[], int k, int u, int v) { int d = 1, m; while (d < k) { m = (d + k) / 2; if (Sanh(c[m].a,c[m].b,u,v) < 0) d = m+1; else k = m; } return d; } void Doc() { int i, j, u, v, k = 0; ifstream f(fn); f >> n >> m >> s; cout << endl << n << " " << m << " " << s; // The first edge (u,v) f >> u >> v; ++k; c[k].a = u; c[k].b = v; for (i = 2; i <= m; ++i) { f >> u >> v; j = BinSearch(c,k,u,v); if (Sanh(c[j].a,c[j].b,u,v) != 0) { if (Sanh(c[j].a,c[j].b,u,v) < 0) { ++k; c[k].a = u; c[k].b = v; } else { memmove(&c[j+1], &c[j], (k-j+1)*sizeof(cung));// <mem.h> c[j].a = u; c[j].b = v; ++k; } } } f.close(); m = k; } // Ondinh.CPP Phuong an cu // HSG 2010 #include <string.h> #include <fstream> #include <iostream> //#include <mem.h> using namespace std; // D A T A A N D V A R I A B L E S char * fn = "ondinh.inp"; char * gn = "ondinh.out"; const int mn = 10001; const int mm = 50001; typedef struct { int a, b; } cung; cung c[mm]; int p[mn]; char d[mn]; int s[mn]; int n, m, x; // so dinh n, so cung m, dinh xuat phat x // P R O T O T Y P E S int main(); void Doc(); int XuLi(); int Minp(); int Min(int, int); int BinSearch(cung [], int, int, int); int Sanh(int,int,int,int); void Ghi(); int main(){ Doc(); XuLi(); Ghi(); cout << endl << " Fini"; cin.get(); return 0; } int Min(int a, int b) { return (a <= b) ? a : b; } int Minp() { int i, imin = 0; for (i = 1; i <= n; ++i) if (!d[i] && p[i] < p[imin]) imin = i; d[imin] = 1; return imin; } void Ghi() { int i, k = 0; for (i = 1; i <= n; ++i) if (s[i] > 1) ++k; ofstream g(gn); g << k; g.close(); } int XuLi() { int i, imin, j, k; memset(d,0,sizeof(d)); for (i = 2; i <= n; ++i) s[i] = 0; s[x] = 1; p[0] = n+2; p[x] = 0; for (i = 2; i <= n; ++i) p[i] = n+1; for (i = 1; i <= n; ++i) { imin = Minp(); for (k = BinSearch(c,m,imin,0); c[k].a == imin; ++k) { j = c[k].b; if (!d[j]) { if (p[imin]+1 < p[j]) { p[j] = p[imin]+1; s[j] = s[imin]; } else if (p[imin]+1 == p[j]) ++s[j]; } } } } int Sanh(int u1, int v1, int u2, int v2) { if (u1 < u2) return -1; if (u1 > u2) return 1; // u1 == u2 if (v1 < v2) return -1; if (v1 > v2) return 1; return 0; } int BinSearch(cung c[], int k, int u, int v) { int d = 1, m; while (d < k) { m = (d + k) / 2; if (Sanh(c[m].a,c[m].b,u,v) < 0) d = m+1; else k = m; } return d; } void Doc() { int i, j, u, v, k = 0; ifstream f(fn); f >> n >> m >> x; // The first edge (u,v) f >> u >> v; ++k; c[k].a = u; c[k].b = v; for (i = 2; i <= m; ++i) { f >> u >> v; j = BinSearch(c,k,u,v); if (Sanh(c[j].a,c[j].b,u,v) != 0) { if (Sanh(c[j].a,c[j].b,u,v) < 0) { ++k; c[k].a = u; c[k].b = v; } else { memmove(&c[j+1], &c[j], (k-j+1)*sizeof(cung));// <mem.h> c[j].a = u; c[j].b = v; ++k; } } } f.close(); m = k; } Mã số thuế Xét tập S gồm tất cả các số 1 n trong hệ 36, 36 n 10 16 . Cho số m: 3 m 70. Xét dãy số nguyên 1 < c 1 < c 2 < < c k < 36, k = (m 1)/2 , x là số nguyên lớn nhất không vượt quá x. Chọn các số chứa các chữ số < c1 cấp cho 2 nhóm 1 và 2 rồi xóa các số này. Chọn các số chứa các chữ số < c2 cấp cho 2 nhóm 3, 4 Các số còn lại cấp cho 1 hoặc 2 nhóm cuối. Nhóm le: từ nhỏ, nhóm chẵn: từ lớn. Cho các số hệ 10: n, m, ci, p và q. Xác định mã (hệ 36) cấp cho ng thứ q nhóm p. Thí dụ: n = 50, m = 3, p = 2, q = 2, c1 = 16. 1d Căt đoạn Cho hình chữ nhật OABC, OA = n, OC = m, coi O là gốc tọa độ (0,0). Trong hình CN cho k đoạn thẳng đứng. Tìm điểm P trên BA hoặc BC để đoạn OP cắt nhiều đoạn nhất. Đoạn khác nhau Cho dãy a gồm n số nguyên dương. Một đoạn của dãy a, kí hiệu a[i j] là dãy gồm các phần tử đứng liên tiếp nhau trong dãy a, kể từ phần tử a i đến phần tử a j , a[i j] = (a i , a i+1 , ,a j-1 , a j ), 1 i <= j n. Hãy tìm đoạn dài nhất gồm các phần tử đôi một khác nhau. 1 n, a i 100000. Dữ liệu vào: Tệp văn bản diff.inp Dòng đầu tiên: số n. Từ dòng thứ hai trở đi: dãy số a. Dữ liệu ra: Tệp văn bản diff.out chứa 2 số: imax chỉ số đầu tiên của đoạn dài nhất tìm được trong dãy a dmax số phần tử của doạn dài nhất. Các số trên cùng dòng cách nhau qua dấu cách. diff.inp diff.out Giải thích 10 5 2 4 1 5 3 2 7 6 9 3 8 Tính từ phần tử thứ 3 có cả thảy 8 số đôi một khác nhau là 4 1 5 3 2 7 6 9 Thuật toán Lần lượt đọc các phần tử a i của dãy a và đánh dấu vị trí xuất hiện của a i trong dãy thông qua mảng p, p[a i ] = i. Với thí dụ đã cho, sau khi đọc và xử lý xong dãy a ta phải thu được i 1 2 3 4 5 6 7 8 9 10 a i 5 2 4 1 5 3 2 7 6 9 p 4 2/7 6 3 1/5 9 8 0 10 0 p[2] = 2/7 cho biết số 2 lúc đầu xuất hiện tại vị trí 2 trong dãy a, sau đó xuất hiện tại vị trí 7 trong dãy a. p[8] = p[10] = 0 cho biết các số 8 và 10 không xuất hiện trong dãy a. Ta gọi p là dãy trỏ ngược hay dãy vị trí của dãy a. Ta xử lý từng đoạn d của a i như sau. Mỗi đoạn d sẽ bao gồm một dãy liên tiếp các phần tử đôi một khác nhau tính từ chỉ số i đến j. Thí dụ trên cho ta lần lượt 3 đoạn sau: Đoạn thứ nhất d = a[1 4] = (5, 2, 4, 1), i = 1, j = 4, Đoạn thứ hai d = a[2 6] = (2, 4, 1, 5, 3), i = 2, j = 6, Đoạn thứ ba d = a[3 10] = (4, 1, 5, 3, 2, 7, 6, 9), i = 3, j = 10. Mỗi đoạn d được xác định như sau: Mỗi khi gặp phần tử a j đầu tiên trùng với một phần tử trong dãy tính từ i thì ta cắt ra được đoạn d = a[i j1]. Với mỗi đoạn d[i j] ta tính số phần tử của đoạn đó là ji+1 và cập nhật giá trị dmax. Để khởi trị cho đoạn tiếp theo, ta đặt i = p[a j ]+1. Chú ý rằng p[a j ] là vị trí xuất hiện của giá trị lặp a j . Độ phức tạp O(n) Chương trình Pascal (* diff.pas Tim doan dai nhat gom cac phan tu doi mot khac nhau *) const fn = 'diff.inp'; gn = 'diff.out'; bl = #32; nl = #13#10; mn = 100001; var p: array[0 mn] of longint; n: longint; imax, dmax: longint; { imax - chi so dau tien cua doan dai nhat dmax - so phan tu cua doan dai nhat } f,g: text; procedure Run; var i, j, v, istart: longint; begin imax := 0; dmax := 0; fillchar(p,sizeof(p),0); assign(f,fn); reset(f); readln(f,n); read(f,v); { phan tu dau tien trong day } p[v] := 1; istart := 1; for i := 2 to n do begin read(f,v); if (p[v] >= istart) then begin if (i-istart > dmax)then begin dmax := i-istart; imax := istart; end; istart := p[v]+1; [...]... dài nhất Cho dãy a gồm n số nguyên dương Hãy tìm đoạn dài nhất gồm các phần tử tạo thành một hoán vị của dãy số nguyên dương liên tiếp s, s+1, ,k; 1 n, ai 100000 Dữ liệu vào: Tệp văn bản hvskmax.inp Dòng đầu tiên: số n Từ dòng thứ hai trở đi: dãy số a Dữ liệu ra: Tệp văn bản hvskmax.out chứa 2 số: imax chỉ số đầu tiên của đoạn dài nhất tìm được trong dãy a dmax số phần tử của đoạn dài. .. Ghi(); } Hoán vị 1k dài nhất IOIcamp Marathon 2005-2006 Cho dãy a gồm n số nguyên dương Hãy tìm đoạn dài nhất gồm các phần tử tạo thành một hoán vị của dãy số tự nhiên 1 k; 1 n, ai 100000 Dữ liệu vào: Tệp văn bản hv1kmax.inp Dòng đầu tiên: số n Từ dòng thứ hai trở đi: dãy số a Dữ liệu ra: Tệp văn bản hv1kmax.out chứa 2 số: imax chỉ số đầu tiên của đoạn dài nhất tìm được trong dãy a dmax ... Hoán vị 1k Cho dãy a gồm n số nguyên dương đôi một khác nhau Hãy tìm đoạn dài nhất gồm các phần tử tạo thành một hoán vị của dãy (1, 2 , , k), 1 n, ai 100000 Dữ liệu vào: Tệp văn bản hv1k.inp Dòng đầu tiên: số n Từ dòng thứ hai trở đi: dãy số a Dữ liệu ra: Tệp văn bản hv1k.out chứa 2 số: imax chỉ số đầu tiên của đoạn dài nhất tìm được trong dãy a dmax số phần tử của đoạn dài nhất Các số... dãy a gồm n số nguyên dương đôi một khác nhau Hãy tìm đoạn dài nhất gồm các phần tử tạo thành một hoán vị của dãy số tự nhiên liên tiếp (s, s+1 , , k), 1 n, ai 100000 Dữ liệu vào: Tệp văn bản hvsk.inp Dòng đầu tiên: số n Từ dòng thứ hai trở đi: dãy số a Dữ liệu ra: Tệp văn bản hvsk.out chứa 2 số: imax chỉ số đầu tiên của đoạn dài nhất tìm được trong dãy a dmax số phần tử của đoạn dài. .. tử của đoạn dài nhất Các số trên cùng dòng cách nhau qua dấu cách hvsk.inp hvsk.out Giải thích 7 12 1 4 7 8 5 6 3 5 Tính từ phần tử thứ 3 trong dãy a có 5 số liên tiếp tạo thành một hoán vị của 4 8 là a[3 7]: 4 7 8 5 6 Thuật toán Gọi p là dãy trỏ ngược của dãy a Vì dãy a gồm các phần tử đôi một khác nhau nên p cũng chứa các chỉ số đôi một khác nhau Khi đó a chứa một đoạn là hoán vị của dãy số tự nhiên... a dmax số phần tử của đoạn dài nhất Các số trên cùng dòng cách nhau qua dấu cách hv1kmax.inp hv1kmax.out Giải thích 10 12 1 4 1 5 3 2 3 1 2 3 5 Tính từ phần tử thứ 3 trong dãy a có 5 số liên tiếp tạo thành một hoán vị của 1 5 là a[3 7]: 4 1 5 3 2 Thuật toán Duyệt dãy, dựa theo bài diff, xác định từng đoạn ứng viên a[d c] chứa tối đa các phần tử liên tiếp nhau trong dãy a và đôi một khác nhau Với... thủ tục Hv(d,c) xác định và cập nhật đoạn dài nhất trong a[d c] tạo thành một hoán vị của dãy số tự nhiên 1 k Độ phức tạp Chương trình Pascal (* hv1kmax.pas: Tim doan dai nhat gom cac phan tu tao thanh mot hoan vi cua 1 k *) const fn = 'hv1kmax.inp'; gn = 'hv1kmax.out'; mn = 100002; bl = #32; nl = #13#10; var p: array[0 mn] of longint; { p[v] - noi xuat hien gia tri v trong day } n: longint; imax, dmax:... của 1 6 là 4 1 5 3 2 6 Thuật toán Kí hiệu a[i j] là đoạn gồm các phần tử liên tiếp từ ai đến aj của dãy a và kí hiệu set(x) là tập chứa các phần tử (khác nhau) của dãy x Với thí dụ đã cho ta có, a[1 5] = (5, 2, 4, 1, 5) và do đó set(a[1 5]) = {1, 2, 4, 5} Gọi p là dãy vị trí (trỏ ngược) của dãy a Vì dãy a gồm các phần tử đôi một khác nhau nên p cũng chứa các chỉ số đôi một khác nhau Khi đó a chứa một... của đoạn dài nhất Các số trên cùng dòng cách nhau qua dấu cách hvskmax.inp hvskmax.out Giải thích 10 5 1 9 7 5 8 6 3 9 2 3 5 Tính từ phần tử thứ 3 trong dãy a có 5 số liên tiếp tạo thành một hoán vị của 5 9 là a[3 7]: 9 7 5 8 6 Thuật toán Pha 1 Đọc dãy a, với mỗi ai ghi nhận p[ai] = i là vị trí xuât hiện giá trị ai Gọi vmin và vmax lần lượt là giá trị min và max của dãy a Pha 2 Duỵệt dãy giá trị i... tự nhiên ai i = 1 n Hãy tìm đoạn dài nhất gồm các phần tử, trong đó hai phần tử kề nhau thì nguyên tố cùng nhau 1 n, ai 100000 /* Primes.cpp Tim doan dai nhat gom cac so nguyen to cung nhau */ #include #include #include using namespace std; // D A T A A N D V A R I A B L E S const int mn = 100001; const char * fn = "coprime.inp"; . Thi HSG Quốc gia 2010 CCKLK: Dãy con chung không liền kề dài nhất Cho dãy số nguyên dương x = (x 1 , x 2 , , x n ). Dãy y = (x i1 , x i2 , , x ik ) được gọi là dãy con không liền kề của dãy. < i2 1 < < ik 1 n. Cho 2 dãy số nguyên a gồm n phần tử và b gồm m phần tử. Xác định chiều dài k của dãy con chung không liền kề dài nhất của a và b. 2 m, n 1000, 1 . trí 2 trong dãy a, sau đó xuất hiện tại vị trí 7 trong dãy a. p[8] = p[10] = 0 cho biết các số 8 và 10 không xuất hiện trong dãy a. Ta gọi p là dãy trỏ ngược hay dãy vị trí của dãy a. Ta xử