Mối liên hệ giữa mảng và con trỏ

Một phần của tài liệu Giáo trình lập trình cc++ cơ bản (Trang 77 - 89)

Con trỏ là một biến chứa địa chỉ của một vùng nhớ hoặc một biến khác.

Ví dụ 5.6:

int i, j, *p; // p là con trỏ trỏ đến một số nguyên i = 5;

p = &i; // p chứa địa chỉ của biến i

j = *p; // j chứa giá trị tại vùng nhớ do p trỏ tới: j = 5.

*p = j+2; // vùng nhớ do p trỏ tới chứa giá trị j+2, tức lúc này i = j+2 = 7

5.3.2. Con trỏ và mảng

Con trỏ thường được dùng để xử lý mảng.

Ví dụ 5.7: Với các khai báo sau:

int a[10];

int *p;

Ta có thể gán:

p = a; //cho con trỏ p trỏ đến đầu mảng ap = &a[0].

và các cách viết sau là tương đương:

*p  a[0]

*(p + i)  a[i]

p + i  &a[i]

p = p + 4  *p = a[4]

a[i]  *(a + i)

Các cách viết trên là cách khai thác mảng thông qua con trỏ. Mặt khác, có thể khai thác con trỏ thông qua mảng:

p[i] thay cho *(p + i) Tức là lúc này p đóng vai trò như một mảng.

Chú ý:

Khi khai báo mảng: địa chỉ của mảng được cấp rõ ràng và đủ kích thước, địa chỉ này không thay đổi. Tên mảng được xem như là một con trỏ hằng trỏ đến vị trí đầu tiên của mảng.

Khi khai báo con trỏ: biến con trỏ phải được gán cho một địa chỉ cụ thể.

Ví dụ 5.8:

int a[10];

a[i] = 0; hoặc *(a + i) = 0; là hoàn toàn hợp lệ Còn

int *p;

p[i] = 0; hoặc *(p + i) = 0; là vô nghĩa vì p chưa được gán địa chỉ của một đối tượng cụ thể nào cả.

BÀI TẬP

Bài tập 5.1: (ARRMAX) Viết chương trình tìm giá trị lớn nhất của một mảng số nguyên gồm N phần tử.

Input:

- Dòng đầu chứa số nguyên: N

- Dòng tiếp theo chứa các phần tử a1,…,aN

Output: M là số nguyên lớn nhất trong mảng Ví dụ:

INPUT OUTPUT

5

1 2 30 4 5

30

Bài tập 5.2: (SQRSUM) Viết chương trình tính tổng bình phương của các số âm trong một mảng gồm N phần tử.

Input:

- Dòng đầu chứa số nguyên: N

- Dòng tiếp theo chứa các phần tử a1,…,aN

Output: S là tổng bình phương các số âm trong mảng Ví dụ:

INPUT OUTPUT

5

1 -2 30 -4 5

20

Bài tập 5.3: (AVERAGE) Viết chương trình tính trung bình cộng của các số chẵn trong một mảng gồm N phần tử.

Input:

- Dòng đầu chứa số nguyên: N

- Dòng tiếp theo chứa các phần tử a1,…,aN

Output: T là trung bình cộng của các số chẵn trong mảng, làm tròn đến 2 chữ số thập phân.

Ví dụ:

INPUT OUTPUT

5

1 2 3 4 5

3.00

Bài tập 5.4: (MERGEARR) Cho 2 mảng số nguyên đã được sắp xếp theo thứ tự tăng dần. Hãy trộn 2 mảng đó lại thành mảng C sao cho mảng C vẫn có thứ tự tăng dần.

Input:

- Dòng đầu chứa 2 số nguyên: M, N

- Dòng tiếp theo chứa các phần tử a1,…,aM tăng dần - Dòng tiếp theo chứa các phần tử b1,…,bN tăng dần Output:

- Dòng đầu ghi: M+N

- Dòng sau ghi: C1, C2,…, CM+N tăng dần Ví dụ:

INPUT OUTPUT

5 3 1 3 5 7 9 2 4 6

8

1 2 3 4 5 6 7 9 Gợi ý:

- Dùng 2 chỉ số i,j để duyệt qua các phần tử của 2 mảng A, B và k là chỉ số cho mảng C.

