Có hai cách để tham chiếu đến các thành phần của cấu trúc tương ứng với hai trường hợp sau:
Nếu nó là biến cấu trúc: dùng phép toán dấu chấm (.) để tham chiếu đến các trường (thành phần) của cấu trúc:
<Tên_Cấu_Trúc>.<Tên_Trường>
Nếu nó là biến con trỏ trỏ đến cấu trúc: dùng phép toán mũi tên (->) để tham chiếu đến các trường:
<Tên_Con_Trỏ_Cấu_Trúc> -> <Tên_Trường>
Ví dụ 7.7: Cho các khai báo sau:
struct Date {
int day;
int month;
int year;
}date;
typedef struct Date DATE;
DATE date, *ps;
Các cách tham chiếu sau là hợp lệ:
date.day = 31;
date.month = 5;
date.year = 1997 hoặc:
ps->day = 31;
ps->month = 5;
ps->year = 1997;
các phép toán con trỏ trên tương đương với (*ps).day = 31;
(*ps).month = 5;
(*ps).year = 1997;
Gán hai biến cấu trúc
struct Date d = {31,5,1997};
struct Date today;
today = d;
Ví dụ 7.8: Viết chương trình quản lý sinh viên với một số chức năng cơ bản sau:
- Nhập vào một mảng gồm n sinh viên.
- In danh sách sinh viên ra màn hình.
- Sắp xếp lại danh sách sinh viên theo thứ tự alphabet.
1. #include <iostream>
2. #include <string>
3. using namespace std;
4.
5. struct SINHVIEN 6. {
7. char name[30];
8. int tuoi;
9. };
10.
11. void Nhap(int &n,SINHVIEN a[]) 12. {
13. cout<<"Nhap so sinh vien: "; cin>>n;
14. for(int i=1;i<=n;i++) 15. {
16. cout<<"Ho ten sinh vien thu "<<i<<": ";
17. fflush(stdin);
18. gets(a[i].name);
19. cout<<"Tuoi sinh vien thu "<<i<<": ";
20. cin>>a[i].tuoi;
21. } 22. } 23.
24. void InDS(int n,SINHVIEN a[]) 25. {
26. cout<<endl<<"Danh sach sinh vien: "<<endl;
27. for(int i=1;i<=n;i++) 28. {
29. cout<<i<<" . "<<a[i].name<<", "<<a[i].tuoi<<endl;
30. } 31. } 32.
33. void Sort(int n,SINHVIEN a[]) 34. {
35. for(int i=1;i<n;i++) 36. for(int j=i+1;j<=n;j++)
37. if(strcmp(a[i].name,a[j].name)>0) 38. {
39. SINHVIEN tam = a[i];
40. a[i] = a[j];
41. a[j] = tam;
42. } 43. } 44.
45. int main() 46. {
47. SINHVIEN sv[50];
48. int n;
49. Nhap(n,sv);
50. InDS(n,sv);
51. Sort(n,sv);
52. InDS(n,sv);
53. return 0;
54. }
BÀI TẬP
Bài tập 7.1: (STAMGIAC) Viết chương trình tính diện tích tam giác ABC biết tọa độ A(xA,yA), B(xB,yB), C(xC,yC).
Input: xA, yA, xB, yB, xC, yC nguyên Output: S là diện tích
Ví dụ:
INPUT OUTPUT
0 0 4 0 0 3 6
Gợi ý: Tính theo công thức
A C C A C B B C B A A
By x y x y x y x y x y
x
S
2 1
Bài tập 7.2: (SDAGIAC) Viết chương trình tính diện tích của một đa giác lồi S có n đỉnh (các tọa độ nguyên).
Input:
- Dòng đầu: n
- n dòng tiếp theo, mỗi dòng lưu tọa độ x,y của các đỉnh Output: S là diện tích
Ví dụ:
INPUT OUTPUT
3 0 0 4 0 0 3
6
Gợi ý: Tính theo công thức dt(S)=
n i
i i i
iy x y
x
1
1
1 ) |
( 2 | 1
trong đó: (xi,yi) là tọa độ đỉnh thứ i của đa giác S.
Bài tập 7.3: (CHECKPOINT) Cho đa giác lồi S có n đỉnh và một điểm P (các tọa độ nguyên). Hãy kiểm tra xem P nằm trong hay ngoài đa giác S.
Input:
- Dòng đầu: n
- n dòng tiếp theo, mỗi dòng lưu tọa độ x,y của các đỉnh đa giác - Dòng cuối: tọa độ x,y của điểm P
Output: TRUE/FALSE ứng với điểm P ở trong hay ngoài đa giác Ví dụ:
INPUT OUTPUT
3 0 0 4 0 0 3 1 1
TRUE
Bài tập 7.4: (TRIANGLE) Trong mặt phẳng, cho tam giác ABC với các tọa độ nguyên. Hãy cho biết trong hình tam giác này có bao nhiêu điểm có tọa độ nguyên? Lưu ý, điểm nằm trên cạnh của tam giác không tính là ở trong tam giác.
Input:
- Dòng đầu chứa số nguyên dương N là số bộ test.
- Mỗi dòng ghi tọa độ xA, yA, xB, yB, xC, yC của 3 đỉnh tam giác trong giới hạn [-500, 500].
Output: Mỗi dòng chứa một số nguyên duy nhất là số điểm có tọa độ nguyên trong tam giác.
Ví dụ:
INPUT OUTPUT
1
2 1 1 6 -5 2
16
Bài tập 7.5: (WATTER) (Olympic Tin học 2005, khối Cao đẳng) Ở miền Trung thường năm nào cũng có những đợt hạn hán nên ông Nam có những thùng dự trữ nước. Do mua làm nhiều đợt nên N (1 ≤ N ≤ 1000) thùng chứa nước của ông Nam có kích thước khác nhau, mỗi thùng có sức chứa Ci (1 ≤ Ci ≤ 10000, 1 ≤ i ≤ N). Dự đoán rằng
năm nay sẽ có đợt hạn hán lớn nên ông Nam muốn đổ đầy nước hết các thùng để dự trữ. Sau khi kiểm tra ông Nam thấy rằng có một số thùng vẫn còn đầy, một số khác thì vơi đi một phần, còn một số thì đã hết. Ông quyết định các thùng nào chưa đầy thì sẽ chở đi để đổ đầy nước. Nhưng do nơi lấy nước rất xa, và mỗi lần chỉ chở đi được 1 thùng nên ông quyết định sẽ san nước giữa các thùng với nhau để số thùng phải chở đi là ít nhất.
Yêu cầu: Cho dung lượng nước hiện có của thùng thứ i là Bi (0
≤ Bi ≤ Ci, 1 ≤ i ≤ N), hãy giúp ông Nam xác định số lượng thùng ít nhất phải mang đi.
Input: có dạng sau:
Dòng thứ nhất ghi một số tự nhiên N là số lượng các thùng nước.
Dòng thứ i trong N dòng tiếp theo mỗi dòng có 2 số nguyên Bi và Ci (0 ≤ Bi ≤ Ci) mô tả thông tin thùng thứ i, với Bi là nước còn trong thùng và Ci là sức chứa của thùng, các số cách nhau ít nhất một khoảng trắng.
Output: một số là số lượng ít nhất các thùng nước tìm được.
Ví dụ:
INPUT OUTPUT
4 0 1 4 5 0 2 1 2
1
Bài tập 7.6: (ROBOT) (Olympic Tin học 2011, khối Cao đẳng) Cho lưới nguyên Oxy. Điểm nguyên (x1, y1) và điểm nguyên (x2, y2) được gọi là kề nhau nếu thỏa điều kiện |x1 - x2| + |y1 - y2| = 1.
Một robot ban đầu đứng tại gốc tọa độ. Ở mỗi bước, robot sẽ di chuyển sang một điểm nguyên kề với vị trí hiện tại.
Từ bước di chuyển thứ hai trở đi, robot có thể đi tiếp theo hướng cũ, rẽ sang trái, rẽ sang phải, hay trở lại vị trí trước đó.
Trong ví dụ ở hình bên, từ ô (0,0), robot đi đến (1,0), rẽ trái sang ô (1,1), rẽ phải sang ô
(2,1), rẽ phải sang ô (2, 0), rẽ trái sang (3,0) cuối cùng rẽ phải sang ô (3, - 1).
Yêu cầu: Cho tọa độ các điểm nguyên mà robot đã đi qua. Hãy đếm xem robot đã rẽ phải bao nhiêu lần.
Input: có cấu trúc như sau:
Dòng đầu tiên chứa 1 số nguyên dương n (với 2 ≤ n ≤ 10000) là tổng số điểm nguyên mà robot đã đi qua (kể cả vị trí xuất phát là gốc tọa độ),
Dòng thứ i trong n dòng tiếp theo (1 ≤ i ≤ n) chứa 2 số nguyên xi và yi là tọa độ điểm nguyên mà robot đã đi qua.
Output: một số nguyên là số lần robot đã rẽ phải.
Ví dụ:
INPUT OUTPUT
7 0 0 1 0 1 1 2 1 2 0 3 0 3 -1
3
Bài tập 7.7: (RADAR) (Olympic Tin học 2006, khối Không chuyên) Một vùng biển hình chữ nhật được chia lô thành m hàng được đánh số từ 1 đến m từ trên xuống dưới và n cột được đánh số từ 1 đến n từ trái sang phải. Lô nằm ở vị trí giao của hàng p (1≤ p ≤m) và cột q (1≤ q
≤n) được gọi là lô có tọa độ (p, q). Để bảo vệ các giàn khoan dầu trên
vùng biển này người ta bố trí một số radar tại một số lô. Mỗi radar có khả năng phát hiện tầu thuyền tại chính lô đó và 8 lô lân cận (4 lô chung cạnh và 4 lô chung đỉnh) kể cả trên biên của các lô này. Một lô trên vùng biển được coi là an toàn nếu tàu từ ngoài vùng biển trên muốn vào trong lô đó thì dù đi theo đường đi như thế nào cũng đều bị ít nhất một radar phát hiện.
Yêu cầu: Cho kích thước của vùng biển và vị trí của các lô được bố trí radar. Hãy xác định tổng số lô an toàn nằm trong vùng biển này.
Input: có định dạng như sau:
Dòng đầu ghi hai số nguyên dương m và n (1≤ m, n ≤300) là kích thước (hàng và cột) của vùng biển.
Dòng thứ hai ghi số nguyên k (1 ≤ k ≤ m x n) là số các radar được bố trí.
Trên dòng thứ i trong k dòng tiếp theo ghi hai số nguyên dương p, q (1 ≤ p ≤ m, 1≤ q ≤ n) là tọa độ lô bố trí radar thứ i.
Output: một số nguyên dương là tổng số các lô an toàn trong vùng biển.
Ví dụ:
INPUT OUTPUT
8 8 4 1 1 2 4 4 1 4 3
23
Bài tập 7.8: (TICKET) (Olympic Tin học 2007, khối Không chuyên) Một xe buýt hoạt động trên tuyến đường có N bến đỗ và các bến đỗ được đánh số từ 1 đến N, (1 là bến xuất phát, N là bến cuối cùng). Ở bến đỗ i có Ai hành khách lên xe và Bi hành khách xuống xe, với i = 1, ..., N. Với số nguyên dương K cho trước, việc soát vé hành khách được nhân viên thực hiện ở các bến đỗ: 1, K+1, 2K+1, ..., mK+1, trong đó
mK+1 ≤ N và theo quy tắc là sau khi các hành khách đã lên và xuống xe xong thì soát vé tất cả các hành khách có mặt trên xe. Với cách soát vé như vậy, một số hành khách có thể không bị soát vé lần nào.
Yêu cầu: hãy lập trình tìm số hành khách ít nhất và nhiều nhất đi trên xe buýt mà không bị soát vé lần nào.
Input:
Dòng thứ nhất chứa 2 số nguyên dương N và K, với 1≤K≤N≤1000;
Dòng thứ i trong N dòng tiếp theo chứa 2 số nguyên Ai và Bi, với 0 ≤ Ai, Bi ≤1000, i = 1, ..., N.
Output: ghi ra 2 số nguyên, cách nhau một dấu cách, là số hành khách nhỏ nhất và lớn nhất mà không bị soát vé lần nào.
Ví dụ:
INPUT OUTPUT
4 2 5 0 5 0 0 3 0 7
0 3
Bài tập 7.9: (OLYMPIC) (Olympic Tin học 2011, khối Không chuyên) Năm 2011 đánh dấu 20 năm hình thành và phát triển của Olympic Tin học sinh viên Việt Nam. Để hỗ trợ các bạn sinh viên chuẩn bị tốt cho kỳ thi này, trên website IT-2011 có n bài tập (1 ≤ n ≤ 105). Các bài được đánh số từ 1 đến n. Mỗi bài tập nhằm rèn luyện một số kỹ năng cho thí sinh, ví dụ như kỹ thuật lập trình, giải thuật, cấu trúc dữ liệu…
Nhằm định hướng cho quá trình tự luyện tập được hiệu quả, mỗi bài tập có một yêu cầu tối thiểu về trình độ kỹ năng. Để giải được bài thứ i, bạn cần có trình độ kỹ năng tối thiểu là ai. Điều này có nghĩa là sinh viên có thể giải được bài thứ i khi và chỉ khi có trình độ kỹ năng bằng hoặc lớn hơn ai. Nếu giải được bài thứ i trình độ kỹ năng của sinh viên sẽ tăng thêm một lượng là bi (1 ≤ ai, bi ≤ 109).
Giả sử ban đầu, trình độ kỹ năng của bạn trước khi làm bài tập là c (0 ≤ c ≤ 109). Các bài tập có thể được làm theo trình tự bất kỳ tùy chọn.
Ví dụ, với trình độ kỹ năng ban đầu c = 1, n = 4 và các giá trị ai, bi tương ứng là (1, 10), (21, 5), (1, 10), (100, 100), bạn sẽ giải bài 1, sau đó làm bài 3 và cuối cùng làm bài 2. Như vậy bạn sẽ làm được tất cả là 3 bài.
Yêu cầu: Cho các số nguyên n, c và các cặp giá trị (ai, bi), 1 ≤ i
≤ n. Hãy xác định số lượng bài tối đa có thể được giải.
Input: có cấu trúc như sau:
Dòng đầu tiên chứa 2 số nguyên n và c,
Dòng thứ i trong số n d.ng tiếp theo (1 ≤ i ≤ n) chứa 2 số nguyên ai và bi.
Output: một số nguyên - số lượng bài tối đa có thể giải được.
Ví dụ:
INPUT OUTPUT
4 1 1 10 21 5 1 10 100 100
3
Bài tập 7.10: (ROOMS) (Olympic Tin học 2006, khối Chuyên) Trong một Olympic Tin học sinh viên, có N cuộc thi được đánh số hiệu từ 1 đến N. Cuộc thi thứ i có thời điểm bắt đầu Si và thời điểm kết thúc Fi. Tại mỗi thời điểm trong mỗi phòng thi có không quá một cuộc thi diễn ra, ngoại trừ trường hợp thời điểm kết thúc một cuộc thi có thể đồng thời là thời điểm bắt đầu của một cuộc thi khác.
Yêu cầu:
Hãy xếp phòng thi cho tất cả các cuộc thi sao cho số phòng cần sử dụng là ít nhất.
Input: theo qui cách như sau:
Dòng thứ nhất ghi số nguyên dương N (N≤ 1000) là số lượng cuộc thi.
Trên dòng thứ i (1 ≤ i ≤ N) trong N dòng tiếp theo ghi hai số nguyên dương Si và Fi (0 ≤ Si < Fi ≤ 70000) tương ứng là thời điểm bắt đầu và thời điểm kết thúc của cuộc thi i.
Output: Ghi ra một số nguyên M là số phòng ít nhất cần cho các cuộc thi.
Ví dụ:
INPUT OUTPUT
5 0 2 1 2 3 4 2 5 4 5
2