- Trong khi (i<m) và (j<n) thì:

/*Tức trong khi cả 2 dãy A, B đều chưa duyệt hết */

+ Nếu A[i]>B[j] thì: C[k]=A[i]; i=i+1;

+ Ngược lại: C[k]=B[j]; j=j+1;

- Nếu dãy nào hết trước thì đem phần còn lại của dãy kia bổ sung vào cuối dãy C.

Bài tập 5.5: (ASCEND) Cho dãy các số nguyên gồm N phần tử. Hãy kiểm tra dãy số đã được sắp theo thứ tự tăng dần hay chưa? (TRUE:

đã sắp tăng dần, FALSE: chưa sắp tăng).

Input:

- Dòng đầu chứa số nguyên: N

- Dòng tiếp theo chứa các phần tử a1,…,aN

Output: TRUE/FALSE Ví dụ:

INPUT OUTPUT

5

1 2 3 4 5

TRUE

Bài tập 5.6: (DAYTANG) Viết chương trình nhập vào một dãy số nguyên a1, a2, ..., an. Tìm độ dài dãy con tăng dần dài nhất. (Dãy con là dãy các phần tử liên tiếp nhau trong mảng).

Input:

- Dòng đầu chứa số nguyên: N

- Dòng tiếp theo chứa các phần tử a1,…,aN

Output: S là độ dài dãy con tăng dần dài nhất Ví dụ:

INPUT OUTPUT

10

9 12 2 2 3 7 8 5 10 15

5

Bài tập 5.7: (SETNUM) Cho n số nguyên dương a1, a2,..., an (1 ≤ n, ai ≤ 106). Hãy xác định số lượng các phần tử khác nhau trong dãy số đã cho.

Input:

- Dòng đầu chứa số nguyên dương n.

- Dòng sau chứa n số nguyên a1, a2,..., an.

Output: một số nguyên S là số các phần tử khác nhau trong dãy số đã cho.

Ví dụ:

INPUT OUTPUT

5

4 1 4 2 1

3

Bài tập 5.8: (SUPASCEN) Dãy số nguyên dương được gọi là dãy siêu tăng nếu kể từ phần tử thứ hai trở đi, mỗi phần tử không nhỏ hơn tổng của các phần tử đứng trước đó.

Ví dụ: a = {1, 5, 6, 15, 30} là dãy siêu tăng; b = {1, 5, 9, 10, 21}

không phải là dãy siêu tăng.

Cho dãy số nguyên dương {a} gồm n phần tử (n≤50, a<1018).

Hãy kiểm tra tính siêu tăng của dãy a.

Input:

- Dòng đầu chứa số nguyên dương n.

- Dòng sau chứa n số nguyên a1, a2,..., an. Output: TRUE/FALSE ứng với dãy siêu tăng.

Ví dụ:

INPUT OUTPUT

5

1 5 6 15 30

TRUE

INPUT OUTPUT

5

1 5 9 10 21

FALSE

Bài tập 5.9: (DEL) (Olympic Tin học 2012, khối Không Chuyên) Cho dãy số nguyên không âm a1, a2, . . , an. Người ta tiến hành chọn ra 2 chỉ số i, j sao cho 1 ≤ i < 𝑗 ≤ 𝑛 và xóa khỏi dãy 2 số ai, aj để tổng giá trị các số còn lại trong dãy là số chẵn.

Yêu cầu: Cho dãy số a1, a2, . . , an. Hãy đếm số lượng cách chọn 2 chỉ số i, j thỏa mãn. Hai cách chọn khác nhau nếu tồn tại một chỉ số khác nhau.

Input:

- Dòng 1: chứa số nguyên n (n ≤ 106)

- Dòng 2: chứa n số nguyên không âm a1, a2, . . , an (ai ≤ 109) Output: Một số nguyên là số cách chọn 2 chỉ số thỏa mãn.

Ví dụ:

INPUT OUTPUT

5

1 2 3 4 5

6

Bài tập 5.10: (FSEQ) (Olympic Tin học 2013, khối Cao đẳng)

Một dãy số gồm n số nguyên f1,f2,…,fn được gọi là dãy có tính chất của dãy số Fibonacci nếu n≥3 và với mọi số fi (i≥3 ) thỏa mãn điều kiện fi = fi-1 + fi-2.

Ví dụ, dãy 1, 1, 2, 3, 5, 8 là dãy số có tính chất của dãy số Fibonacci; còn dãy 3, 3, 6, 9, 14, 23 không phải là dãy số có tính chất của dãy số Fibonacci.

Yêu cầu: Cho dãy số nguyên a1, a2,…,an. Hãy tìm một dãy con liên tiếp gồm nhiều phần tử nhất của dãy số đã cho có tính chất của dãy số Fibonacci.

Input:

- Dòng đầu chứa số nguyên n (3 ≤ n ≤ 30000)

- Dòng thứ hai chứa n số nguyên a1, a2,…,an (|ai| ≤ 109).

Output: Một số nguyên là số lượng phần tử của dãy con tìm được, ghi -1 nếu không tồn tại dãy con liên tiếp nào của dãy có tính chất của dãy số Fibonacci.

Ví dụ:

INPUT OUTPUT

7

1 3 3 6 9 14 23

4

Bài tập 5.11: (USEQ) (Olympic Tin học 2015, khối Cao đẳng) Người ta định nghĩa dãy số nguyên dương 𝑎1,𝑎2,…,𝑎𝑛 đồng đẳng với dãy số nguyên dương 𝑏1,𝑏2,…,𝑏𝑛 nếu với mọi 𝑖,𝑗 (𝑖=1,2,…,𝑛;𝑗=1,2,…,𝑛) đều thỏa mãn:

 Nếu 𝑎𝑖<𝑎𝑗 thì 𝑏𝑖<𝑏𝑗;

 Nếu 𝑎𝑖=𝑎𝑗 thì 𝑏𝑖=𝑏𝑗;

 Nếu 𝑎𝑖>𝑎𝑗 thì 𝑏𝑖>𝑏𝑗;

Yêu cầu: Cho hai dãy số nguyên dương 𝑎1,𝑎2,…,𝑎𝑛 và 𝑏1,𝑏2,…,𝑏𝑛, hãy kiểm tra xem hai dãy có đồng đẳng hay không?

Input:

- Dòng đầu ghi số nguyên dương 𝑇 là số bộ dữ liệu;

- 𝑇 nhóm dòng sau, mỗi nhóm dòng tương ứng với một bộ dữ liệu có khuôn dạng:

o Dòng đầu của nhóm chứa số nguyên 𝑛 (n≤80);

o Dòng thứ hai gồm 𝑛 số nguyên dương 𝑎1,𝑎2,…,𝑎𝑛 (𝑎𝑖≤109);

o Dòng thứ ba gồm 𝑛 số nguyên dương 𝑏1,𝑏2,…,𝑏𝑛 (𝑏𝑖≤109);

Output: Gồm 𝑇 dòng tương ứng với 𝑇 bộ dữ liệu trong dữ liệu vào, mỗi dòng ghi YES nếu hai dãy đồng đẳng, ghi NO nếu hai dãy không đồng đẳng.

Ví dụ:

INPUT OUTPUT

2 3 3 5 1 5 24 4 3 2 8 1 20 24 22

YES NO

Bài tập 5.12: (CABLE) Cho N đoạn dây có độ dài L1,L2,...,LN. Yêu cầu cắt các đoạn dây này thành K đoạn bằng nhau với độ dài lớn nhất có thể được. Nếu như không thể nhận được K đoạn có độ dài 1, đưa ra 0.

Giới hạn : 1≤ N, K ≤10000, 100≤Li≤10000000 tất cả là số nguyên, thời gian 1 giây.

Input:

- Dòng đầu tiên chứa số hai số N và K. N

- Dòng tiếp theo-là các số L1,L2,...,LN , mỗi số trên một dòng.

Output: Một số X là độ dài của các đoạn thẳng.

Ví dụ:

INPUT OUTPUT 4 11

802 743 457 539

200

Bài tập 5.13: (SYMABILITY) Dãy số nguyên được gọi là dãy khả đối xứng nếu có thể sắp xếp lại thành một dãy đối xứng. Cho dãy số nguyên gồm n phần tử (n>0). Hãy kiểm tra dãy có phải là khả đối xứng?

Input:

- Dòng đầu: n (n<106).

- Dòng sau ghi n số nguyên a1, a2,...,an (ai<1018).

Output: TRUE/FALSE tương ứng với khả đối xứng.

Ví dụ:

INPUT OUTPUT

5

1 5 6 5 6

TRUE

Bài tập 5.14: (MINSEG) Cho dãy số nguyên không âm, tìm đoạn ngắn nhất có tổng bằng k.

Input:

- N, k (N<10000: số phần tử của dãy, k<1018).

- a1,…,aN (ai<106) Output:

- L, R (chỉ số đầu và cuối của dãy ngắn nhất đầu tiên tìm được) Ví dụ:

INPUT OUTPUT

12 10

2 1 5 3 2 0 9 1 0 5 0 41

7 8

Bài tập 5.15: (MATSUM) Viết chương trình tính tổng 2 ma trận vuông A, B cấp n.

Input:

- Dòng đầu: n < 103

- n dòng tiếp theo, mỗi dòng chứa n số nguyên của ma trận A.

- n dòng tiếp theo, mỗi dòng chứa n số nguyên của ma trận B.

Output: Ma trận kết quả C Ví dụ:

INPUT OUTPUT

2 1 2 3 4 5 6 7 8

6 8 10 12

Gợi ý:

Công thức tính tổng 2 ma trận: Cij = Aij + Bij

Bài tập 5.16: (MATMUL) Viết chương trình tính tích 2 ma trận vuông A, B cấp n.

Input:

- Dòng đầu: n < 103

- n dòng tiếp theo, mỗi dòng chứa n số nguyên của ma trận A.

- n dòng tiếp theo, mỗi dòng chứa n số nguyên của ma trận B.

Output: Ma trận kết quả C Ví dụ:

INPUT OUTPUT

2 1 2 3 4 5 6 7 8

19 22 43 50

Công thức tính tích 2 ma trận: Cij =

n

k

kj

ik B

A

1

*

Bài tập 5.17: (PASCAL) Viết chương trình in ra màn hình tam giác Pascal.

Input: N

Output: Ma trận tam giác Pascal Ví dụ:

INPUT OUTPUT

4 1

1 1

1 2 1

1 3 3 1

1 4 6 4 1

Ý tưởng:

Tam giác Pascal được tạo ra theo qui luật sau:

+ Mỗi dòng đều bắt đầu và kết thúc bởi số 1.

+ Phần tử thứ j ở dòng i nhận được bằng cách cộng 2 phần tử thứ j-1 và j ở dòng thứ i-1: a(i,j) = a(i-1,j-1) + a(i-1,j).

Bài tập 5.18: Viết chương trình in ra các số nguyên từ 1 đến N2 theo hình xoắn ốc với N được nhập vào từ bàn phím. Ví dụ, với N=5 ta có:

1 2 3 4 5

16 17 18 19 6 15 24 25 20 7 14 23 22 21 8 13 12 11 10 9

Bài tập 5.19: Viết chương trình nhập vào số tự nhiên N (N lẻ), sau đó điền các số từ 1 đến n2 vào trong một bảng vuông sao cho tổng các hàng ngang, hàng dọc và 2 đường chéo đều bằng nhau (bảng này được gọi là Ma phương).

Ví dụ: Với N=3 và N=5 ta có

Bắc

2 7 6 3 16 9 22 15

9 5 1 20 8 21 14 2

4 3 8 Tây 7 25 13 1 19 Đông 24 12 5 18 6

11 4 17 10 23 Nam

Phuơng pháp:

Xuất phát từ ô bên phải của ô nằm giữa. Đi theo hướng đông bắc để điền các số 1, 2, ...

Khi điền số, cần chú ý một số nguyên tắc sau:

- Nếu vượt ra phía ngoài bên phải của bảng thì quay trở lại cột đầu tiên.

- Nếu vượt ra phía ngoài bên trên của bảng thì quay trở lại dòng cuối cùng.

- Nếu số đã điền k chia hết cho N thì số tiếp theo sẽ được viết trên cùng một hàng với k nhưng cách 1 ô về phía bên phải.

Một phần của tài liệu Giáo trình lập trình cc++ cơ bản (Trang 77 - 89)

Tải bản đầy đủ (PDF)

(176 trang)