P. 1
GT Bai Tap Lap Trinh Can Ban SGU 2010

GT Bai Tap Lap Trinh Can Ban SGU 2010

|Views: 569|Likes:
Được xuất bản bởiNHULEE

More info:

Published by: NHULEE on Dec 20, 2011
Bản quyền:Attribution Non-commercial

Availability:

Read on Scribd mobile: iPhone, iPad and Android.
download as PDF, TXT or read online from Scribd
See more
See less

11/29/2014

pdf

text

original

Bài tập lập trình căn bản – SGU2010

Trang 1

Lời giới thiệu
Lập trình căn bản là học phần đầu tiên đối với các sinh viên thuộc chuyên ngành công nghệ thông tin và cũng là học phần đang được giảng dạy cho sinh viên các chuyên ngành khoa học tự nhiên và khoa học kỹ thuật. Lập trình căn bản cũng là nội dung quan trọng trong khối kiến thức ở các kỳ thi tốt nghiệp, thi hoàn chỉnh đại học, thi cao học các chuyên ngành công nghệ thông tin. Quyển giáo trình bài tập lập trình căn bản này trình bày các chủ đề bài tập liên quan đến thuật toán, các cấu trúc điều khiển, chương trình con, đệ quy, mảng, con trỏ, chuỗi, kiểu cấu trúc, file dữ liệu theo ngôn ngữ C/C++. Mỗi chủ đề được thiết kế gồm các phần: Tóm tắt lý thuyết, hướng dẫn giải một số dạng bài tập điển hình và một số đề bài tập chọn lọc. Trong mỗi chủ đề đều có các ví dụ minh họa, mỗi ví dụ có trình bày về phương pháp giải, toàn văn chương trình kèm theo một số bộ test mẫu. Phần cuối của quyển giáo trình có hướng dẫn giải cho một số bài tập tiêu biểu, đồng thời bổ sung một số bài tập nâng cao và bộ đề thi mẫu để sinh viên tự rèn luyện kỹ năng phân tích vấn đề bài toán, rèn luyện tư duy và phong cách lập trình. Quyển giáo trình này được biên soạn để giảng dạy học phần lập trình căn bản ở hệ đại học và cao đẳng. Quyển sách này cũng có thể làm tài liệu tham khảo cho các giáo viên đang giảng dạy kiến thức lập trình căn bản ở bậc phổ thông, và giúp cho sinh viên tự học có kết quả. Tùy theo học phần quy định trong chương trình đào tạo mà giáo viên có thể chọn một số nội dung phù hợp trong quyển giáo trình này để trình bày. Chúng tôi trân trọng giới thiệu với bạn đọc quyển giáo trình Bài tập lập trình căn bản này và hy vọng rằng nó sẽ giúp cho việc giảng dạy và học tập môn lập trình căn bản được thuận lợi hơn. Cuối cùng, chúng tôi xin gởi lời cảm ơn chân thành đến Giáo sư tiến sỹ Trần Văn Hạo đã có nhiều đóng góp quý báu, cảm ơn các đồng nghiệp trong khoa công nghệ thông tin đã cùng chúng tôi chia sẽ nội dung tập bài giảng học phần lập trình căn bản này trong thời gian qua. Thành phố Hồ Chí Minh, ngày 06 tháng 09 năm 2010 CÁC TÁC GIẢ

Bài tập lập trình căn bản – SGU2010 Chương 1

Trang 2

THUẬT TOÁN
A.TÓM TẮT LÝ THUYẾT 1.1.Định nghĩa Thuật toán là một bảng liệt kê các chỉ dẫn (hay các qui tắc) cần thực hiện theo từng bước xác định nhằm giải quyết một vấn đề, bài toán. Đối với mỗi thuật toán phải có các thông tin dữ liệu đầu vào, sau đó là một dãy các phép xử lý và cuối cùng là xuất kết quả cần tìm. 1.2.Các đặc trưng của thuật toán Tính xác định: Ở mỗi bước các chỉ dẫn phải rõ ràng. Tính kết thúc: Thuật toán phải dừng sau một số hữu hạn bước. Tính đúng đắn: Thuật toán phải cho ra kết quả đúng theo yêu cầu của bài toán. Tính tổng quát: Thuật toán phải áp dụng được cho các bài toán cùng loại. Những thuật toán có các đặc trưng trên được gọi là các thuật toán có lời giải đúng. Trong giới hạn của quyển giáo trình này, tác giả chỉ đề cập đến các thuật toán có lời giải đúng; ngoài ra còn có những thuật toán cho lời giải gần đúng như thuật toán xấp xỉ, thuật toán di truyền, thuật toán heuristic, thuật toán tham lam,… 1.3.Ngôn ngữ biểu diễn thuật toán Có nhiều cách để biểu diễn một thuật toán chẳng hạn như: ngôn ngữ tự nhiên, ngôn ngữ sơ đồ khối, ngôn ngữ mã giả,… Để có thói quen lập trình tốt, khi đối diện với một bài toán thì sinh viên nên dành một lượng thời gian thích hợp để tìm ra thuật toán – đây là bước đầu tiên quan trọng nhất; tiếp theo là dùng một trong các cách trên để biểu diễn lại thuật toán trước khi bắt tay vào soạn thảo chương trình. Sau đây, tác giả tóm tắt cách biểu diễn thuật toán bằng ngôn ngữ sơ đồ khối và bằng ngôn ngữ mã giả; đối với những thuật toán phức tạp, dài dòng thì có thể biểu diễn bằng ngôn ngữ tự nhiên.

Bài tập lập trình căn bản – SGU2010 1.4.Ngôn ngữ sơ đồ khối 1.4.1.Tập ký hiệu của ngôn ngữ sơ đồ khối Bắt đầu

Trang 3

Kết thúc

Nhập liệu

Xuất liệu

Xử lý

Điều kiện

1.4.2.Biểu diễn các cấu trúc 1.4.2.1.Cấu trúc rẽ nhánh Dạng 1

điều kiện đúng công việc

Bài tập lập trình căn bản – SGU2010

Trang 4

Mô tả hoạt động Nếu <điều kiện> đúng thì sẽ thực hiện <công việc>, nếu <điều kiện> sai thì sẽ không thực hiện <công việc>. Lưu ý: <điều kiện> ở đây có dạng là một biểu thức logic, còn <công việc> có thể là một công việc đơn hoặc nhiều công việc đơn gộp lại. Dạng 2

sai

điều kiện

đúng

công việc 2

công việc 1

Mô tả hoạt động Nếu <điều kiện> đúng thì thực hiện <công việc 1>, ngược lại nếu <điều kiện> sai thì sẽ thực hiện <công việc 2>. Lưu ý:Với sơ đồ này thì luôn có một <công việc i> sẽ được thực hiện bất kể <điều kiện> đúng hay sai. 1.4.2.2.Cấu trúc lặp với số lần lặp biết trước biểu thức 1

biểu thức 2

điều kiện đúng công việc

sai

thoát

Bài tập lập trình căn bản – SGU2010

Trang 5

Mô tả hoạt động Đầu tiên sẽ thực hiện <biểu thức 1>, sau đó kiểm tra <diều kiện>. Nếu <điều kiện> đúng thì sẽ thực hiện <công việc> rồi đến <biểu thức 2>. Sau khi thực hiện xong <biểu thức 2> thì cấu trúc này quay trở lại kiểm tra <điều kiện> và bắt đầu một chu kỳ mới,…cứ thế vậy đến khi <điều kiện> nhận giá trị sai thì cấu trúc lặp này sẽ kết thúc. Lưu ý: <biểu thức 1> là phép gán cho khởi đầu giá trị của biến điều khiển vòng lặp, <biểu thức 2> thường là phép gán để thay đổi giá trị của biến điều khiển vòng lặp, còn <điều kiện> thường là một phép so sánh biến điều khiển vòng lặp và số lần lặp. 1.4.2.3.Cấu trúc lặp với số lần lặp không biết trước Dạng 1 sai

điều kiện

đúng

công việc

thoát

Mô tả hoạt động Nếu <điều kiện> đúng thì sẽ thực hiện <công việc>, sau khi thực hiện xong <công việc> thì sẽ quay trở lại kiểm tra <điều kiện> và bắt đầu một chu kỳ mới,…cứ thế vậy vòng lặp tiếp tục đến khi nào <điều kiện> nhận giá trị sai thì kết thúc. Rõ ràng với cấu trúc này thì trong <công việc> phải có một công đoạn nào đó để sau một số hữu hạn lần lặp sẽ làm <điều kiện> mang giá trị sai để vòng lặp kết thúc.

Bài tập lập trình căn bản – SGU2010 Dạng 2

Trang 6

công việc

đúng

điều kiện

sai

thoát

Mô tả hoạt động Trước hết <công việc> sẽ được thực hiện, sau đó thực hiện <điều kiện>. Nếu <điều kiện> đúng thì lại bắt đầu một chu kỳ mới,…cứ như vậy đến khi <điều kiện> nhận giá trị sai thì cấu trúc lặp này kết thúc. Tương tự như sơ đồ ở dạng 1, sau một số lần lặp thì <điều kiện> phải mang giá trị sai để vòng lặp kết thúc. 1.5. Ngôn ngữ mã giả 1.5.1.Tập ký hiệu (theo ngôn ngữ C/C++) Bắt đầu đoạn lệnh: { Kết thúc đoạn lệnh: } Lệnh nhập dữ liệu: cin Lệnh xuất dữ liệu : cout Lệnh xử lý dữ liệu: = Biểu thức điều kiện: () 1.5.2.Biểu diễn các cấu trúc 1.5.2.1.Cấu trúc rẽ nhánh Dạng 1 if (<điều kiện>) <công việc>; Mô tả hoạt động

Bài tập lập trình căn bản – SGU2010

Trang 7

Nếu <điều kiện> đúng thì thực hiện <công việc>, nếu <điều kiện> sai thì sẽ không thực hiện <công việc>. Lưu ý: Nếu <công việc> có từ hai câu lệnh đơn trở lên thì cần đặt <công việc> giữa hai dấu { }. Dạng 2 if (<điều kiện>) <công việc1>; else <công việc2>; Mô tả hoạt động Nếu <điều kiện> đúng thì sẽ thực hiện <công việc 1>, ngược lại nếu < điều kiện> sai thì <công việc 2> sẽ được thực hiện. 1.5.2.2.Cấu trúc lặp với số lần lặp biết trước for (<biểu thức 1>; <điều kiện>; <biểu thức2>) <công việc>; Mô tả hoạt động Đầu tiên sẽ thực hiện <biểu thức 1>, sau đó kiểm tra <điều kiện>. Nếu <điều kiện> đúng thì sẽ thực hiện <công việc> rồi đến <biểu thức 2>. Sau khi thực hiện xong <biểu thức 2> thì cấu trúc này quay trở lại kiểm tra <điều kiện> và bắt đầu một chu kỳ mới,…cứ thế vậy đến khi <điều kiện> nhận giá trị sai thì cấu trúc lặp này sẽ kết thúc. 1.5.2.3.Sơ đồ lặp với số lần lặp không biết trước Dạng 1 while (<điều kiện>) <công việc>; Mô tả hoạt động Nếu <điều kiện> đúng thì sẽ thực hiện <công việc>, sau đó quay trở lại thực hiện <điều kiện>. Vòng lặp while này sẽ kết thúc khi <điều kiện> sai. Dạng 2 do {

Bài tập lập trình căn bản – SGU2010 <công việc>; } while (<điều kiện>);

Trang 8

Mô tả hoạt động Trước hết <công việc> sẽ được thực hiện, sau đó kiểm tra <điều kiện>. Nếu <điều kiện> đúng thì quay trở lại thực hiện <công việc> và bắt đầu một chu trình mới. Vòng lặp do while kết thúc khi <điều kiện> nhận giá trị sai. 1.6.Sơ lược về cách xác định độ phức tạp của một thuật toán Xác định độ phức tạp tính toán của một thuật toán có thể dẫn tới những bài toán phức tạp. Tuy nhiên trong thực tế, đối với một số thuật toán ta có thể phân tích được độ phức tạp của một thuật toán bằng một số quy tắc sau đây. 1.6.1.Quy tắc cộng Giả sử T1(n) và T2(n) là thời gian thực hiện của hai đoạn chương trình P1 và P2 mà T1(n) = O(f(n)) và T2(n) = O(g(n)), thì thời gian thực hiện P1 rồi tiếp theo đến P2 sẽ là T1(n) + T2(n) = O(max(f(n), g(n)). Chẳng hạn đoạn lệnh for (i=1;i<=n;i++) x=x+1; có thời gian thực hiện là O(n.1) = O(n). Thuật toán có độ phức tạp là O(n), thuật toán có độ phức tạp O(n) thường được gọi là thuật toán có độ phức tạp tuyến tính. 1.6.2.Quy tắc nhân Giả sử T1(n) và T2(n) là thời gian thực hiện của hai đoạn chương trình P1 và P2 mà T1(n) = O(f(n)) và T2(n) = O(g(n)), thì thời gian thực hiện P1 và P2 lồng nhau là T1(n) * T2(n) = O(f(n).g(n)) Chẳng hạn đoạn lệnh for (i=1;i<=n;i++) for (j=1;j<=n;j++ ) x=x+1; có thời gian thực hiện là O(n.n) = O(n2). 1.6.3.Thuật toán thời gian đa thức và thuật toán thời gian không đa thức.

Bài tập lập trình căn bản – SGU2010

Trang 9

Thông thường các hàm thể hiện độ phức tạp tính toán của thuật toán có dạng đa thức như: hằng số, log2n, n, nlogn, n2, n3,... hay có dạng hàm mũ như: 2n, n!, nn,… Thuật toán với thời gian thực hiện có cấp hàm đa thức thì thường là chấp nhận được. Với những bài toán có độ phức tạp là đa thức thì có thể tìm được lời giải đúng; còn với những bài toán chưa tìm được thuật toán đa thức để giải (các thuật toán này gọi là các thuật toán thời gian không đa thức), thì nên tiếp cận theo hướng các thuật toán gần đúng chẳng hạn như: thuật toán xấp xỉ, thuật toán ngẫu nhiên, thuật toán di truyền, các thuật toán metaheuristic,... 1.7.Sơ lược về kiểm thử phần mềm Mặc dù một phần mềm thường được tự động hóa một phần bởi các công cụ phân tích và lập trình; tuy nhiên rất nhiều công đoạn trong quá trình sản xuất phần mềm vẫn được thực hiện bởi con người, do đó vẫn có khả năng xảy ra lỗi. Lỗi có thể xảy ra trong tất cả các giai đoạn của quy trình phát triển phần mềm: phân tích yêu cầu, thiết kế, mã hoá; do đó phải kiểm thử chương trình trước khi chính thức sử dụng là yêu cầu quan trọng và hiển nhiên. Kiểm thử phần mềm giúp phát hiện được lỗi trong chương trình (nếu có), chứng minh được phần mềm hoạt động đúng như đã thiết kế và cũng góp phần chứng minh chất lượng của phần mềm. Trong học phần căn bản này, khi viết xong một chương trình cho một vấn đề bài toán thì các sinh viên nên kiểm thử lại thuật toán và cú pháp của chương trình qua một số bộ test mẫu; để từ đó có thể phát hiện sai sót hoặc có thể cải tiến để được một chương trình hiệu quả hơn về mặt thời gian hoặc không gian lưu trữ dữ liệu,… Các bộ test mẫu phải có tính chọn lọc, có khả năng tìm ra lỗi cao, các bộ test nên không quá phức tạp cũng không quá đơn giản. Việc tìm ra các bộ test mẫu tốt để kiểm thử thường là mất nhiều thời gian. Lưu ý: Việc kiểm thử phần mềm không khẳng định được phần mềm không còn khiếm khuyết, chỉ khẳng định được phần mềm có lỗi và giúp giảm thiểu lỗi. Ta nên tiến hành kiểm thử phần mềm bắt đầu từ những module riêng biệt rồi sau đó tích hợp các module lại; và thường thì việc kiểm thử phần mềm

Bài tập lập trình căn bản – SGU2010

Trang 10

được thực hiện bởi những đối tượng không tham gia vào quá trình phát triển phần mềm. B.CÁC DẠNG BÀI TẬP Dạng 1: Cấu trúc rẽ nhánh Ví dụ 1-1.Hãy biểu diễn thuật toán giải phương trình dạng ax2 + bx + c = 0 (sử dụng ngôn ngữ sơ đồ khối)
Bắt đầu

a,b,c

đúng

a=0
sai d=b2 - 4.a.c sai đúng
vô nghiệm

đúng

b=0

d<0
sai đúng

c=0 x=-c/b
sai đúng
vô số nghiệm

x12=-b/(2.a)

d=0

x

vô nghiệm

sai x1,2=(-b± d x1,x2
)/(2.a)

Kết thúc

Bài tập lập trình căn bản – SGU2010
Các bộ test mẫu Test test 1 test 2 test 3 test 4 test 5 test 6 Hệ số a 0 0 0 1 1 1 Hệ số b 0 0 2 3 -4 4 Hệ số c 0 1 5 4 4 3 Kết quả Phương trinh vố số nghiệm Phương trinh vô nghiệm

Trang 11

Phương trinh có một nghiệm x=-2.5 Phương trinh vô nghiệm Phương trinh có nghiệm kép x1=x2=2
Phương trinh có hai nghiệm x1=-1, x2 =-3

Ví dụ 1-2.Hãy biểu diễn thuật toán kiểm tra n có phải là số chính phương hay không ? (sử dụng ngôn ngữ mã giả) Ở đây ta áp dụng định nghĩa: n là số chính phương nếu kết quả căn bậc hai của n là một số nguyên. cin>>n; if (sqrt(n)==int(sqrt(n)) cout<<”n la so chinh phuong”; else cout<<”n khong la so chinh phuong”; Lưu ý: Ở đây sqrt là hàm khai căn bậc 2 và int sẽ lấy phần nguyên của số thực sqrt(n).
Các bộ test mẫu: test 1 n kết quả 1 chính phương test 2 5 không chính phương test 3 10 không chính phương test 4 100 chính phương

Dạng 2: Cấu trúc lặp với số lần lặp biết trước Ví dụ 1-3. Biểu diễn thuật toán tính tổng s = 1 + 2 +...+n (sử dụng ngôn ngữ sơ đồ khối).

Bài tập lập trình căn bản – SGU2010

Trang 12

Bắt đầu

n

s=0 i=1

sai i<=n đúng s=s+i i=i+1

s

Kết thúc

Các bộ test mẫu:
test 1 test 2 test 3 test 4

N s

0 0

1 1

10 55

100 5050

Ví dụ 1-4. Biểu diễn thuật toán tính tổng S(n) = 1 + tự nhiên ³ 1 (sử dụng ngôn ngữ mã giả). cin>>n; s=0;

1 1 1 + + ... + với n là số 2 3 n

Bài tập lập trình căn bản – SGU2010

Trang 13

for (i=1;i<=n;i++) s=s+1/i; cout<<s; Lưu ý: Khi viết lại thuật toán này bằng ngôn ngữ C/C++ thì cần phải chuyển đổi 1/n về giá trị thực.
Các bộ test mẫu: test 1 N S 2 1.50 test 2 5 2.28 test 3 10 2.93 test 4 100 5.19

Dạng 3: Cấu trúc lặp với số lần lặp không biết trước Ví dụ 1-5. Biểu diễn thuật toán tìm ước số chung lớn nhất của 2 số nguyên dương a,b (sử dụng ngôn ngữ sơ đồ khối).
Bắt đầu

a,b

r=a mod b;

sai r<>0

đúng

a=b; b=r; r=a mod b;

b

Kết thúc

Bài tập lập trình căn bản – SGU2010
Các bộ test mẫu: test 1 a b Kết quả 18 12 6 test 2 4 18 2 test 3 101 103 1

Trang 14

test 4 3 1000000 1

Ví dụ 1-6. Hãy biểu diễn thuật toán tìm số nguyên dương n lớn nhất sao cho tổng 1 + 2 + 3+....+n < M với M là dữ liệu đầu vào (sử dụng ngôn ngữ mã giả). Sử dụng sơ đồ dạng 1 cin>>M; n=0; s=0; while (s<M) { n++; s=s+n; } cout<<n-1; Sử dụng sơ đồ dạng 2 cin>>M; n=0; s=0; do { n++; s=s+n; } while (s<M); cout<<n-1;
Các bộ test mẫu:

Bài tập lập trình căn bản – SGU2010
test 1 M n 15 4 test 2 20 5 test 3 100 13

Trang 15
test 4 1000 44

Dạng 4: Tối ưu hóa cấu trúc Tiêu chí về một chương trình tốt là chương trình đó phải chạy tốn ít thời gian nhất, tiếp theo là các tiêu chí khác như trong sáng, dễ hiểu, dễ cải tiến,... Trong mục này chúng ta hãy thực hiện việc tối ưu hóa cấu trúc lập trình để có thuật toán có thời gian thực hiện nhanh hơn. Ví dụ 1-7. Giải hệ phương trình bậc nhất hai ẩn sau đây:
ì x + y = 36 í î2 x + 4 y = 100

Thuật toán 1 for (int x=1;x<=36;x++) for (int y=1;y<=25;y++) if (x+y==36 && 2*x+4*y==100) cout<<"x="<<x<<",y="<<y; Thuật toán 2 for (int y=1;y<=25;y++) { int x=36-y; if (2*x+4*y==100) cout<<"x="<<x<<",y="<<y; } Ví dụ 1-8. Viết chương trình tính tổng S =1 + x/1!+ x2/2! + x3/3! + …. + xn/n! với x và n cho trước. Thuật toán 1 s=1; for (int i=1; i<=n;i++) { p=1;

Bài tập lập trình căn bản – SGU2010 for (int j=1; j<=i;j++) p=p*x/j; s=s+p;

Trang 16

} Thời gian thực hiện thuật toán này được đánh giá là T(n)=O(n2). Sau đây là một thuật toán khác hiệu quả hơn: Thuật toán 2 s=1; p=1; for (int i=1;i<=n;i++) { p=p*x/i; s=s+p; } Thời gian thực hiện thuật toán này được đánh giá là T(n)=O(n)
Các bộ test mẫu: test 1 x n p 0 1 1 test 2 1 1 2 test 3 5 3 18.4 test 4 100 2 7.389057

C.BÀI TẬP Hãy biểu diễn thuật toán cho các bài toán sau: BT1-1.Cho số tự nhiên n. Hãy kiểm tra xem n có phải là số hoàn thiện hay không? (n được gọi là số hoàn thiện nếu nó bằng tổng các ước số thực sự của nó). BT1-2.Cho số tự nhiên n. Hãy kiểm tra xem n có phải là số nguyên tố hay không ? BT1-3.Cho số tự nhiên n. Hãy tìm n số nguyên tố đầu tiên. BT1-4.Cho số tự nhiên n. Hãy tìm số nguyên tố lớn nhất không vượt quá số nguyên dương n. BT1-5.Cho n số a0,a1,...an-1. Hãy tìm ước số chung lớn nhất và bội số chung nhỏ nhất của n số này.

Bài tập lập trình căn bản – SGU2010

Trang 17

BT1-6.Hãy tìm tất cả các số nguyên dương x,y,z là nghiệm của hệ phương trình sau:
ì x + y + z = 100 ï í z ï5 x + 3 y + 3 = 100 î

BT1-7.Hãy tìm tất cả các số có 5 chữ số sao cho các chữ số của nó là đối xứng. Ví dụ 12321, 22222,… là các số đối xứng. BT1-8.Trong mặt phẳng tọa độ OXY cho 4 điểm A, B, C, D lần lượt có tọa độ là (xa,ya), (xb,yb), (xc,yc), (xd,yd). Hãy kiểm tra xem ABCD có tạo thành một hình bình hành không ? BT1-9.Trong mặt phẳng tọa độ OXY cho 3 điểm A(xa,ya), B(xb,yb), M(xm,ym). Hãy kiểm tra xem M có thuộc đoạn AB hay không ? BT1-10.Trong mặt phẳng tọa độ OXY cho ba điểm A(xa,ya); B(xb,yb), C(xc,yc) và một điểm M(xm,ym). Hãy xác định xem M nằm trong, nằm ngoài hay nằm trên biên của tam giác ABC ?

Bài tập lập trình căn bản – SGU2010 Chương 2

Trang 18

MỞ ĐẦU VỀ NGÔN NGỮ LẬP TRÌNH C/C++
A.TÓM TẮT LÝ THUYẾT 2.1.Kiểu dữ liệu số 2.1.1.Kiểu số nguyên Các số nguyên thuộc tập Z được định nghĩa với các từ khoá, kích thước và miền giá trị như sau: Từ khóa unsigned char char unsigned int int unsigned long long Kích thước 8 bits 8 bits 16 bits 16 bits 32 bits 32 bits 0 .. 255 -128 .. 127 0 .. 65.535 -32.768 .. 32.767 0 .. 4.294.967.295 -2.147.483.648 .. 2.147.483.647 Miền giá trị

Các phép toán số học đối với số nguyên (đã sắp theo độ ưu tiên) Toán tử + * / % 2.1.2.Kiểu số thực Từ khoá float double long double Kích thước 32 bits 64 bits 80 bits Miền giá trị của trị tuyệt đối 3.4 * (10-38) đến 3.4 * (1038) 1.7 * (10-308) đến 1.7 * (10308) 3.4 * (10-4932) đến 1.1 * (104932) Ý nghĩa cộng trừ nhân chia lấy thương chia lấy số dư 5/2=2 6%4 = 2 Ví dụ

Trên miền số thực không có phép toán chia lấy dư. 2.2.Lệnh nhập, xuất dữ liệu, lệnh gán 2.2.1.Xuất dữ liệu với printf()

Bài tập lập trình căn bản – SGU2010

Trang 19

Xuất ra màn hình giá trị của các biểu thức theo một khuôn mẫu nào đó. printf (<hằng chuỗi định dạng>, <biểu thức 1>, <biểu thức 2>,. . .); Hằng chuỗi định dạng chứa mã định dạng sau đây: %[width].prec type; trong đó: width khoảng trống dành để chứa biểu thức cần xuất ra màn hình. prec định kích thước của phần thập phân. type định kiểu của biểu thức theo sau hằng chuỗi định dạng d số nguyên hệ 10 ld số long c ký tự s chuỗi ký tự f số thực float lf số thực double chẳng hạn cần xuất hai giá trị a và b lên màn hình trong đó a là kiểu số nguyên và b là kiểu số thực thì ta có câu lệnh sau: printf(“%4d %6.2f”, a, b); Khi đó a được dành cho 4 khoảng trắng để ghi giá trị và b được dành cho 6 khoảng trắng để ghi giá trị kể cả dấu chấm thập phân và 2 chữ số phần thập phân. Chú ý: hằng \n thường được sử dụng để đưa con trỏ về đầu dòng tiếp theo làm chương trình dễ đọc. 2.2.2.Lệnh gán Lệnh gán dùng để gán giá trị cho các biến, cú pháp của lệnh gán như sau: tên biến = <biểu thức>; Trong đó <biểu thức> có thể là một hằng, một công thức hay là một biến khác đã được gán giá trị trước đó. Trong một phép gán, biến được gán phải xuất hiện bên trái dấu bằng; còn hằng, biến hoặc biểu thức để gán thì xuất hiện ở bên phải của dấu bằng. Thông thường thi cả hai vế trong một câu lệnh gán phải có cùng kiểu. Tuy nhiên khi gán một giá trị nguyên cho một biến thực, thì giá trị nguyên sẽ được chuyển đổi thành giá trị thực tương ứng, còn khi thực hiện phép gán một số thực cho một số nguyên, thì kết quả sẽ được phần nguyên của

Bài tập lập trình căn bản – SGU2010

Trang 20

số thực đó chứ không phải là một phép gán sai như một số ngôn ngữ lập trình khác. Chuyển đổi kiểu dữ liệu Khi thực hiện các phép tính toán số học thường xảy ra nhu cầu chuyển đổi kiểu các toán hạng để tính toán theo cú pháp chuyển đổi kiểu như sau: (kiểu dữ liệu) biểu thức Ví dụ: a,b là các số nguyên. Cần xuất giá trị của phân số a/b thì có ba cách chuyển đổi kiểu sau: (float)a/b, float(a)/b, a/float(b); đặc biệt trong trường hợp a hoặc b là hằng số thì việc chuyển a hoặc b thành số thực có thể thực hiện bằng cách ghi thêm .0 sau hằng đó (ví dụ 1/n ghi thành 1.0/n). Chú thích trong chương trình Khi viết chương trình nên đưa vào các dòng chú thích để chương trình dễ đọc. Điều này cũng giúp cho việc sửa đổi nâng cấp chương trình về sau. Có hai cách để ghi lời chú thích: cách 1: đặt dấu // trước dòng muốn chú thích cách 2: bao đoạn cần chú thích giữa hai dấu /* */ Lời chú thích có thể đặt ở bất kỳ vị trí nào trong chương trình, nếu chương trình dài phức tạp thì nên đưa chú thích vào trước mỗi đoạn lệnh để giải thích. 2.2.3.Nhập dữ liệu với scanf() Nhập các giá trị từ bàn phím và lưu giữ vào nội dung của các địa chỉ biến theo cú pháp sau: scanf (<hằng chuỗi định dạng>, <địa chỉ biến 1>, <địa chỉ biến 2>,. . .); Hằng chuỗi dịnh dạng chứa mã định dạng sau đây: d nhập số nguyên 10 c nhập ký tự s nhập chuỗi ký tự ld nhập vào số long f số thực float Để xuất, nhập dữ liệu chúng ta hoàn toàn có thể sử dụng hai lệnh trong thư viện stdio.h là printf, scanf như đã đề cập ở các ví dụ trên. Tuy nhiên chúng ta

Bài tập lập trình căn bản – SGU2010

Trang 21

cũng có thể sử dụng các lệnh cout, cin trong thư viện iostream.h để việc viết chuơng trình được linh hoạt hơn. 2.2.4.Xuất dữ liệu với cout cout << <biểu thức1> [ <<biểu thức2>] [...] Lệnh này cho phép xuất giá trị của các biểu thức ra màn hình. Các <biểu thức i> cũng có thể là các hàm, các hằng,… Một số lệnh sau đây (trong thư viện iomanip.h) có thể được sử dụng chung với lệnh cout: int setw(int n); quy định độ rộng trên màn hình để xuất giá trị là n cột. int setprecision(int n); quy định số lượng số lẻ sau dấu chấm thập phân cần xuất ra màn hình là n số lẻ. Tuy nhiên cú pháp này (thường được sử dụng khi có nhu cầu xuất dữ liệu kiểu số thực) lại không hiệu quả như khi sử dụng cú pháp của câu lệnh printf như trên. 2.2.5.Nhập dữ liệu với cin cin>> <biến 1> [>> <biến 2> ] [...]; Lệnh này cho phép nhập từ bàn phím giá trị cho các biến, sau mỗi lần nhập giá trị phải nhấn enter hoặc phím khoảng cách. Lưu ý: Không sử dụng lệnh cin để nhập chuỗi. 2.3.Toán tử 2.3.1.Toán tử so sánh toán tử < > == <= >= != nhỏ hơn lớn hơn bằng nhỏ hơn hoặc bằng lớn hơn hoặc bằng khác nhau định nghĩa

2.3.2.Toán tủ logic: Phép phủ định

!

Bài tập lập trình căn bản – SGU2010 Phép hội Phép tuyển a 0 0 1 1 b 0 1 0 1 !a 1 1 0 0 && || a && b 0 0 0 1 a ||b 0 1 1 1

Trang 22

2.3.3.Toán tử tăng giảm Ngôn ngữ C/C++ đưa ra hai phép toán một ngôi để tăng và giảm các biến (nguyên và thực). Toán tử tăng ++ sẽ cộng 1 vào toán hạng của nó, toán tử giảm – sẽ trừ đi 1. Chẳng hạn nếu n đang có giá trị bằng 5 thì sau phép tính ++n, n có giá trị 6, còn sau phép tính --n, n có giá trị 4. Dấu phép toán ++ và – có thể đứng trước hoặc sau toán hạng, như vậy có thể viết: ++n, n++, --n, n--. Sự khác nhau giữa ++a và a++ ở chỗ: trong khi phép n++ thì n tăng sau khi giá trị của nó đã được sử dụng, còn trong phép ++n thì n được tăng trước khi giá trị của nó được sử dụng. Sự khác nhau giữa –n và n-- cũng tương ứng như vậy. Chẳng hạn đoạn lệnh int a=1;b=3; cout <<++a+b++; thì kết quả xuất là 5 2.3.4.Toán tử điều kiện (<biểu thức điều kiện> ? <biểu thức 1> : <biểu thức 2>) Ý nghĩa: Nếu <biểu thức điều kiện> là đúng thì trả về <biểu thức 1> ngược lại trả về <biểu thức 2>. Chẳng hạn để tìm giá trị lớn nhất của 2 số a,b thì có thể viết đoạn lệnh như sau: max=a>b?a:b; Lưu ý: <biểu thức i> ở đây có thể là một đoạn lệnh, nhưng chúng ta không nên lạm dụng để tránh làm phức tạp chương trình không cần thiết. 2.3.5.Thứ tự ưu tiên của các toán tử

Bài tập lập trình căn bản – SGU2010

Trang 23

Khi tính giá trị của một biểu thức, ngôn ngữ C/C++ quy ước thứ tự ưu tiên của các toán tử từ cao đến thấp như sau: phép gọi hàm ! / , * , \ , %, && +, -, || < , >, ==, < =, > =, != 2.4.Cấu trúc của một chương trình C/C++ đơn giản Khai báo các thư viện được sử dụng trong chương trình. Định nghĩa các hằng số Khai báo các biến toàn cục Khai báo các tiêu đề hàm Chương trình chính (void main()) Thiết kế chi tiết từng hàm tự tạo (một chương trình đơn giản mẫu có thể xem ở chương trình 2-1 sau đây, còn một chương trình chi tiết với đầy đủ cấu trúc như trên có thể xem trong phần học về chương trình con). B.CÁC DẠNG BÀI TẬP Dạng 1: Sử dụng các hàm nhập, xuất dữ liệu, lệnh gán Ví dụ 2-1. Trong mặt phẳng tọa độ OXY cho 3 điểm A,B,C lần lượt có tọa độ là (xa,ya), (xb,yb), (xc,yc). Hãy tính chu vi, diện tích và tọa độ trọng tâm của tam giác này. Thuật toán Gọi cv, s lần lượt là chu vi và diện tích của đường tròn; a,b,c lần lượt là chiều dài các cạnh BC, AC, AB. Áp dụng công thức tìm khoảng cách giữa hai điểm ta có:
a = ( xc - xb) 2 + ( yc - yb) 2

b = ( xc - xa) 2 + ( yc - ya) 2
c = ( xb - xa) 2 + ( yb - ya) 2

Chu vi của tam giác ABC:

Bài tập lập trình căn bản – SGU2010

Trang 24

cv=a + b + c Áp dụng công thức tìm diện tích của tam giác khi biết chiều dài 3 cạnh của tam giác, ta có:
S= p( p - a)( p - b)( p - c) với p là nữa chu vi của tam giác ABC: p=cv/2

Gọi (xg,yg) là tọa độ trọng tâm của tam giác ABC, ta có công thức: xg=(xa+xb+xc)/3 yg=(ya+yb+yc)/3 Chương trình 2-1 #include <conio.h> #include <iostream.h> #include <math.h> void main() { clrscr(); int xa,ya,xb,yb,xc,yc; double a,b,c,p,cv,s,xg,yg; //------------------------------------------cout<<"Nhap toa do cua diem A(xa,yx):";cin>>xa>>ya; cout<<"Nhap toa do cua diem B(xb,yb):";cin>>xb>>yb; cout<<"Nhap toa do cua diem C(xc,yc):";cin>>xc>>yc; //------------------------------------------a=sqrt((xb-xc)*(xb-xc)+(yb-yc)*(yb-yc)); b=sqrt((xa-xc)*(xa-xc)+(ya-yc)*(ya-yc)); c=sqrt((xa-xb)*(xa-xb)+(ya-yb)*(ya-yb)); cv=a+b+c; p=(a+b+c)/2; s=sqrt(p*(p-a)*(p-b)*(p-c)); xg=(xa+xb+xc)/3.0; // chuyển mẫu số về số thực yg=(ya+yb+yc)/3.0; //------------------------------------------cout<<"\nChu vi cua tam giac la : "<<cv;

Bài tập lập trình căn bản – SGU2010 cout<<"\nDien tich cua tam giac la: "<<s; cout<<"\nToa do trong tam cua la : "<<xg<<","<<yg; getch(); }
Các bộ test mẫu: Test 1 2 3 A (0;3) (-3;0) (0;4) B (0;-3) (3;0) (4;0) C (4;0) (0;4) (0;0) Chu vi 16 16 13.66 Diện tích 12 12 8

Trang 25

Trọng tâm (1.33;0) (0;1.33) (1.33;1.33)

Dạng 2: Sử dụng các hàm liên quan đến phép chia lấy nguyên và chia lấy dư. Ví dụ 2-2. Nhập một số nguyên dương n có 3 chữ số. Hãy tính tổng các chữ số của số đó. Thuật toán Tách các chữ số của số n. Sau đó tính tổng các chữ số của số đó. cin>>n; Hàng đơn vị = n %10 Hàng chục = n % 100 /10 Hàng trăm = n /100 cout<<hangchuc + hangdv + hangtram; Chương trình 2-2 #include <conio.h> #include <iostream.h> void main() { clrscr(); int n; cin>>n; int hangchuc=n%10; int hangdv=n%100/10; int hangtram=n/100; cout<<hangchuc + hangdv + hangtram;

Bài tập lập trình căn bản – SGU2010 getch(); }
Các bộ test mẫu: test1 n Kết quả 197 17 test2 135 9 test3 111 3

Trang 26

test4 100 1

Dạng 3: Sử dụng toán tử điều kiện Ví dụ 2-3.Nhập vào 3 số nguyên a,b,c. Hãy tìm giá trị lớn nhất của 3 số đó. Thuật toán max=a; if (b > max) max=b; if (c > max) max=c; Chương trình 2-3 #include <conio.h> #include <iostream.h> void main() { clrscr(); int a,b,c; cin>>a>>b>>c; int max=a; max=b>max ? b:max; max=c>max ? c:max; cout<<max; getch(); } Toán tử điều kiện có thể được sử dụng để giải các bài toán có cấu trúc rẽ nhánh đơn giản như giải phương trình, hệ phương trình,…. Tuy nhiên lời giải sẽ rườm rà, khó đọc. Cấu trúc if else trong chương tiếp theo sẽ giải quyết vấn đề vừa nêu một cách trong sáng, hiệu quả hơn.

Bài tập lập trình căn bản – SGU2010

Trang 27

C.BÀI TẬP Viết chương trình hoàn chỉnh cho các bài toán sau đây (mỗi bài tập yêu cầu sinh viên ghi chú lại một số bộ test mẫu để kiểm thử chương trình). BT2-1.Viết chương trình nhập vào hai số nguyên a, b; sau đó tính a + b, a - b. a * b, a / b. BT2-2.Nhập vào 2 số nguyên a,b. Hãy hoán đổi giá trị của hai biến a,b. BT2-3.Trong mặt phẳng tọa độ OXY cho 2 điểm A, B; điểm A có tọa độ là (x,y), điểm B có tọa độ là (z,0) với x, y, z là các số dương. Hãy tính diện tích tam giác OAB. BT2-4.Trong mặt phẳng tọa độ OXY cho 3 điểm A,B,C lần lượt có tọa độ là (xa,ya), (xb,yb), (xc,yc). Tìm diện tích và chu vi của các đường tròn nội tiếp và ngoại tiếp tam giác ABC. BT2-5.Viết chương trình in lên màn hình sáu số nguyên ngẫu nhiên trong phạm vi từ 0 đến 9. BT2-6.Nhập vào s giây, hãy đổi s giây ra dạng giờ – phút – giây. BT2-7.Dùng toán tử điều kiện, tìm giá trị nhỏ nhất, giá trị lớn nhất của 5 số nguyên a,b,c,d,e. BT2-8.Dùng toán tử điều kiện giải phương trình bậc nhất ax + b= 0. BT2-9.Trong mặt phẳng tọa độ OXY cho 3 điểm A,B,C lần lượt có tọa độ là (xa,ya), (xb,yb), (xc,yc). Hãy tìm tọa độ trực tâm của tam giác, tọa độ tâm đường tròn ngoại tiếp, tọa độ tâm đường tròn nội tiếp và tọa độ chân đường cao AH. Tìm diện tích đường tròn nội tiếp, diện tích đường tròn ngoại tiếp của tam giác ABC. BT2-10.a.Tìm sin, cosin, tg, cotg của góc alpha độ, với alpha là dữ liệu nhập vào. b.Hãy tìm tọa độ các đỉnh (số nguyên) của một tam giác nội tiếp đường tròn có tâm tại gốc tọa độ, bán kính r và góc của đỉnh thứ nhất so với phương ngang là 90o.

Bài tập lập trình căn bản – SGU2010 Chương 3

Trang 28

CÁC CẤU TRÚC RẼ NHÁNH
A.TÓM TẮT LÝ THUYẾT 3.1.Cấu trúc if else Dạng 1 if (<biểu thức >) <khối lệnh>; Mô tả hoạt động Nếu <biểu thức> đúng (có giá trị khác 0) thì chương trình sẽ thực hiện <khối lệnh>, nếu <biểu thức> sai (có giá trị bằng 0) thì chương trình sẽ bỏ qua < khối lệnh > để thực hiện các câu lệnh tiếp theo sau đó. Chú ý: -<Biểu thức> có thể là kiểu nguyên hay kiểu số thực. -Các <khối lệnh > nếu có từ hai câu lệnh đơn trở lên thì phải đặt trong cặp dấu ngoặc {}. Khi khối lệnh chỉ gồm một câu lệnh thì có thể bỏ dấu ngoặc nhọn đầu và cuối. Không được đặt dấu chấm phẩy sau dấu ngoặc nhọn kết thúc khối. Khối lệnh tương đương với câu lệnh riêng lẻ về mặt cú pháp. Nói cách khác, chỗ nào đặt được một câu lệnh thì ở đó ta cũng có quyền đặt một khối lệnh. -<Biểu thức> sau if thường là dạng điều kiện và luôn được đặt trong cặp dấu (). Dạng 2 if (<biểu thức > ) < khối lệnh 1>; else < khối lệnh 2>; Mô tả hoạt động Nếu <biểu thức> đúng thì chương trình sẽ thực hiện <khối lệnh 1>, nếu <biểu thức> sai thì chương trình sẽ thực hiện <khối lệnh 2>. Sự lồng nhau của các câu lệnh if -Cho phép sử dụng các câu lệnh if lồng nhau. Điều đó có nghĩa là các khối lệnh có thể chứa các câu lệnh if else khác. Khi sử dụng nhiều câu lệnh if lồng nhau

Bài tập lập trình căn bản – SGU2010

Trang 29

thì nên sử dụng các dấu đóng mở khối để tránh sự hiểu nhầm. Trong trường hợp không sử dụng dấu đóng mở khối thì else sẽ được gắn với if không có else gần nhất trước đó. -Để chương trình rõ ràng, dễ kiểm tra và tránh nhầm lẫn, ta nên viết chương trình theo quy tắc sau: thứ nhẩt, các câu lệnh và khối lệnh nằm trong một cấu trúc điều khiển thì viết tụt vào bên phải; thứ hai, các câu lệnh và khối lệnh cùng cấp thì viết trên cùng một cột; thứ ba, điểm đầu và điểm cuối của một khối lệnh thì cùng thẳng cột. 3.2.Cấu trúc switch . . . case switch (<biểu thức> ) { case hằng-1 : < khối lệnh 1>; break; case hằng-2 : < khối lệnh 2>; break; .... case hằng-n : < khối lệnh n>; break; default : < khối lệnh 0>; break; } Mô tả hoạt động -Tiến hành so sánh giá trị của <biểu thức> với từng giá trị hằng i nằm sau các từ khóa case. Nếu giá trị của <biểu thức> trùng với hằng i thì <khối lệnh i> tương ứng sẽ được thực hiện, nếu sau <khối lệnh i> có lệnh break thì chương trình sẽ cho phép thoát ra khởi cấu trúc switch case. Trong trường hợp <khối lệnh i> bằng rỗng thì < khối lệnh i+1> sẽ được xem xét tương tự. -Khi cấu trúc có sử dụng từ khóa default thì nếu giá trị của <biểu thức> không trùng với các giá trị từ hằng 1 đến hằng n thì < khối lệnh 0> sau default sẽ được thực hiện.

Bài tập lập trình căn bản – SGU2010

Trang 30

-Lệnh break có tác dụng ngắt chương trình, thoát khỏi <khối lệnh> chứa nó. Lưu ý, nếu khi một hoặc nhiều các <khối lệnh i> đã được thực hiện nhưng không gặp câu lệnh break thì <khối lệnh 0> sau default vẫn được thực hiện. -Cấu trúc if else mạnh hơn so với cấu trúc switch theo nghĩa nếu đoạn lệnh giải được bằng cấu trúc switch thì cũng sẽ giải được bằng cấu trúc if else. -Theo cú pháp switch (<biểu thức>) thì biểu thức phải là kiểu nguyên (số nguyên, ký tự, giá trị logic). B.CÁC DẠNG BÀI TẬP Dạng 1: Bài tập sử dụng cấu trúc if else Ví dụ 3-1.Giải hệ phương trình: í

ìa1 x + b1 y = c1 îa 2 x + b2 y = c2

Thuật toán -Tính định thức d, dx, dy. -Nếu d khác 0 thì hệ phương trình có nghiệm duy nhất là (dx/d;dy/d). Ngược lại (khi d=0) Nếu dx khác 0 hoặc dy khác 0 thì hệ là vô nghiệm; Ngược lại (cả d,dx,dy đều bằng 0). hệ là vô số nghiệm. Chương trình 3-1 #include <conio.h> #include <iostream.h> void main() { int a1,b1,c1,a2,b2,c2; cin>>a1>>b1>>c1; cin>>a2>>b2>>c2; float d,dx,dy; d=a1*b2-a2*b1; dx=c1*b2-c2*b1;

Bài tập lập trình căn bản – SGU2010 dy=a1*c2-a2*c1; if (d!=0) cout<<dx/d<<" : "<<dy/d; if (d==0 && (dx!=0 || dy!=0)) cout<<"He pt vo nghiem"; if (d==0 && dx==0 && dy==0) cout<<"He pt vo so nghiem";

Trang 31

} Chúng ta đã trình bày lời giải trên bằng cách sử dụng cấu trúc rẽ nhánh if else dạng 1, nếu sử dụng cấu trúc rẽ nhánh if else dạng 2, ta có đoạn chương trình sau: if (d!=0) cout<<dx/d<<" : "<<dy/d; else if (dx!=0 ||dy!=0) cout<<"He pt vo nghiem"; else cout<<"He pt vo so nghiem";
Các bộ test mẫu Test 1 2 3 4 a1 1 1 1 1 b1 1 3 -1 1 c1 36 5 0 1 a2 2 6 1 2 b2 4 18 -1 2 c2 100 4 -4 2 Kết quả 22;14 Vô nghiệm Vô nghiệm Vô số nghiệm

Ví dụ 3-2 Viết chương trình nhập vào hai số nguyên a,b; sau đó thực hiện một trong bốn phép tính cộng, trừ, nhân, chia (nếu gõ ký tự + thì thực hiện phép cộng, nếu gõ ký tự - thì thực hiện phép trừ,…). Chương trình 3-2 #include <conio.h> #include <iostream.h> void main()

Bài tập lập trình căn bản – SGU2010

Trang 32

{ clrscr(); float a,b; char pt;// phep toan cout<<"\nChuong trinh thuc hien 4 phep toan so hoc\n"; cout<<"Nhap vao so a = ";cin>>a; cout<<"Nhap vao so b = ";cin>>b; cout<<"\nGo dau + de thuc hien phep cong:"; cout<<"\nGo dau - de thuc hien phep tru :"; cout<<"\nGo dau * de thuc hien phep tich:"; cout<<"\nGo dau / de thuc hien phep chia:"; cout<<"\nHay nhap vao lua chon:"; cin>>pt; if (pt=='+') cout<<"Ket qua la : "<<a+b; else if (pt=='-') cout<<"Ket qua la : "<<a-b; else if (pt=='*') cout<<"Ket qua la : "<<a*b; else if (pt=='/') cout<<"Ket qua la : "<<(float)a/b; else cout<<"Ban da chon khong dung phep toan!"; getch(); } Dạng 2: Bài tập sử dụng cấu trúc switch case Ví dụ 3-3:Nhập 2 giá trị tháng, năm của một ngày nào đó. Hãy cho biết tháng đó có bao nhiêu ngày?

Bài tập lập trình căn bản – SGU2010

Trang 33

Lưu ý: các tháng 1,3,5,7,8,10,12 có 31 ngày; các tháng 4,6,9,11 có 30 ngày. Riêng tháng 2 thì có những trường hợp sau: Trường hợp 1: Nếu là năm nhuận thì tháng đó có 29 ngày (năm nhuận là năm chia hết cho 4 nhưng không chia hết cho 100 hoặc chia hết cho cả 400 và 100), trường hợp hai: Nếu năm không nhuận thì tháng đó có 28 ngày. Chương trình 3-3 #include <iostream.h> void main() { int thang, songay;// so ngay cua thang cin>> thang;; switch (thang) { case 1: case 3: case 5: case 7: case 8: case 10: case 12:songay=31;break; case 4: case 6: case 9: case 11:songay=30;break; case 2:cin>>nam; if ((nam %4==0 && nam %100!=0) ||(nam %400==0 && nam %100==0) songay=29; else songay=28; break;

Bài tập lập trình căn bản – SGU2010 } cout<<songay; }
Các bộ test mẫu Test test 1 test 2 test 3 test 4 test 5 Tháng/năm 2/2008 2/2009 1/2009 11/2008 2/2000 Số ngày của tháng tương ứng 29 28 31 30 28

Trang 34

Ví dụ 3-4:(Giải lại ví dụ 3-2 theo cấu trúc switch case) Chương trình 3-4 #include <iostream.h> void main() { float a,b; char pt; cout<<"Chuong trinh thuc hien 4 phep toan so hoc\n"; cout<<"Nhap vao so a = ";cin>>a; cout<<"Nhap vao so b = ";cin>>b; cout<<"\nGo dau + de thuc hien phep cong:"; cout<<"\nGo dau - de thuc hien phep tru :"; cout<<"\nGo dau * de thuc hien phep tich:"; cout<<"\nGo dau / de thuc hien phep chia:"; cout<<"\nHay nhap vao lua chon:"; cin>>pt; switch (pt) { case '+':cout<<"Ket qua la : "<<a+b;break; case '-':cout<<"Ket qua la : "<<a-b;break; case '*':cout<<"Ket qua la : "<<a*b;break; case '/':cout<<"Ket qua la : "<<(float)a/b;break; default : cout<<"Ban da chon khong dung phep toan!";

Bài tập lập trình căn bản – SGU2010 } }

Trang 35

C.BÀI TẬP Viết chương trình hoàn chỉnh cho các bài toán sau đây BT3-1.Nhập vào một ký tự ch. Nếu ch là ký tự thường thì chuyển qua ký tự in hoa, nếu ch là ký tự hoa thì chuyển qua ký tự in thường, nếu ch là chữ số thì xuất mã ASCII của nó, nếu ch là một trong bốn phép toán số học thì xuất ra dòng chữ “phep toan”, nếu ch là ký tự khoảng trống thì xuất dòng chữ “khoang trang”, nếu không thuộc các loại kể trên thì xuất dòng chữ “khong thuoc cac ky tu tren”. BT3-2.Viết chương trình nhập vào 2 số nguyên dương a và b. Nếu cả a và b đều là số chẵn thì xuất câu: “a va b la 2 so chan” Nếu trong 2 số a và b chỉ có một số chẵn thì xuất câu: “chi co mot so chan” Nếu trong 2 số a và b không có số chẵn nào thì xuất câu; “a, b la hai so le” BT3-3.Cho 4 số a,b,c,d khác nhau đôi một. Hãy tìm giá trị lớn nhì BT3-4.Giải phương trình dạng: ax2 + bx + c = 0 BT3-5.Cho 4 số a,b,c,d khác nhau đôi một. Hãy xuất 4 số này ra màn hình theo chiều tăng dần. BT3-6.a.Nhập 3 giá trị ngày, tháng, năm. Hãy tìm ngày kề sau của ngày vừa nhập. b.Nhập 3 giá trị ngày, tháng, năm. Hãy tìm ngày kề trước của ngày vừa nhập. BT3-7.Trong mặt phẳng tọa độ OXY cho hai đường tròn, mỗi đường tròn biết tọa độ tâm và bán kính. Hãy kiểm tra xem hai đường tròn này giao nhau, cắt nhau hay tiếp xúc với nhau. BT3-8.Trong mặt phẳng tọa độ OXY cho hai đường thẳng có phương trình lần lượt là: a1x + b1y + c1 = 0 và a2x + b2y + c2 = 0 (trong đó ai,bi,ci là các số thực). Hãy kiểm tra xem hai đường thẳng này là trùng nhau? song song nhau? cắt nhau ? hay vừa cắt nhau vừa vuông góc nhau?

Bài tập lập trình căn bản – SGU2010

Trang 36

BT3-9.Cho một hình chữ nhật có cách cạnh song song với các trục tọa độ, tọa độ góc dưới trái là (x1,y1) và tọa độ góc trên phải là (x2,y2). Hãy kiểm tra xem điểm M(x,y) có nằm trong hình chữ nhật trên hay không ? (nằm trên cạnh được xem như nằm trong). Giả sử tọa độ các điểm là các số nguyên. BT3-10.Trong mặt phẳng tọa độ OXY cho 4 điểm A, B, C, D lần lượt có tọa độ là (xa,ya), (xb,yb), (xc,yc), (xd,yd). Hãy kiểm tra xem tứ giác ABCD có phải là một hình bình hành không ?

Bài tập lập trình căn bản – SGU2010 Chương 4

Trang 37

CÁC CẤU TRÚC LẶP
A.TÓM TẮT LÝ THUYẾT 4.1.Cấu trúc lặp for for (<biểu thức 1>; <điều kiện>; <biểu thức 2>) { <khối lệnh> ; } Mô tả hoạt động Đầu tiên sẽ thực hiện <biểu thức 1>, sau đó kiểm tra <điều kiện>. Nếu <điều kiện> đúng thì sẽ thực hiện <khối lệnh> rồi đến <biểu thức 2>. Sau khi thực hiện xong <biểu thức 2> thì cấu trúc này quay trở lại kiểm tra < điều kiện> và bắt đầu một chu kỳ mới,…cứ thế vậy đến khi <điều kiện> nhận giá trị sai thì cấu trúc lặp này sẽ kết thúc. Cũng như đã đề cập trong chương trước, <điều kiện> là một biểu thức dạng logic và số lần lặp đã được biểu thị tường minh trong <điều kiện> này. 4.2.Cấu trúc lặp while while (<điều kiện>) { <khối lệnh>; } Mô tả hoạt động Nếu <điều kiện> đúng thì sẽ thực hiện <khối lệnh>, sau đó quay trở lại kiểm tra <điều kiện>. Vòng lặp while này sẽ kết thúc khi <điều kiện> nhận giá trị sai. Nhận xét: <khối lệnh> trong thân vòng lặp while có thể không được thực hiện lần nào. 4.3.Cấu trúc lặp do while do {

Bài tập lập trình căn bản – SGU2010 <khối lệnh>; } while <điều kiện>;

Trang 38

Mô tả hoạt động Trước hết <công việc> sẽ được thực hiện, sau đó kiểm tra <điều kiện>. Nếu <điều kiện> đúng thì quay trở lại thực hiện <công việc>. Vòng lặp này kết thúc khi <điều kiện> nhận giá trị sai. Nhận xét: <khối lệnh> trong thân vòng lặp do while được thực hiện ít nhất là một lần. 4.4.Câu lệnh break Khi có nhiều chu trình lồng nhau, câu lệnh break sẽ thoát ra khỏi chu trình lặp (hoặc switch) bên trong nhất chứa nó. Như vậy, break cho ta khả năng ra khỏi một chu trình (từ một điểm bất kỳ bên trong chu trình) mà không cần dùng đến điều kiện kết thúc chu trình. 4.5.Câu lệnh continue Trái với câu lệnh break, câu lệnh continue dùng để bắt đầu một vòng lặp mới của chu trình bên trong nhất chứa nó. Nói một cách chính xác hơn: Khi gặp một câu lệnh continue bên trong thân của một cấu trúc for, máy sẽ chuyển tới bước khởi đầu lại. Khi gặp một câu lệnh continue bên trong thân của một cấu trúc while hoặc do while, máy sẽ chuyển tới xác định giá trị biểu thức (viết sau từ khóa while) và sau đó tiến hành kiểm tra điều kiện kết thúc chu trình. Một điều kiện cần lưu ý thêm là: continue chỉ áp dụng cho các chu trình chứ không áp dụng cho switch. B.CÁC DẠNG BÀI TẬP Dạng 1:Bài toán với số lần lặp biết trước Ví dụ 4-1.Nhập vào một số nguyên dương n <= 1000000000. Hãy cho biết số lượng các ước số dương của n. Thuật toán Do n chỉ có thể chia hết cho các số từ 1 đến n/2. Ta đặt biến d là số lượng các ước số của n tại thời điểm đang xét. Ta có thuật toán như sau:

Bài tập lập trình căn bản – SGU2010 d=1; (hiểu phép gán đầu tiên d=1 là do có n là ước của n) for (int i=1;i<=n/2;i++) if (n % i==0) d++; Chương trình 4-1 #include<conio.h> #include<iostream.h> void main() { clrscr(); long n; int d=1; cin>>n; for (long i=1;i<=n/2;i++) if (n % i==0) d++; cout<<"So luong uoc so cua so n :"<<d; getch(); }
Các bộ test mẫu test 1 n Kết quả 1 1 test 2 100 9 test 3 1001 2

Trang 39

test 4 10001 4

Ví dụ 4-2.Giả sử n ³1 và x là số thực. Hãy viết hàm tính giá trị của biểu thức sau đây :
S (n, x) = x x2 x3 xn + - ... + ( - 1 ) n - 1 1 1 1 1 1 1+ 1 1+ + 1+ + ... + 2 2 3 2 n Bài toán này thoạt nhìn thì cũng rối; bài toán này có ba vấn đề cần giải

quyết như sau: Thứ nhất là xử lý biểu thức chứa hàm mũ ở tử số, thứ hai là xử lý chuỗi số ở mẫu số, thứ ba là xử lý vấn đề đan dấu của chuỗi. Việc tìm ra một thuật toán hay với độ phức tạp tuyến tính cho bài toán này là điều mà chúng ta cần nhắm tới.

Bài tập lập trình căn bản – SGU2010

Trang 40

Ta giải quyết từng vấn đề trên như sau: Thứ nhất, tử số của số hạng đứng sau bằng tử số của số hạng đứng liền trước nó nhân với x, do đó khi tính tử số của một số hạng ta không cần tính lại từ đầu; thứ hai, việc tính các tổng cho mẫu số cũng có tính chất tương tự; thứ ba, việc xử lý vấn đề đan dấu của chuỗi thì ta chỉ cần luân phiên đảo dấu của các số hạng bằng cách cho dau =dau với dau được nhân vào cho từng hệ số. Chương trình 4-2 #include <conio.h> #include <iostream.h> void main() { clrscr(); int n; float x; cin>>n>>x; float s=0,tu=1,mau=0,dau=1; for (int i=1;i<=n;i++) { tu=tu*x; mau=mau+1.0/i; s=s+dau*tu/mau; dau=-dau; } cout<<s; getch(); }
Các bộ test mẫu Test n x Kết quả test 1 3 1 0.878788 test 2 1 10 10 test 3 100 1 0.530037 test 4 5 3 79.270622

Dạng 2:Bài toán với số lần lặp không biết trước

Bài tập lập trình căn bản – SGU2010

Trang 41

Ví dụ 4-3.Viết chương trình nhập vào một số nguyên dương n (0 < n < 1000000000). Hãy tính tổng các chữ số của số đó. Thuật toán Lần lượt tìm giá trị của từng chữ số của n và cộng dồn vào s. (Ở đây n theo đề bài có thể lớn đến hàng tỉ, do đó cần khai báo biến n thuộc kiểu unsigned long). Chương trình 4-3 #include <iostream.h> void main() { long n; cin>>n; int s=0; while (n>0) { s=s+n%10; n=n/10; } cout<<s; }
Các bộ test mẫu Test n Kết quả test 1 1 1 test 2 2010 3 test 3 999111 30 test 4 1010101 4

Ví dụ 4-4.Tìm ước số (thực sự) lẻ lớn nhất của số tự nhiên n (ước số thực sự là ước số của n nhưng nhỏ hơn n). Thuật toán Ước số thực sự lớn nhất của n chỉ có thể là n/2, do đó thuật toán sẽ duyệt i giảm từ n/2 đến 1, giá trị i nào là lẻ và là ước của n thì i chính là kết quả, thuật toán kết thúc. Chương trình 4-4 #include <conio.h>

Bài tập lập trình căn bản – SGU2010 #include <iostream.h> void main() { int n; clrscr(); cin>>n; int i=n; while (i%2==0 || n%i!=0) i--; cout<<i; getch() }
Các bộ test mẫu Test n Kết quả test 1 100 25 test 2 16 1 test 3 27 9

Trang 42

test 4 1001 1

Ví dụ 4-5. Nhập vào số tự nhiên n. Hãy tìm n số nguyên tố đầu tiên. Thuật toán Cho biến i bắt đầu từ giá trị 2, đặt số lượng số nguyên tố ban đầu là d=0. Cứ mỗi giá trị i thì kiểm tra xem i có phải là số nguyên tố hay không ? Nếu i là số nguyên tố thì tăng số d lên 1 đơn vị. Vòng lặp sẽ kết thúc khi đã tìm được đủ n số nguyên tố. Chương trình 4-5 #include <iostream.h> void main() { int n; cout<<"Nhap vao so tu nhien n:"; cin>>n; int demsont=0; int i=2,d; while (demsont<n)

Bài tập lập trình căn bản – SGU2010 { d=0; for (int j=1;j<=i;j++) if (i%j==0) d++; if (d==2) { cout<<i<<" "; demsont++; } i++; } }
Các bộ test mẫu Test Test 1 Test 2 Test 3 n 2 5 8 1 2 2 2 2 3 3 3 5 5 7 7 11 11 13 3 4 5 6

Trang 43

7

8

17

19

C.BÀI TẬP Viết chương trình hoàn chỉnh cho các bài toán sau đây BT4-1.Hãy hiển thi ba nhóm ký tự chữ cái hoa (A,B,C,…), chữ cái thường(a,b,c,…), chữ số (0,1,2,…) cùng với mã ASCII tương ứng với ký tự đó lên màn hình (phân theo từng nhóm trên).

1 1 1 + + ... + với n là số tự nhiên ³ 0. 3 5 (2n + 1) 1 1 1 b.Tính tổng S = + + ... + với n là số tự nhiên ³ 1. 2 4 2n
BT4-2.a.Tính tổng S = 1 +

x2 x3 xn + + ... + c.Tính tổng S ( x, n) = x + 1+ 2 1+ 2 + 3 1 + 2 + 3 + ... + n
n x2 x3 n x - + ... + (-1) d.Tính tổng S ( x, n) = - x + 2! 3! n!

Bài tập lập trình căn bản – SGU2010

Trang 44

e.Giả sử n≥1 và x là số thực. Hãy viết hàm tính giá trị của biểu thức sau đây:

x x2 xn n 1+ - ... + ( -1) 1+ 2 2 + 3 n + ( n + 1)
BT4-3. Tính 1.2 + 2.3.4 +3.4.5.6+...+ n(n+1)...(2n) BT4-4.a.Tính sinx + sin sinx +....+ sin sin...sin x (n lần sin) b.Tính cos x + coscos x2 +...+ cos cos...cos cos xn BT4-5. a.Cho tổng S=1+3+5+...+(2n+1) với n≥0 và số nguyên M. Hãy tìm giá trị n nhỏ nhất sao cho S >M. b.Nhập số nguyên tố n. Hãy tim số nguyên tố kế tiếp sau số n. c.Nhập vào số nguyên n. Hãy tìm số nguyên tố gần nó nhất. BT4-6.Ngày 01/01/2010 là ngày thứ Sáu. Khoa công nghệ thông tin họp toàn thể giáo viên của khoa vào các ngày thứ Sáu đầu tiên của tháng. Riêng các tháng 7,8 thì không họp. Hãy in ra các ngày trong năm 2010 mà khoa đã họp. BT4-7.Cần có 200000 đồng từ 3 loại giấy bạc 1000 đồng, 2000 đồng, 5000 đồng. Lập chương trình để tìm tất cả các phương án có thể. BT4-8.a.Viết chương trình hiển thị tất cả các số có 3 chữ số sao cho tổng các chữ số của số đó bằng tích của chúng. b.Tìm các số có 5 chữ số khác nhau đôi một. Có bao nhiêu số như vậy ? BT4-9.Ta có 3,5,7 là cấp số cộng bao gồm các số nguyên tố. Hãy kiểm tra xem trong các số tự nhiên <10000 còn có một cấp số cộng nào khác gồm 3 phần tử là số nguyên tố nữa hay không ? BT4-10.Viết hàm kiểm tra xem một số nguyên dương cho trước có phải là toàn các chữ số nguyên tố hay không ? Ví dụ : 23527, 22,…

Bài tập lập trình căn bản – SGU2010 Chương 5

Trang 45

CHƯƠNG TRÌNH CON
A.TÓM TẮT LÝ THUYẾT 5.1.Khái niệm chương trình con Khi lập trình giải quyết một vấn đề bài toán, thường để đơn giản hóa việc viết chương trình, người ta tách chương trình lớn đó thành các đoạn chương trình nhỏ hơn - mỗi đoạn giải quyết trọn vẹn một vấn đề cụ thể; mỗi đoạn nhỏ này được gọi là một chương trình con. Chương trình con trong C/C++ được gọi chung là hàm. Việc lập trình theo kiểu phân nhỏ như trên làm cho việc phân tích chương trình được dễ dàng, việc sửa lỗi và nâng cấp chương trình cũng được thuận lợi, thời gian thực hiện toàn bộ chương trình được rút ngắn lại. Sử dụng hàm cũng sẽ làm cho chương trình tránh lặp lại các đoạn công việc tương tự nhau,… Bản thân C đã có nhiều hàm (những hàm này gọi là hàm chuẩn), trong chương này, chúng ta sẽ học cách để tự viết một ra một hàm (những hàm như vậy được gọi là hàm tự tạo). 5.2.Cách thiết kế và sử dụng hàm Tham số hình thức, tham số hình thức biến, tham số hình thức trị Các biến được liệt kê trong danh sách hàm được gọi là tham số hình thức, nếu trước các biến không có chỉ dẫn & thì các biến đó gọi là tham số hình thức trị (gọi tắt là tham trị), các biến được khai báo sau từ khóa & được gọi là tham số hình thức biến (gọi tắt là tham biến), danh sách các biến ở lời gọi hàm hay thủ tục gọi là tham số thực tế. Đối với các số được truyền theo kiểu tham trị thì giá trị của các biến có thể thay đổi trong thân hàm chứa nó, nhưng khi ra khỏi hàm đó giá trị của biến giống như giá trị của biến đó trước khi vào thân hàm, còn nếu truyền theo kiểu tham biến thì mọi sự thay đổi trong thân hàm sẽ được giữ lại ngay cả khi nó ra khỏi hàm đó. Biến toàn cục và biến địa phương

Bài tập lập trình căn bản – SGU2010

Trang 46

Các biến được khai báo trong các hàm - kể cả hàm void main() được gọi là các biến cục bộ (hay là biến địa phương) và nó chỉ có tác dụng trong phạm vi hàm chứa nó và khi chương trình con kết thúc thì các biến này cũng mất tác dụng theo. Các biến được khai báo ngoài void main() được gọi là biến toàn cục; các biến toàn cục sẽ ảnh hưởng đến cả chương trình. Khi lập trình tránh tối đa việc khai báo biến toàn cục. Hàm có trị trả về, hàm không có trị trả về Khi thiết kế một hàm thì trước hết cần đặt một tên hàm có tính gợi nhớ, sau đó cần phân tích kỹ để trả lời các câu hỏi: hàm cần thiết kế là hàm có trị trả về hay không có trị trả về? Hàm cần bao nhiêu tham số? Các tham số này là tham trị hay tham biến ? Ta sẽ thiết kế hàm có trị trả về khi kết quả của hàm đó (thông qua lời gọi hàm) còn được sử dụng ở các hàm hoặc các biểu thức khác nữa; ngược lại ta nên dùng hàm không có trị trả về. Lưu ý là nếu hàm có trị trả về thì chỉ trả về duy nhất một giá trị, do đó nếu hàm có nhiều hơn một trị trả về thì sao ? Vấn đề này có thể được giải quyết theo nhiều cách. Sau đây là hai cách có thể chọn: thứ nhất là phân rã chức năng của hàm thành nhiều chức năng riêng cụ thể nhất, để mỗi hàm có một chức năng riêng biệt và nó sẽ trả về đúng một giá trị, thứ hai là trả về nhiều giá trị thông qua kỹ thuật truyền tham biến. Nếu hàm có trị trả về thì trong thân hàm đó phải có lệnh return để trả về một kết quả duy nhất sau khi thực hiện xong hàm đó. B.CÁC DẠNG BÀI TẬP Dạng 1: Thiết kế hàm có trị trả về hàm không có trị trả về. Ví dụ 5-1.Viết chương trình đếm xem từ 1 đến 100000 có bao nhiêu số nguyên tố ? Bao nhiêu số chính phương ? Bao nhiêu số hoàn hảo ? Thuật toán Ta cần thiết kế hàm nguyento(n) để kiểm tra xem n có phải là số nguyên tố hay không ? Tương tự như đối với số chính phương, hoàn hảo. Cả 3 hàm này đều phải thiết kế theo kiểu hàm có trị trả về (trả về kiểu int). Tiếp theo là thiết kế hàm cho biết số lượng của các số nguyên tố, chính phương, hoàn hảo (đặt tên hàm là demso). Do một hàm nếu có trị trả về thì chỉ

Bài tập lập trình căn bản – SGU2010

Trang 47

trả về duy nhất một giá trị, nhưng ở đây có đến 3 giá trị cần trả về nên ta cần sử dụng hàm không có trị trả về - các giá trị cần trả về có thể xuất ngay trong thân hàm đó. Chương trình 5-1 #include <math.h> #include <iostream.h> int nguyento(long n); int chinhphuong(long n); int hoanhao(long n); void demso(long n); void main() { demso(10000); } int nguyento(long n) { if (n<2) return 0; long k=sqrt(n); for (long i=2;i<=k;i++) if (n%i==0) return 0; return 1; } int chinhphuong(long n) { return sqrt(n)==long(sqrt(n)); } int hoanhao(long n) { long k=n/2;

Bài tập lập trình căn bản – SGU2010 long tonguoc=0; for (long i=1;i<=k;i++) if (n%i==0) tonguoc+=i; return tonguoc==n; } void demso(long n) { long demsont=0,demsocp=0,demsohh=0; for (long i=1;i<=n;i++) { if (nguyento(i)) demsont++; if (chinhphuong(i)) demsocp++; if (hoanhao(i)) demsohh++; } cout<<"\nSo luong so nguyen to : "<<demsont; cout<<"\nSo luong so chinh phuong: "<<demsocp; cout<<"\nSo luong so hoan hao : "<<demsohh; }
Các bộ test mẫu: Số lượng nguyên tố Chính phương Hoàn hảo 10 4 3 1 10000 1229 100 4

Trang 48

50000 5133 223 4

Dạng 2: Thiết kế hàm có truyền tham biến Ví dụ 5-2. Viết chương trình nhập vào 2 phân số a/b và c/d. Hãy tính tổng của 2 phân số. Yêu cầu phân số kết quả phải ở dạng tối giản. Ví dụ: 1/2 + 1/6 có kết quả là 2/3. Thuật toán Với ví dụ này ta thiết kế các hàm sau: void nhapps(int &tu, int &mau); void xuatps(int tu, int mau); void congps(int tu1, int mau1,int tu2, int mau2, int &tu, int &mau);

Bài tập lập trình căn bản – SGU2010

Trang 49

int uscln(int a, int b); Trong đó, hàm nhapps thì các tham số phải là tham biến do các phân số đầu vào còn được sử dụng ở hàm congps, hàm xuatps thì các tham số chỉ cần là tham trị. Thực chất thì hàm xuatps các tham số ghi là tham biến vẫn không sai, nhưng không là nên tránh. Do cả hai hàm nhập phân số và xuất phân số này không được gọi ở một hàm hoặc một biểu thức khác nên tốt nhất là thiết kế theo kiểu hàm không có trị trả về. Còn hàm congps thì do kết quả trả về là một phân số - nghĩa là có tử số và mẫu số, nên không thể trả về thông qua tên hàm do đó ta cần viết hàm không có trị trả về và khi đó giá trị trả về được trả về thông qua hai tham biến của hàm. (nếu coi phân số như là một biến của kiểu struct thì có thể viết hàm có trị trả về cho trường hợp này. Vấn đề này sẽ được xử lý trong chương 11). Chương trình 5-2 #include <iostream.h> void nhapps(int &tu, int &mau); void xuatps(int tu, int mau); void congps(int tu1, int mau1,int tu2, int mau2, int &tu, int &mau); int uscln(int a, int b); void main() { int tu1,mau1,tu2,mau2,tu,mau; nhapps(tu1,mau1); nhapps(tu2,mau2); congps(tu1,mau1,tu2,mau2,tu,mau); xuatps(tu,mau); } void nhapps(int &tu, int &mau) { cout<<"Nhap vao tu so : "; cin>>tu; cout<<"Nhap vao mau so : ";

Bài tập lập trình căn bản – SGU2010 cin>>mau; } void { xuatps(int tu, int mau) int uc=uscln(tu,mau); tu=tu/uc; mau=mau/uc; cout<<"Ket qua: "<<tu<<"/"<<mau<<endl;

Trang 50

} void {

congps(int tu1, int mau1,int tu2, int mau2, int &tu, int &mau) tu=tu1*mau2+tu2*mau1; mau=mau1*mau2;

} int uscln(int a, int b) { int r=a%b; while (r!=0) { a=b; b=r; r=a%b; } return b; }
Các bộ test mẫu test 1 Phân số 1 Phân số 2 Kết quả 1/2 1/6 2/3 test 2 1/1 4/2 3/1 test 3 5/6 6/7 71/42 test 4 10/101 2/103 1232/10403

Ví dụ 5-3. Nhập 3 giá trị ngày, tháng, năm. Hãy tìm ngày kề sau của ngày vừa nhập. Thuật toán

Bài tập lập trình căn bản – SGU2010

Trang 51

Ta thiết kế hai hàm sau: int songay(int thang, int nam) void ngaymai(int &ngay, int &thang, int &nam) Hàm songay cho biết số ngày của một tháng nào đó, còn hàm ngaymai cho biết ngày kề sau của ngày hiện tại. Ở đây cần trả về 3 giá trị là ngay, thang, năm nên cả 3 giá trị này cần được trả về thông qua tham biến và hàm này được thiết kế theo kiểu hàm không có trị trả về như trên. Chương trình 5-3 #include <iostream.h> int songay(int thang, int nam) { switch (thang) { case 1: case 3: case 5: case 7: case 8: case 10: case 12:return 31; case 4: case 6: case 9: case 11:return 30; case 2:if (nam %4==0 && nam %400!=0) return 29; return 28; } } void ngaymai(int &ngay, int &thang, int &nam) {

Bài tập lập trình căn bản – SGU2010 if (ngay<songay(thang,nam)) ngay++; else { ngay=1; thang++; if (thang>12) { thang=1; nam++; } } } void main() { int ngay,thang,nam; cin>>ngay>>thang>>nam; ngaymai(ngay,thang,nam); cout<<ngay<<" "<<thang<<" "<<nam; }
Các bộ test mẫu Ngày hiện tại test 1 test 2 test 3 test 4 test 5 31/12/2009 28//2/2000 28/2/2009 30/11/2009 28//2/2004 Ngày mai 1/1/2010 01/3/2000 1/3/2009 1/12/2009 29/2/2004

Trang 52

C. BÀI TẬP Viết chương trình hoàn chỉnh cho các bài toán sau đây BT5-1.Viết chương trình thực hiện các công việc sau: a.Tính tổng các chữ số của số tự nhiên n. b.Tìm chữ số đầu tiên của số tự nhiên n.

Bài tập lập trình căn bản – SGU2010

Trang 53

c.Tìm chữ số lớn nhất của số tự nhiên n. d.Tìm chữ số chẵn cuối cùng của số tự nhiên n. e.Kiểm tra các chữ số của n có tăng dần từ trái qua phải hay không ? BT5-2.Nhập vào n. Hãy viết chương trình thực hiện các công việc sau: a.Đếm số lượng số nguyên tố nhỏ hơn hoặc bằng n. b.Tìm số nguyên tố nhỏ nhất lớn hơn n. c.Tìm số nguyên tố gần n nhất (có thể lớn hơn hoặc nhỏ hơn n). BT5-3.Hãy phân tích số tự nhiên n thành tích các số nguyên tố Ví dụ 90=2 * 3 * 3 * 5. BT5-4.a.Tìm tất cả các số lẻ có 4 chữ số biết rằng khi đảo trật tự của các chữ số thì ta thu được một số nguyên tố cùng nhau với số đã cho. b.Viết chương trình hiển thị tất cả các số <10000 có biểu diễn nhị phân là đối xứng. c.Viết chương trình tìm số nguyên dương nhỏ nhất sao cho có thể biểu diễn nó bằng tổng lập phương của 2 số dương (tức là x3+y3) chỉ đúng bằng hai cách. BT5-5.a.Một số nguyên có k chữ số được gọi là số Amstrong khi nó bẳng tổng lũy thừa k của từng chữ số. Hãy in ra các số Amstrong trong đoạn [1..1000000]. b.Số tự nhiên n được gọi là Palindrom nếu cách viết thập phân của số đó là đối xứng, ví dụ 2112, 353,…Hãy in các số Palindrom < 10000. BT5-6.a.Viết chương trình nhập số tự nhiên n. Hãy in ra chữ số thứ n của dãy vô hạn các số chính phương 149162536496481100... b.Viết chương trình kiểm tra khẳng định sau đây: “5 chữ số cuối cùng của số 211781 cũng chính là 1781”. c.Giai thừa N ký hiệu là N! là tích tất cả các số nguyên từ 1 đến N. giai thừa N tăng rất nhanh, ví dụ 5!=120, 10!=3628800. Một cách để xác định các số lớn như vậy, người ta chỉ ra số lần xuất hiện các số nguyên tố trong phân tích của nó ra thừa số nguyên tố. Ví dụ 825 có thể xác định như sau: (0 1 2 0 1 1) có nghĩa là 825 = 20. 31.52.70.111 Cho một số nguyên dương N £ 1000. Hãy tìm biểu diễn số N! dưới dạng số lần xuất hiện các số nguyên tố trong phân tích số N! ra các thừa số nguyên tố.

Bài tập lập trình căn bản – SGU2010

Trang 54

BT5-7.Trong biểu thức :((((a1?a2)?a3)?a4)?a5) = a6. Hãy điền vào các vị trí dấu ? bởi một trong 4 phép tóan +, - , * , / sao cho giá trị của biểu thức đã cho hai vế bằng nhau. Hãy tìm tất cả các lời giải. BT5-8.Trong mặt phẳng tọa độ OXY cho 4 điểm A, B, C, D lần lượt có tọa độ là (xa,ya), (xb,yb), (xc,yc), (xd,yd). Hãy kiểm tra xem hai đoạn thẳng AB và CD có cắt nhau hay không ? BT5-9.Trong mặt phẳng tọa độ OXY cho ba điểm A(xa,ya); B(xb,yb), C(xc,yc) và một điểm M(xm,ym). Hãy xác định xem M nằm trong, nằm ngoài hay nằm trên biên của tam giác ABC ? BT5-10.Cho hai hình chữ nhật. Hình chữ nhật thứ nhất có tọa độ góc dưới trái là x1,y1 và tọa độ góc trên phải là x2,y2. Hình chữ nhật thứ hai có tọa độ góc dưới trái là x3,y3 và tọa độ góc trên phải là x4,y4. Giả thiết các tọa độ là các số nguyên và các hình chứ nhật có các cạnh song song với các trục tọa độ. Hãy tìm diện tích hình được phủ bởi hai hình chữ nhật trên.

Bài tập lập trình căn bản – SGU2010 Chương 6

Trang 55

KỸ THUẬT LẬP TRÌNH ĐỆ QUY
A.TÓM TẮT LÝ THUYẾT 6.1.Khái niệm đệ qui Một hàm được gọi là có tính đệ qui nếu trong bản thân nó có lệnh gọi lại chính nó một cách trực tiếp hay gián tiếp. Một chương trình được gọi là có tính đệ qui nếu nó có chứa ít nhất một hàm đệ qui. Một hàm đệ qui gồm có hai phần: Phần cơ sở và phần đệ qui. Phần cơ sở (hay còn gọi là phần dừng) mô tả cấp độ giải được của bài toán, phần đệ quy là phần gọi lại chính nó nhưng với cấp độ thấp hơn. Bản chất của lập trình đệ qui như thế nào? Trong lập trình đệ qui, khi một hàm (hay thủ tục) gọi đệ qui đến chính nó, thì ở mỗi lần gọi tới, máy sẽ tạo ra một tập các biến cục bộ hoàn toàn độc lập với các tập biến cục bộ đã được tạo ra trong các lần gọi trước đó, có bao nhiêu lần gọi tới hàm đệ quy thì cũng có bấy nhiêu lần thoát ra khỏi hàm, cứ mỗi lần thoát ra khỏi hàm thì một tập các biến cục bộ sẽ được giải phóng, sự tương ứng giữa các lần gọi tới hàm và thoát ra khỏi hàm được thực hiện theo thứ tự ngược, nghĩa là lần ra đầu tiên ứng với lần vào cuối cùng và lần ra khỏi hàm cuối cùng ứng với lần đầu tiên gọi tới hàm (cơ chế vào sau ra trước) Các chương trình đệ quy thường gặp có thể thuộc trong bốn loại sau: Đệ quy tuyến tính, đệ quy nhị phân, đệ quy hỗ tương và đệ quy phi tuyến. Trong mục dưới đây, chúng ta sẽ lần lượt xét các loại đệ quy kể trên, ở mỗi loại chúng ta minh họa bằng một số ví dụ điển hình. 6.2.Phân loại đệ quy 6.2.1.Đệ quy tuyến tính (còn gọi là đệ quy đuôi) Một hàm được gọi là đệ quy tuyến tính nếu một lần gọi hàm nó chỉ phát sinh tối đa một lời gọi đệ quy. 6.2.2.Đệ quy nhị phân Một hàm được gọi là đệ quy nhị phân nếu mỗi lần gọi hàm nó phát sinh tối đa hai lời gọi đệ quy.

Bài tập lập trình căn bản – SGU2010

Trang 56

6.2.3.Đệ quy hỗ tương Hai hàm P,Q được gọi là đệ quy hỗ tương nếu hàm P có lời gọi đến hàm Q và ngược lại một cách tường minh hay tiềm ẩn. 6.2.4.Đệ quy phi tuyến (đệ quy phức) Một hàm được gọi là đệ quy phi tuyến nếu mỗi lần gọi hàm thì nó phát sinh ra khoảng n lần gọi đệ quy - thông thường lời gọi đệ quy được đặt trong vòng lặp. 6.3.Khử đệ quy Mặc dù bất kỳ bài toán nào cũng có thể giải bằng kỹ thuật đệ quy, thế nhưng chúng ta không nên lạm dụng đệ quy và nếu một bài toán có lời giải không đệ quy thì nên chọn lời giải không đệ quy (lời giải không có tính đệ quy được gọi là khử đệ quy). Cài đặt đệ quy trong máy tính đôi lúc lại không đơn giản như phát biểu đệ quy, máy tính vẫn có những hạn chế về bộ nhớ nên không phải lúc nào cũng có thể biểu diễn một cách hoàn hảo các phát biểu đệ quy. Đôi lúc ta còn phải tìm cách khử đệ quy để làm giảm bớt độ phức tạp của chương trình. Với đệ quy tuyến tính và đệ quy nhị phân thì thường chúng ta tìm được cách khử đệ quy không khó lắm. Tuy nhiên với các bài toán dạng đệ quy phi tuyến hoặc đệ quy hỗ tương thì việc khử đệ quy có thể là phức tạp. B.CÁC DẠNG BÀI TẬP Dạng 1: Đệ quy tuyến tính Ví dụ 6.1.Viết chương trình tính n!, với n là một số nguyên không âm. Giai thừa được định nghĩa theo kiểu quy nạp như sau: n! = n*(n-1)! Chương trình 6-1 #include <iostream.h> long giaithua(int n); void main() { cout<<giaithua(5); } long giaithua(int n)

Bài tập lập trình căn bản – SGU2010 { if (n==0|| n==1) return 1; else return (n*giaithua(n-1)); } Dạng 2: Đệ quy nhị phân Ví dụ 6.2.Tính số hạng thứ n của dãy fibonacci biết f(1)=1, f(2)=1, f(n)= f(n-1) + f(n-2)

Trang 57

Chương trình 6-2 #include <stdio.h> #include <conio.h> int f(int n); void main() { clrscr(); cout<<f(7); getch(); } int f(int n) { if (n==1 || n==2) return 1; else return f(n-1)+f(n-2); } Ví dụ 6.3. Cho một dãy số được định nghĩa theo công thức quy nạp như sau (với n là số nguyên ≥1) f (1) = 1; f (2) = 2; f (3) = 3.

Bài tập lập trình căn bản – SGU2010

Trang 58

f ( n + 3) = 2 f ( n + 2) + f ( n + 1) - 3 f ( n)
Viết chương trình tính f(n). Chương trình 6-3 #include <iostream.h> long f(int n) { if (n==1||n==2||n==3) return n; return 2*f(n-1) + f(n-2)-3*f(n-3); } void main() { int n; cin>>n ; cout<<f(n); }
Các bộ test mẫu Test n f(n) Test 1 8 13 Test 2 20 -7546 Test 3 30 1338706

Dạng 3: Đệ quy hỗ tương Ví dụ 6-4. Viết hàm tính số hạng thứ n của hai dãy sau: x(0) = 1, y(0) = 0, x(n) = x(n - 1) + y(n - 1) với mọi n > 0, y(n) = 3*x(n - 1) + 2*y(n - 1) với mọi n > 0. Chương trình 6-4 #include<conio.h> #include<iostream.h> int tinhxn(int n); int tinhyn(int n);

Bài tập lập trình căn bản – SGU2010 void main() { clrscr(); cout<<tinhxn(3)<<endl; cout<<tinhyn(3); getch(); } int tinhxn(int n) { if (n==0) return 1; return tinhxn(n-1)+tinhyn(n-1); } int tinhyn(int n) { if (n==0) return 0; return 3*tinhxn(n-1)+2*tinhyn(n-1); } Dạng 4: Đệ quy phi tuyến Ví dụ 6-5. Bài toán tìm tất cả các dãy nhị phân chiều dài n. Chẳng hạn với n=3 thì ta có các dãy nhị phân: 000 001 010 011 100 101 110 111 Chương trình 6-5 #include<iostream.h> #include<conio.h>

Trang 59

Bài tập lập trình căn bản – SGU2010 #include<iomanip.h> int x[1000]; int m,dem=0; void xuat(); void duyetnhiphan(int i); void main() { clrscr(); cout<<"Nhap m = :"; cin>>m; duyetnhiphan(1); getch(); } void xuat() { cout<<++dem<<setw(4); for (int i=1;i<=m;i++) cout<<x[i]<<setw(4); cout<<endl; } void duyetnhiphan(int i) { for (int j=0;j<=1;j++) { x[i]=j; if (i==m) xuat(); else duyetnhiphan(i+1); } }

Trang 60

Bài tập lập trình căn bản – SGU2010 Dạng 5: Vấn đề khử đệ quy Ví dụ 6-6. Viết chương trình tính n! bằng cách không dùng đệ quy Chương trình 6-6 #include <iostream.h> #include <conio.h> long giaithua(int n); void main() { clrscr(); cout<<giaithua(10); getch(); } long giaithua(int n) { long temp=1; for (int i=1;i<=n;i++) temp *=i; return temp; } Ví dụ 6.7. Tính số hạng thứ n của dãy fibonacci F(n) biết f(1)=1, f(2)=1, f(n)= f(n-1) + f(n-2) Chương trình 6-7 #include <iostream.h> void main() { int f[100]; int n; cout<<”Nhap n = "; cin>>n;

Trang 61

Bài tập lập trình căn bản – SGU2010 f[1]=f[2]=1; for (int i=3;i<=n;i++) f[i]=f[i-1]+f[i-2]; cout<<f[n]; } C.BÀI TẬP BT6-1.a.Tính tổng S = 1 + 2 +…+ n, với n là số tự nhiên ³ 0.

Trang 62

b.Hiển thị các chữ số của một số nguyên theo chiều ngược lại. BT6.2. a.Cho dãy n số nguyên, hãy tính tổng các phần tử. b.Cho dãy n số nguyên dương, hãy đếm số lượng các số chẳn.
(sinh viên có thể làm bài tập này sau khi học đến khái niệm mảng 1 chiều)

BT6-3.Tìm ước số chung lớn nhất của 2 số tự nhiên. BT6.4.Tính S (n) = 2 + 2 + ... + 2 + 2 có n dấu căn BT6-5.Viết chương trình tính f(n) (với n ³ 1, n là số nguyên dương), biết rằng f(n) được tính theo công thức quy nạp sau đây: f(1) = 1, f(2n) =2f(n), f(2n+1)= 2f(n) + 3f(n+1) a.Tính f(5) b.Tính f(n). BT6-6.Với mỗi n ³ 1, số Yn được tính như sau : Y1=1, Y2=2, Y3=3, Yn=Yn-1 + 2Yn-2 + 3Yn-3 nếu n ³4 a.Tính Y5 b.Viết hàm tính Yn bằng phương pháp đệ quy. c.Viết hàm tính Yn không dùng đệ quy cũng không dùng biến mảng để lưu giá trị tạm. BT6-7.Viết hàm tính A(m,n) biết:

ìn + 1, khi m = 0 ï A( m, n) = í A(m - 1,1), khi n = 0 ï A(m - 1, A( m, n - 1)) î

Bài tập lập trình căn bản – SGU2010

Trang 63

BT6-8.Cho dãy xn được định nghĩa như sau: x0=1, x1=2, xn=nx0+(n-1)x1+…+xn-1 Viết hàm đệ quy tính xn (với n ³ 0). BT6-9.Với mỗi n ³ 1, số Xn được tính như sau : X1=1, X2=1 Xn=Xn-1 + (n-1)Xn-2 với n ³3 a.Viết hàm tính Xn bằng phương pháp đệ quy. b.Viết hàm tính Xn không dùng đệ quy cũng không dùng biến mảng để lưu giá trị tạm. BT6-10.Bài toán tháp Hà Nội. Giả sử có 3 cọc A, B, C. Ban đầu tại A đặt một số đĩa với thứ tự đĩa trên nhỏ đĩa dưới to - như hình vẽ dưới đây.

Yêu cầu của bài toán là chuyển toàn bộ số đĩa trên sang cọc C, trong quá trình chuyển được phép sử dụng cọc C, mỗi lần chuyển đúng 01 đĩa và luôn bảo đảm nguyên tắc đĩa nhỏ nằm trên đĩa lớn trong suốt quá trình chuyển.

Bài tập lập trình căn bản – SGU2010 Chương 7

Trang 64

MẢNG MỘT CHIỀU
A.TÓM TẮT LÝ THUYẾT 7.1.Định nghĩa mảng Một biến chỉ có thể biểu diễn được một giá trị tại một thời điểm. Để biểu diễn một dãy số hay một bảng số ta có thể dùng nhiều biến rời rạc, tuy nhiên cách này không tiện lợi. Việc sử dụng mảng là cách tốt nhất và là bắt buộc trong nhiều trường hợp xử lý vấn đề bài toán. Mảng có thể hiểu là một số hữu hạn các phần tử có cùng một kiểu giá trị và có chung một tên. Mỗi phần tử biểu diễn được một giá trị. Số phần tử của mảng được xác định ngay từ khi định nghĩa mảng. Mỗi phần tử của mảng được truy cập trực tiếp thông qua tên mảng cùng với chỉ số của mảng (các chỉ số này được đặt trong cặp dấu []). C cho phép làm việc với mảng một chiều, hai chiều hoặc nhiều chiều. 7.2.Khai báo mảng 1 chiều < kiểu dữ liệu> tênmảng[const n]; Ví dụ để khai báo mảng một chiều có tên là a gồm 10 phần tử thuộc kiểu số nguyên ta thực hiện câu lệnh như sau: int a[10]; Việc truy xuất đến từng phần tử của mảng một chiều: Phần tử của mảng một chiều sẽ được truy xuất thông qua tên mảng[chỉ số], chẳng hạn để truy xuất phần tử thứ i của mảng một chiều có tên là a ta có thể câu lệnh a[i]. Lưu ý: Chỉ số đầu tiên của mảng là 0, tuy nhiên tùy theo vấn đề bài toán đang biểu diễn mà nên sử dụng chỉ số đầu tiên của mảng là 0 hay là 1. 7.3. Nhập/xuất mảng một chiều Nhập mảng n số nguyên nhập từ bàn phím void nhapmang(int a[], int &n) { cout<<"Nhap vao so n: ";cin>>n;

Bài tập lập trình căn bản – SGU2010 for (int i=0;i<n;i++) cin>>a[i]; } Xuất mảng n số nguyên nhập từ bàn phím void xuatmang(int a[], int n) { cout<<endl; for (int i=0;i<n;i++) cout<<a[i]<<" "; } 7.4.Một số kỹ thuật lập trình đơn giản trên mảng một chiều Dạng 1: Kỹ thuật tính tổng các phần tử tổng=0; for (int i=0;i<n;i++) if (a[i] thỏa mãn điều kiện bài toán) tổng=tổng+a[i]; Dạng 2: Kỹ thuật đếm đếm=0; for (int i=0;i<n;i++) if (a[i] thỏa mãn điều kiện bài toàn) đếm++;

Trang 65

Dạng 3: Kỹ thuật đặt lính canh Phần tử lính canh có thể hiểu là một ví trị nào đó của mảng, hoặc là một giá trị nào đó của mảng hoặc cũng có thể là một giá trị tùy theo từng yêu cầu cụ thể của bài toán,… Sau đó tiến hành duyệt các phần tử của mảng, nếu có phần tử nào thỏa điều kiện của bài toán thì tiến hành thay đổi vị trí lính canh (hoặc giá trị canh. Vị trí canh (hoặc giá trị canh) này chính là thông tin cần tìm. Tuy nhiên tùy thông tin cần có của vấn đề bài toán mà định thông tin về phần tử lính canh cho phù hợp. Dạng 4: Kỹ thuật đặt cờ hiệu flag=0;

Bài tập lập trình căn bản – SGU2010 for (int i=0;i<n;i++) if (a[i] thỏa mãn điều kiện bài toán) đặt flag=1 và kết thúc vòng lặp Giá trị trả về là flag.

Trang 66

Kỹ thuật này có thể sử dụng vòng lặp while hoặc do while thì cấu trúc sẽ tự nhiên hơn. Nếu sử dụng chương trình con để thiết kế các hàm thuộc loại này thì không cần phải sử dụng các biến flag mà có thể sử dụng ngay giá trị trả về của chương trình con làm giá trị cờ hiệu. Dạng 5: Kỹ thuật sắp xếp Sắp xếp là một nội dung quan trọng của học phần cấu trúc dữ liệu, ở đây chúng ta chỉ xét đến một phương pháp sắp xếp đơn giản nhất đó là phương pháp sắp xếp đổi chỗ trực tiếp. Xét một mảng n số a0, a1,.., aN-1. Nếu có i < j và ai > aj, thì ta gọi đó là một nghịch thế. Mảng chưa sắp xếp sẽ có nghịch thế, và ngược lại mảng đã có thứ tự sẽ không còn chứa nghịch thế. Để sắp xếp một mảng, ta có thể tìm cách làm giảm số các nghịch thế trong mảng này bằng cách hoán vị các phần tử ai,aj nếu có i < j và ai > aj theo một quy luật nào nào đó. Như đã đề cập ở trên, để sắp xếp một dãy số, ta có thể xét các nghịch thế có trong dãy và làm triệt tiêu dần chúng đi. Ý tưởng chính của giải thuật là xuất phát từ đầu dãy, tìm tất cả nghịch thế chứa phần tử này, triệt tiêu chúng bằng cách đổi chỗ phần tử này với phần tử tương ứng trong cặp nghịch thế. Lặp lại xử lý trên với các phần tử tiếp theo trong dãy. Đoạn mã thể hiện ý tưởng sắp xếp đổi chỗ trực tiếp như sau: for (i=0; i<n-1;i++) for (j=i+1;j<n ;j++) if (a[i]>a[j]) hoanvi(a[i],a[j]); Dạng 6: Kỹ thuật xử lý mảng

Bài tập lập trình căn bản – SGU2010

Trang 67

Cho mảng chiều a gồm n phần tử. Hãy xóa phần tử tại vị trí k của mảng. Thuật toán Các phần tử bắt đầu từ vị trí thứ k + 1 đến cuối mảng được dịch chuyển qua trái một vị trí. Sau khi xóa xong thì cần cập nhật lại số lượng phần tử của mảng (n = n-1). Cho mảng chiều a gồm n phần tử. Hãy chèn phần tử x vào vị trí k của mảng. Thuật toán Các phần tử bắt đầu từ vị trí thứ k + 1 đến cuối mảng được dịch chuyển qua phải một vị trí. Sau đó chèn phần tử x vào vị trí k. Sau khi chèn xong thì cần cập nhật lại số lượng phần tử của mảng (n = n+1). B.CÁC DẠNG BÀI TẬP Ví dụ 7-1.Cho mảng một chiều a chứa n số nguyên. Hãy thực hiện các công việc sau: a.Tim tổng các phần tử của mảng b.Tim giá trị lớn nhất của mảng c.Đếm số lượng giá trị đối xứng trong mảng. Chương trình 7-1 #include <iostream.h> #include <conio.h> void nhapmang(int a[], int &n); void xuatmang(int a[], int n); void tinhtong(int a[], int n); int giatrilonnhat(int a[], int n); int demdoixung(int a[], int n); void main() { clrscr(); int a[1000],n; nhapmang(a,n);

Bài tập lập trình căn bản – SGU2010

Trang 68

xuatmang(a,n); tinhtong(a,n); cout<<"\nGia tri lon nhat : "<<giatrilonnhat(a,n); cout<<"\nSo luong cac phan tu doi xung: "<<demdoixung(a,n); getch(); } void nhapmang(int a[], int &n) { cout<<"Nhap vao so n: ";cin>>n; for (int i=0;i<n;i++) cin>>a[i]; } void xuatmang(int a[], int n) { for (int i=0;i<n;i++) cout<<a[i]<<" "; } void tinhtong(int a[], int n) { int s=0; for (int i=0;i<n;i++) s=s+a[i]; cout<<"\nTong cac phan tu cua day : "<<s; } int giatrilonnhat(int a[], int n) { int max=a[0]; for (int i=1;i<n;i++) if (a[i]>max) max=a[i]; return max;

Bài tập lập trình căn bản – SGU2010 } int demdoixung(int a[], int n) { int dem=0; for (int i=0;i<n/2;i++) if (a[i]==a[n-i-1]) dem++; return dem; }
Các bộ test mẫu n Câu a Test 1 Test 2 Câu b Test 1 Test 2 Câu c Test 1 Test 2 Test 3 Test 4 Test 5 6 5 6 1 2 1 1 1 1 1 2 2 2 2 3 3 3 3 2 4 2 1 2 1 1 6 5 -3 6 -7 7 -5 8 -10 2 -5 111 -2 22 5 6 1 -3 2 -7 3 -5 4 -10 5 -5 30 a0 a1 a2 a3 a4 a5

Trang 69

Kết quả 15 0 -2 111 3 2 2 0 0

Ví dụ 7-2. Cho mảng một chiều chứa n số nguyên a0, a1, a2,…,an-1. Hãy viết hàm tìm vị trí của số dương lẻ lớn nhất của mảng. Nếu không tìm thấy thì trả về giá trị -1.
Test 1 Input n=6 4 -100 -20 16 20 -97 Output: -1 Input n=8 1000 7 6 2 -5 -1001 93 100 Output: 6 Test 2

int soduonglelonnhat(int a[],int n) { int vitri=-1,max=0;//hoac la max=-MAXINT;MAXINT trong thu vien values.h

Bài tập lập trình căn bản – SGU2010

Trang 70

for (int i=0;i<n;i++) if (a[i]%2!=0 && a[i]>0 && a[i]>max) { max=a[i]; vitri=i; } return vitri; } Ví dụ 7-3. Cho mảng một chiều chứa n số nguyên dương a0, a1, a2,…,an-1. Hãy viết hàm kiểm tra trong mảng có chứa số nguyên tố nào có đúng hai chữ số hay không ? Nếu có thì trả về giá trị 1, nếu không có thì trả về giá trị 0.
Test 1 n=6 2 21 15 37 49 105 Output: 1 n=8 1001 101 62 63 39 5 231 15 Output: 0 Test 2

int nguyento(int n) { if (n<2) return 0; for (int i=2;i<n;i++) if (n%i==0) return 0; return 1; } int songuyentohaichuso(int a[],int n) { for (int i=0;i<n;i++) if (nguyento(a[i]) && 10<=a[i] && a[i]<=99) return 1; return 0; }

Bài tập lập trình căn bản – SGU2010

Trang 71

Ví dụ 7-4. Sắp xếp các số nguyên tố trong mảng tăng dần, còn các số khác khác thì giữ nguyên giá trị và vị trí. void sapxepnguyento(int a[], int n) { for (int i=0;i<n-1;i++) for (int j=i+1;j<n;j++) if (nguyento(a[i]) && nguyento(a[j]) && a[i]>a[j]) hoanvi(a[i],a[j]); } void hoanvi(int &a, int &b) { int temp=a; a=b; b=temp; }
n Test 1 Kết quả Test 2 Kết quả 6 10 a0 4 5 4 5 6 6 a1 6 3 6 7 19 2 a2 15 8 15 8 4 4 a3 7 2 2 19 3 3 2 5 5 19 16 3 a4 16 a5 19 Kết quả

Ví dụ 7-5. Cho dãy n số nguyên dương a1, a2,..., an. Hãy viết hàm tìm chiều dài của đoạn con liên tiếp dài nhất chứa toàn số chẵn. Nếu không có thì trả về giá trị 0.
Test 1 Input n=12 1 4 12 22 18 21 68 42 16 82 10 5 Output 5 Test 2 Input n=6 1 105 223 15 93 101 Output 0

Bài tập lập trình căn bản – SGU2010

Trang 72

int doansochandainhat(int a[], int n) { int d=0,max=0; for (int i=0;i<n;i++) if (a[i]%2==0) d++; else { if (d>max) max=d; d=0; } return (d>max?d:max); } Ví dụ 7-6. Cho mảng một chiều a chứa n số nguyên dương. Viết hàm xóa tất cả các số nguyên tố trong mảng. void xoaphantu(int a[], int &n, int k) { for (int i=k;i<n;i++) a[i]=a[i+1]; n--; } void xoasonguyento(int a[], int &n) { for (int i=0; i<n;i++) if (nguyento(a[i])) { xoaphantu(a,n,i); i--; } }

Bài tập lập trình căn bản – SGU2010

Trang 73

C.BÀI TẬP Viết chương trình hoàn chỉnh cho các bài toán sau đây BT7-1.Cho mảng một chiều a chứa n số nguyên dương. a.Tìm số nguyên tố nhỏ nhất lớn hơn mọi giá trị có trong mảng. b.Kiểm tra mảng có tăng dần hay không ? Nếu có thì trả về giá trị 1 nếu không có thì trả về giá trị 0. c.Kiểm tra mảng có tồn tại giá trị chẵn nhỏ hơn 2010 hay không ? Nếu có thì trả về giá trị 1 nếu không có thì trả về giá trị 0. d.Kiểm tra các phần tử trong mảng có lập nên một cấp số cộng không ? Nếu có hãy chỉ ra công sai d. e.Tìm giá trị chẵn đầu tiên, nếu không có thì trả về giá trị -1. f.Đếm số lượng các giá trị lớn nhất. g.Tìm giá trị lớn thứ k của mảng. BT7-2.Cho mảng một chiều a chứa n số nguyên. Viết hàm đếm tần số xuất hiện của các phần tử. BT7-3.Cho mảng một chiều chứa n số nguyên dương. Hãy tìm các cặp số nguyên tố cùng nhau. BT7-4.a.Viết hàm tìm k giá trị khác nhau lớn nhất của mảng. b.Viết hàm hãy đưa các số chẵn về đầu mảng, các số lẻ về cuối mảng, còn các số 0 ở giữa. c.Viết hàm sắp xếp các các số trong mảng sao cho các số dương được sắp xếp tăng dần, các số âm được sắp xếp giảm dần, còn các số 0 thì giữ nguyên vị trí. d.Cho mảng một chiều a chứa các số nguyên dương. Hãy xuất các số nguyên tố trong mảng a theo chiều tăng dần. BT7-5.Cho mảng một chiều a chứa n số nguyên dương. a.Tìm bội số chung nhỏ nhất của n số trên. b.Tìm ước số chung lớn nhất của n số trên. BT7-6.Cho dãy n+1 số nguyên a0,a1,…,an-1, anvà một số nguyên x. Hãy tính giá trị của biểu thức P(n,x) = anxn+an-1xn-1 +…+a1x+a0.

Bài tập lập trình căn bản – SGU2010

Trang 74

BT7-7.Cho hai mảng một chiều a và b. Hãy kiểm tra xem tất cả các phần tử của mảng a có nằm trong mảng b hay không ? BT7-8.Viết chương trình in lên màn hình 100 số nguyên ngẫu nhiên trong phạm vi từ 100 đến 999. BT7-9.Cho hai mảng một chiều a và b, các số trong mảng đã được sắp tăng dần. Hãy trộn hai mảng này để được một mảng c cũng được sắp tăng dần. BT7-10.Cho dãy n số nguyên {a} Dãy con liên tiếp là dãy mà thành phần của nó là các thành phần liên tiếp nhau trong {a}. Ta gọi tổng của dãy con là tổng tất cả các thành phần của nó. Tìm tổng lớn nhất trong tất cả các tổng của các dãy con của {a}. Ví dụ nếu n = 7 và dãy số như sau: 4 –5 6 –4 2 3 -7 thì kết quả tổng là 7.

Bài tập lập trình căn bản – SGU2010 Chương 8

Trang 75

MẢNG HAI CHIỀU
A.TÓM TẮT LÝ THUYẾT 8.1.Khai báo mảng Mảng hai chiều được khai báo như sau: < kiểu dữ liệu> tên mảng[const m][const n]; Ví dụ sau khai báo một mảng hai chiều có tên là a gồm 10 dòng, 10 cột, các phần tử là các số nguyên. int c[10][10]; Phần tử của mảng được truy xuất thông qua tên mảng[chỉ số dòng][chỉ số cột], chẳng hạn để truy xuất phần tử tại dòng thứ i cột thứ j của mảng a, ta ghi a[i][j]. Mảng hai chiều m dòng n cột được xem như là một bảng hình chữ nhật chứa m*n phần tử cùng kiểu dữ liệu. Bảng sau đây là một mảng hai chiều 3 dòng, 4 cột chứa các số nguyên. cột 0 dòng 0 dòng 1 dòng 2 2 3 3 cột 1 3 8 1 cột 2 4 4 2 cột 3 6 7 5

8.2.Nhập/xuất mảng hai chiều Nhập các phần tử cho mảng hai chiều các số nguyên void nhapmang(int a[maxm][maxn], int &m, int &n) { cout<<"Nhap vao so dong: ";cin>>m; cout<<"Nhap vao so cot : ";cin>>n; for (int i=0;i<m;i++) for (int j=0;j<n;j++) cin>>a[i][j]; } Xuất các phần tử cho mảng hai chiều các số nguyên

Bài tập lập trình căn bản – SGU2010 void xuatmang(int a[maxm][maxn], int m, int n) { for (int i=0;i<m;i++) { for (int j=0;j<n;j++) cout<<a[i][j]<<" "; cout<<endl; } }

Trang 76

B.CÁC DẠNG BÀI TẬP Dạng 1: Kỹ thuật tính tổng các phần tử Cho mảng hai chiều m dòng, n cột; các phần tử là các số nguyên. Hãy viết hàm tính tổng các phần tử của mảng. void tinhtong(int a[maxm][maxn], int m, int n) { int s=0; for (int i=0;i<m;i++) for (int j=0;j<n;j++) s=s+a[i][j]; cout<<"Tong cac phan tu cua mang la : "<<s; } Dạng 2: Kỹ thuật đếm Cho mảng hai chiều m dòng, n cột; các phần tử là các số nguyên. Hãy đếm xem mỗi dòng có bao nhiêu số nguyên tố. void demsonttrendong(int a[maxm][maxn], int m, int n) { for (int i=0;i<m;i++) { int dem=0; for (int j=0;j<n;j++) if (nguyento(a[i][j]))

Bài tập lập trình căn bản – SGU2010 dem++; cout<<dem<<endl; } }

Trang 77

Dạng 3: Kỹ thuật đặt lính canh Cho mảng hai chiều m dòng, n; cột các phần tử là các số nguyên. Hãy tìm số chính phương lớn nhất, nếu không tìm thấy trả về giá trị 0. int chinhphuongln(int a[maxm][maxn], int m, int n) { int cpmax=0; for (int i=0;i<m;i++) for (int j=0;j<n;j++) if ((sqrt(a[i][j])==int(sqrt(a[i][j]))) && (a[i][j]>cpmax)) cpmax=a[i][j]; return cpmax; } Dạng 4: Kỹ thuật đặt cờ hiệu Cho mảng hai chiều m dòng, n cột; các phần tử là các số nguyên. Hãy kiểm tra xem mảng có chứa dòng nào tăng dần hay không? Nếu có trả về giá trị 1; nếu không có trả về giá trị 0. int kiemtradongtang(int a[maxm][maxn], int m, int n) { int flag; for (int i=0;i<m;i++) { flag=1; for (int j=0;j<n-1;j++) if (a[i][j]>a[i][j+1]) flag=0; if (flag==1) return 1; } return 0; }

Bài tập lập trình căn bản – SGU2010

Trang 78

Dạng 5: Kỹ thuật sắp xếp (sắp xếp đổi chỗ trực tiếp) Cho mảng hai chiều m dòng, n cột; các phần tử là các số nguyên. Hãy thực hiện các công việc sau đây: a.Sắp xếp các phần tử tăng dần trên mỗi dòng (từ trái qua phải). b.Sắp các phần tử tăng dần trên mỗi dòng (từ trái qua phải) và tăng dần trên mỗi cột (từ trên xuống dưới, mỗi phần tử của dòng dưới phải lớn hơn tất cả các phần tử của dòng trên). Thuật toán Câu a. Xem mỗi dòng như là một mảng một chiều, áp dụng thuật toán sắp xếp mảng một chiều (như trong chương trước) ta sẽ được mảng tăng dần trên từng dòng như đoạn chương trình sau: void sapdong(int a[maxm][maxn], int m, int n) { for (int i=0;i<m;i++) for (int j=0;j<n-1;j++) for (int k=j+1;k<n;k++) if (a[i][j]>a[i][k]) hoanvi(a[i][j],a[i][k]); } Câu b. Cách 1:Dùng mảng phụ Chuyển dữ liệu từ mảng hai chiều a sang mảng một chiều b, sau đó sắp xếp các phần tử tăng dần trên mảng một chiều b và cuối cùng chuyển dữ liệu từ mảng một chiều b qua lại mảng hai chiều a. Cách 2:Không dùng mảng phụ void sapxep(int a[maxm][maxn], int m, int n) { for (int i=0;i<m*n-1;i++) for (int j=i+1;j<m*n;j++) if (a[i/n][i%n]>a[j/n][j%n]) hoanvi(a[i/n][i%n],a[j/n][j%n]);

Bài tập lập trình căn bản – SGU2010 }
Các bộ test mẫu m=3; n=5 4 2 12 7 3 3 34 1 11 3 17 4 2 7 2 1 3 7 2 3 11 2 4 12 2 4 17 3 7 34

Trang 79

Dạng 6: Kỹ thuật xử lý mảng Cho mảng hai chiều m dòng, n cột; các phần tử là các số nguyên. a.Hoán vị hai dòng k,l của mảng. b.Dịch xuống xoay vòng các dòng một vị trí. a. void hoanvidong(int a[maxm][maxn], int m, int n, int k, int l) { for (int i=0;i<n;i++) hoanvi(a[k][i],a[l][i]); } b. void xoayvong(int a[maxm][maxn], int m, int n) { for (int i=m-1;i>0;i--) hoanvidong(a,m,n,i,i-1); } C.BÀI TẬP Viết chương trình hoàn chỉnh cho các bài toán sau đây BT8-1.Cho mảng hai chiều m dòng, n cột; các phần tử là các số nguyên. Hãy thực hiện các công việc sau đây: a.Tính tổng các phần tử nằm trên các đường biên của mảng. b.Liệt kê chỉ số dòng có chứa giá trị nguyên tố. c.Liệt kê chỉ số dòng chứa toàn giá trị nguyên tố. d.Kiểm tra xem mảng có tồn tại số hoàn thiện nào hay không?

Bài tập lập trình căn bản – SGU2010

Trang 80

e.Tìm tần số xuất hiện của các số. BT8-2.Cho mảng hai chiều n dòng, n cột (gọi là ma trận vuông). Hãy thực hiện các công việc sau đây: a.Tính tổng các phần tử nằm trên đường chéo phụ. b.Kiểm tra ma trận vuông có đối xứng qua đường chéo chính hay không ? c.Kiểm tra xem đường chéo chính có tăng dần từ trên xuống dưới hay không ? d.Đếm số lượng giá trị chẵn trong ma trận tam giác trên. e.Tính tổng các phần tử thuộc ma trận tam giác dưới. f.Hãy tìm giá trị lớn nhất trong ma trận tam giác trên. BT8-3.Cho mảng hai chiều n dòng, n cột. Hãy thực hiện các công việc sau đây: a.Xóa một dòng của mảng. b.Hoán vị hai cột k,l của mảng. c.Đảo ngược các cột (cột đầu tiên về cột cuối, cột thứ 2 về cột gần cuối,...) d.Dịch qua phải một vị trí cho tất cả các cột. e.Dịch xuống k vị trí cho tất cả các dòng. BT8-4.Viết chương trình nhập vào ma trận a các số nguyên kích thước m x n (0< m ≤ 6, 0<n ≤ 8). Tính và xuất ma trận b có cùng kích thước với a sao cho b[i][j] = trung bình cộng của các phần tử kề với phần tử a[i][j] trong ma trận a theo 8 hướng (không tính a[i][j]). BT8-5.Hãy in tam giác Pascal với chiều cao h. Ví dụ với h=5 thì kết quả là: 1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 1 5 10 10 5 1

Bài tập lập trình căn bản – SGU2010

Trang 81

BT8-6.Cho ma trận vuông cấp n có 2n-1 đường chéo song song với đường chéo phụ được đặt tên là 0 đến 2*n-2. Hãy cho biết đường chéo nào có tổng lớn nhất ? BT8-7.Cho ma trận vuông cấp n (n>1). Hãy in các phần tử của ma trận trên theo thứ tự đường xoắn ốc từ ngoài vào trong.

BT8-8.Hãy điền các số từ 1 đến n*n vào bảng sau theo quy luật được mô tả với những trường hợp cụ thể (n = 5,6) như sau: n=5 11 10 4 3 1 19 12 9 5 2 20 18 13 8 6 24 21 17 14 7 25 23 22 16 15 n=6 1 2 6 7 15 16 3 5 8 14 17 26 4 9 13 18 25 27 10 12 19 24 28 33 11 22 23 29 32 33 21 22 30 31 35 36 Hãy nhập n từ bàn phím (1 < n <20) và in bảng lên màn hình theo quy luật trên. BT8-9.Hãy lập trình để xuất bảng số có kích thước là n với 7<n<25 theo quy luật được nhận biết từ cách biểu diễn với các trường hợp cụ thể sau: Với n=5 9 7 5 3 1

Bài tập lập trình căn bản – SGU2010 7 5 3 1 5 3 1 2 3 1 2 4 1 2 4 6 2 4 6 8

Trang 82

Với n=6 11 9 7 5 3 1 9 7 5 3 1 2 7 5 3 1 2 4 5 3 1 2 4 6 3 1 2 4 6 8 1 2 4 6 8 10

Với n=7 13 11 9 7 5 3 1 11 9 9 7 5 3 1 2 7 5 3 1 2 4 7 5 3 1 2 4 6 5 3 1 2 4 6 8 3 1 2 4 6 8 1 2 4 6 8 10

10 12

BT8-10.Bài toán ma phương. a.Bài toán ma phương lẻ Ma phương lẻ là một bảng hình vuông có n cột, n hàng chứa các số nguyên từ 1 đến n2 sao cho tổng các số trong các hàng, các cột và hai đường chéo lớn đều bằng nhau và bằng n(n2 +1)/2. Với mọi n ³ 3 đều có thể xây dựng được ma phương. Ngay từ thời trung cổ, người ta đã biết cách xây dựng ma phương với các n lẻ. Với n cố định, hiện nay người ta vẫn chưa biết được là có

Bài tập lập trình căn bản – SGU2010

Trang 83

thể xây dựng được bao nhiêu ma phương khác nhau. Ma phương có nghĩa là "hình vuông mầu nhiệm", vì người ta cho rằng có điều gì thần bí ẩn chứa ở trong đó. Ma phương gọi là chuẩn khi n2 số của ma phương là n2 số nguyên dương đầu tiên. Thuật toán -Đầu tiên đặt số 1 vào ô chính giữa của dòng cuối. i=n; j=(n/2) + 1; a[i][j]=1; -Khi đã điền số k ta tại ô i,j thì tiến hành điền số tiếp theo là (k+1) theo hướng Đông-Nam (hướng chính). -Việc tìm vị trí của ô để điền giá trị k+1 (vị trí i=i+1,j=j+1) có thể gặp những sự cố sau đây: o Nếu (j>n) và (i<=n) nghĩa là ô đang xét có cột đã vượt ra ngoài bảng thì gán j=1 – nghĩa là đẩy số k + 1 qua cực trái của bảng. o Nếu (i>n) và (j<=n) nghĩa là ô đang xét có dòng đã vượt ra ngoài bảng thì gán i=1 – nghĩa là đẩy số k+1 lên dòng đầu tiên của bảng. o Nếu (i>n) và (j>n) nghĩa là ô đang xét có cả dòng và cột đã vượt ra ngoài bảng thì gán i=i-2; j=j-1; o Nếu a[i,j]<>0 nghĩa là tại ô đang xét đã được điền số rồi thì gán i=i-2; j=j-1; Ví dụ với n =5 thì được ma phương sau: 11 10 4 23 17 18 12 6 5 24 25 19 13 7 1 2 21 20 14 8 9 3 22 16 15

b.Bài toán ma phương chẳn -Điền các số từ 1 đến n2 vào bảng theo thứ tự tăng dần từ trái qua phải và từ trên xuống dưới:

Bài tập lập trình căn bản – SGU2010

Trang 84

for i=1;i<=n;i++; for j=1;j<=n;j++; a[i][j]=(i-1)*n+j; -Việc tạp xâu mẫu: Gán cho chuỗi s bằng k/2 ký tự ‘T’ với k=n/2. Nếu k là số lẻ thì thêm hai ký tự DN vào cuối chuỗi s. Nếu s vẫn chưa đủ k ký tự thì thêm ký tự B vào cuối chuỗi – thêm đến khi nào s có đủ k ký tự thì dừng. -Tạo bảng bằng các kỳ tự trong xâu mẫu trên theo quy tắc được cho trong đoạn mã giả sau: for i=1;i<=k;i++ { for j=1;j<=k;j++ { b[i][j]=nhận ký tự thứ j của chuỗi s. //lưu ý ở đây đang xét chuỗi s bắt đầu từ vị trí s[1]) b[n-i+1][n-j+1]=b[i][j]; // đối xứng qua tâm b[i][n-j+1]=b[i][j]; // đối xứng theo chiều dọc b[n-i+1][j]=b[i][j]; // đối xứng theo chiều ngang } Tiến hành chuyển ký tự cuối của xâu mẫu về vị trí đầu tiên của xâu mẫu. } Ở các vị trí ngoài hình vuông k x k ở trên, nếu giá trị của ô i,j là khác ký tự T thì cho ô đó có giá trị bằng ký tự ‘B’. -Giai đoạn hóan đổi giá trị của các ô (để được ma phương) theo quy tắc sau: for i=1;i<=n;i++ for j=1;j<=n;j++ if (a[i][j]=(i-1)*n+j) // nếu ô i,j là chưa được hóan đổi. { if ( b[i][j]='T') // đối xứng qua tâm swap(a[i][j],a[n-i+1][n-j+1]);

Bài tập lập trình căn bản – SGU2010

Trang 85

if (b[i][j]='D') // đối xứng qua chiều dọc swap (a[i][j],a[i][n-j+1]); if (b[i][j]='N' ) // đối xứng theo chiều ngang swap (a[i][j],a[n-i+1][j]); } Ví dụ với n = 4 thì được ma phương sau: 16 5 9 4 2 11 7 14 3 10 6 15 13 8 12 1

Bài tập lập trình căn bản – SGU2010 Chương 9

Trang 86

CON TRỎ
A.TÓM TẮT LÝ THUYẾT 9.1.Địa chỉ và con trỏ 9.1.1.địa chỉ ô nhớ Liên quan đến một biến ta có các khái niệm: tên biến, kiểu của biến, giá trị của biến. Ví dụ với khai báo: float x; // x là biến kiểu float x=12.5; //x có giá trị là 12.5 và lúc này, biến x chiếm một số ô nhớ liên tiếp trong bộ nhớ, mỗi ô nhớ có kích thước 1 byte (nhắc lại rằng một biến kiểu int chiếm 2 byte, một biến kiểu float chiếm 4 byte,…). Chú ý: địa chỉ của hai biến kiểu int liên tiếp cách nhau 2 byte, địa chỉ của hai biến kiểu float liên tiếp cách nhau 4 byte,… 9.1.2.con trỏ Con trỏ là một kiểu dữ liệu đặc biệt dùng để quản lý địa chỉ của các ô nhớ. Một con trỏ quản lý các địa chỉ mà dữ liệu tại các địa chỉ này có kiểu T thì con trỏ đó được gọi là con trỏ kiểu T. Con trỏ kiểu T chỉ được dùng để chứa địa chỉ của biến kiểu T; nghĩa là con trỏ kiểu int chỉ được dùng để chứa địa chỉ của biến kiểu int, con trỏ kiểu float chỉ được dùng để chứa địa chỉ của các biến kiểu float. 9.1.3.khai báo con trỏ [type] *< pointer_var_name > Chằng hạn với khai báo int x, *px; // x là biến int, còn px là con trỏ kiểu int. 9.1.4.phép lấy địa chỉ của một biến Cú pháp: &< var_name > ví dụ &a lần lượt là địa chỉ của các biến a Chằng hạn với khai báo int a;

Bài tập lập trình căn bản – SGU2010

Trang 87

Muốn biết địa chỉ của biến a ta dùng cách làm sau: cout<<&a<<&b; Lưu ý: -Khi một con trỏ chưa trỏ tới bất kỳ một địa chỉ nào, thì con trỏ đó được gọi là con trỏ NULL. -Con trỏ NULL có địa chỉ là 0000. 9.1.5.phép toán lấy giá trị tại một địa chỉ mà một con trỏ đang trỏ tới. Cú pháp: * < pointer_var_name > chẳng hạn với khai báo int a=10; // biến a có giá trị là 10 int px=&a; // px là con trỏ trỏ đến địa chỉ của biến a thì lúc này nội dung tại địa chỉ mà con trỏ px trỏ đến (tức là giá trị của biến a) là 10. Cần chú ý rằng việc thay đổi giá trị của *px sẽ làm cho giá trị của a thay đổi theo và ngược lại. Chẳng hạn với khai báo int a=10; int *px=&a; *px=*px+2 sẽ làm biến a có giá trị là 12. 9.2.Quy tắc sử dụng con trỏ trong các biểu thức Sử dụng tên con trỏ Con trỏ cũng là một biến, nên khi tên của nó xuất hiện trong một biểu thức thì giá trị của nó sẽ được sử dụng trong biểu thức này. Lưu ý: giá trị của một con trỏ là địa chỉ của một biến nào đó. Trong phép gán mà con trỏ đứng bên trái thì giá trị bên phải là một địa chỉ. Nội dung của một con trỏ cũng có thể được thay đổi. Sử dụng dạng khai báo của con trỏ. Nếu px là con trỏ trỏ tới biến x thì các cách viết x và *px là tương đương nhau.

Bài tập lập trình căn bản – SGU2010

Trang 88

Khi biết được địa chỉ của một biến thì chẳng những chúng ta có thể sử dụng giá trị của nó mà còn có thể gán cho nó một giá trị mới (làm thay đổi nội dung của nó); điều này sẽ được áp dụng khi cần để nhận biết kết quả của hàm thông qua các tham biến. 9.3.Các thao tác trên con trỏ 9.3.1.Phép toán cộng/trừ các địa chỉ Cú pháp : < pointer_var_name > + số kiểu int < pointer_var_name > - số kiểu int int x,*px; px=&x; cout<<px<<endl; //neu dia chi cua px la fff4 px=px+2; cout<<px<<endl; //neu dia chi cua px la fff8 px=px-1; cout<<px<<endl; //neu dia chi cua px la fff6 9.3.2.cấp phát động bộ nhớ +Toán tử new Dạng 1: <pointer_var_name>=new <type>; Cấp phát sizeof (<type>) bytes nhớ trong khối nhớ heap. Nếu cấp phát thành công, hàm trả về địa chỉ đầu của khối nhớ cấp phát được cho con trỏ pointer_var_name. Nếu khối nhớ heap không đủ để cấp phát hàm trả về con trỏ NULL. Dạng 2: <pointer_var_name>=new <type>[N_blocks]; Tương tự như trên, câu lệnh dạng này cấp phát N_blocks*sizeof (<type>) bytes nhớ. Chẳng hạn với khai báo char *pc; pc=new char[10]; // cấp phát 10 khối nhớ 1 byte và cho con trỏ pc trỏ tới địa chỉ của khối nhớ đầu tiên của khối nhớ này. Lưu ý: Cần kiểm tra xem việc cấp phát có thành công hay không. Nếu cấp phát thành công, con trỏ mới bắt đầu trỏ tới địa chỉ đầu của khối nhớ được cấp phát

Bài tập lập trình căn bản – SGU2010

Trang 89

và lúc này chúng ta mới có thể thực hiện các thao tác trên con trỏ này. Chẳng hạn xem đoạn chương trình sau: int *pi; pi= new int; if (pi==NULL) { cout<<"khong du bo nho"; exit(0); } +Từ khóa sizeof Cú pháp: sizeof(<type>) hoặc sizeof(<expression>) Cho biết kích thước lưu trữ các giá trị có kiểu dữ liệu <type> hoặc của kiểu dữ liệu của giá trị biểu thức expression. Chẳng hạn với đoạn chương trình sau: cout<<sizeof(char); cout<<sizeof(int); cout<<sizeof(float); cout<<sizeof(double); cout<<sizeof(long double); thì kết quả là 1 2 4 8 10 hoặc với đoạn chương trình cout<<sizeof('c'); cout<<sizeof(2003); cout<<sizeof(54321); cout<<sizeof(200.3); thì kết quả là 1 2 4 8 9.3.3.Giải phóng khối nhớ đã được cấp phát -Hàm delete void delete <pointer_var_name> Tác dụng: Giải phóng khối nhớ được cấp phát bằng toán tử new mà khối nhớ này đang được quản lý bởi con trỏ <pointer_var_name >

Bài tập lập trình căn bản – SGU2010 Ví dụ delete pc;

Trang 90

-hàm free Cú pháp: void free (<pointer_var_name>) Tác dụng: Giải phóng khối nhớ được cấp phát bằng hàm malloc, calloc mà khối nhớ này đang được quản lý bởi con trỏ <pointer_var_name>. B.CÁC DẠNG BÀI TẬP Dạng 1 : Sử dụng hàm có đối con trỏ. Ví Dụ 9-1.Hoán đổi giá trị của hai biến x,y. Ở các chương trước, chúng ta đã biết cách thiết kế hàm hoán vị này rôi. Sau đây là sử dụng hàm có đối con trỏ. Chương trình 9-1 #include<conio.h> #include<iostream.h> void hoanvi(int *x,int *y); void main() { clrscr(); int a=1, b=2; hoanvi(&a,&b); cout<<a<<b; getch(); } void hoanvi(int *x,int *y) { int temp=*x;*x=*y;*y=temp; } Dạng 2: Con trỏ với mảng 1 chiều Trong C, tên của một mảng là một hằng con trỏ trỏ tới địa chỉ của phần tử đầu tiên của mảng. Chúng ta có thể truy cập tới các phần tử của mảng thông qua địa chỉ của nó bằng cách xuất phát từ địa chỉ phần tử của đầu tiên.

Bài tập lập trình căn bản – SGU2010

Trang 91

Nếu a là mảng một chiều thì trong mọi ngữ cảnh các cách viết sau là tương đương: a, &a[0]; a+i, &a[i] *(a+i), a[i]; Sau đây là một số ví dụ, ở đây chúng ta giải quyết theo hướng có cấp phát vùng nhớ động. Ví dụ 9-2. Tìm số lớn nhất của một dãy n số nguyên nhập từ bàn phím Chương trình 9-2 #include <alloc.h> #include <iostream.h> #include <conio.h> void nhap(int *a, int n); void timgiatriln(int *a, int n); void main() { clrscr(); int *a,n; cout<<"Nhap so phan tu cua mang :";cin>>n; a=new int [n]; nhap(a,n); timgiatriln(a,n); getch(); } void nhap(int *a, int n) { for (int i=0;i<n;i++) cin>>*(a+i); } void timgiatriln(int *a, int n) {

Bài tập lập trình căn bản – SGU2010 int max=*a; for (int i=1;i<n;i++) if (*(a+i)>max) max=*(a+i); cout<<"Gia tri lon nhat la : "<<max; }

Trang 92

Dạng 3: Con trỏ với mảng hai chiều Như chúng ta đã nói trong phần mảng một chiều với con trỏ. Tên của mảng là một hằng con trỏ trỏ đến phần tử đầu tiên của mảng, dựa vào phần tử đầu tiên này mà có thể truy cập đến các phần tử khác trong mảng. Tuy nhiên cần chú ý rằng. Với mảng một chiều *a=1; *(a+1)=2;*(a+2)=3;*(a+3)=4; và phép truy xuất a[2] là hợp lý, tuy nhiên ta không thể truy xuất a[i][j], mà khi đó phần tử ở dòng i cột j của mảng a được truy xuất bởi *(a+n*i+j). cột 1 dòng 0 dòng 1 dòng 2 2 a0 3 a4 3 a8 cột 1 3 a1 8 a5 1 a9 cột 2 4 a2 4 a6 2 a10 cột 3 6 a3 7 a7 5 a11

Việc cấp phát vùng nhớ động để lưu trữ dữ liệu mảng làm tránh lãng phí bộ nhớ. Chẳng hạn với khai báo int a[20][50] thì máy đã cấp phát đúng 20*50 = 1000 khối nhớ 2 byte cho mảng a và nếu thực tế m, n là một số rất bé thì mảng a vẫn chiếm hết 1000 khối nhớ 2 byte. Vấn đề này sẽ được khắc phục bằng cách dùng con trỏ. Ví dụ 9-3. Viết chương trình nhập mảng hai chiều, các phần tử là các số nguyên và một số nguyên x. Hãy đếm xem trong mảng có bao nhiêu số bằng x? Chương trình 9-3 #include<conio.h> #include<iostream.h>

Bài tập lập trình căn bản – SGU2010 #include<stdio.h> #include<alloc.h> void nhap(int *a,int m, int n); void demsobangx(int *a, int m, int n, int x); void main() { int *a,m,n,x; clrscr(); cout<<"Nhap vao so dong:"; cin>>m; cout<<"Nhap vao so cot:"; cin>>n; a=new int [m*n]; nhap(a,m,n); demsobangx(a,m,n,x); getch(); } void nhap(int *a, int m, int n) { for (int i=0;i<m;i++ ) for (int j=0;j<n;j++ ) cin>>*(a+n*i+j); } void demsobangx(int *a, int m, int n, int x) { cout<<"Nhap vao so x can kiem tra :"; cin>>x; int d=0; for (int i=0;i<m;i++ ) for (int j=0;j<n;j++ ) if (x==*(a+n*i+j))

Trang 93

Bài tập lập trình căn bản – SGU2010 { d++; cout<<i<<" "<<j<<endl; } cout<<"So lan xuat hien cua x la : "<<d; }

Trang 94

C.BÀI TẬP BT9-1.Viết các hàm tính tổng, hiệu, tích, thương hai số nguyên a,b. Yêu cầu có sử dụng đối số hàm dạng con trỏ. BT9-2.Nhập vào n số nguyên từ bàn phím.Hãy xuất ra màn hình lần lượt đầu tiên là các số chẵn, sau đó là các số lẻ. BT9-3.Nhập vào ma trận m dòng n cột. Hãy tìm dòng có tổng lớn nhất. BT9-4.Nhập vào ma trận m dòng n cột. Hãy sắp xếp các cột theo chiều giảm dần. BT9-5.Nhập vào ma trận m dòng n cột. Hãy dịch các cột của ma trận qua phải 1 vị trí. BT9-6.Nhập vào ma trận m dòng n cột. Các phần tử là các số nguyên. a.Hãy tính tổng các phần tử trên từng dòng b.Hãy sắp các dòng theo chiều tăng dần c.Hãy sắp xếp mảng theo chiều tăng từ trái sang phải và từ trên xuống dưới.

Bài tập lập trình căn bản – SGU2010 Chương 10

Trang 95

CHUỖI
A.TÓM TẮT LÝ THUYẾT 10.1.ký tự và chuỗi ký tự Ký tự được đặt giữa hai dấu nháy đơn. Chuỗi ký tự là một dãy các ký tự liên tiếp kết thúc bằng ký tự NULL(“\0”), trên màn hình sẽ không nhìn thấy ký tự kết thúc này còn trong bộ nhớ thì nó sẽ chiếm một byte. Chuỗi ký tự đặt trong dấu nháy kép. Chẳng hạn để khai báo biến ký tự ch và gán ký tự A cho ch ta làm như sau: char ch=’A’; . Để khai báo biến chuỗi ký tự ta có thể làm như sau: char* st1=“Thanh Pho Ho Chi Minh”; hoặc char st2[30]=“Thanh Pho Ho Chi Minh”; 10.2.Nhập xuất ký tự Hàm getchar() Dùng để đọc một ký tự từ bàn phím và trả về ký tự đó. Hàm này luôn chờ cho đến khi gặp ký tự xuống dòng mới trả về, vì vậy khi sử dụng luôn phải gõ thêm phím ENTER và sẽ làm phát sinh thêm một ký tự nữa vào bộ nhớ đệm bàn phím. Khi gọi getchar() lần nữa thì sẽ lấy ký tự trong vùng đệm này. Hàm getch() Có cùng chức năng như hàm getche(), nhưng getch() nhập ký tự mà không hiện ra màn hình, trong khi getche() nhập ký tự và ký tự đó có hiện ra màn hình. Hàm putchar() Dùng để xuất một ký tự ra màn hình. 10.3.Nhập/xuất chuỗi ký tự Hàm gets(s)

Bài tập lập trình căn bản – SGU2010

Trang 96

Cho nhập từ bàn phím một chuỗi ký tự cho đến khi gặp ký tự xuống dòng thì đưa chuỗi này vào biến s và thay ký tự xuống dòng bằng ký tự NULL (“\0”) Hàm puts(s) Xuất chuỗi ký tự s ra màn hình. B.CÁC DẠNG BÀI TẬP Ví dụ 10-1. Nhập từ bàn phím một chuỗi. Hãy viết các hàm thực hiện các công việc sau (các công việc là độc lập với nhau; giả thiết thêm rằng chuỗi không có khoảng trắng dư thừa ở đầu và cuối chuỗi). a.Hãy tách một từ bên phải (bên trái) của chuỗi ?. b.Hãy đưa các ký tự đầu của mỗi từ thành chữ hoa, còn các ký tự khác thành chữ thường. c.Đếm xem chuỗi có bao nhiêu từ ? Chương trình 10-1 #include <iostream.h> #include <conio.h> #include <string.h> #include <ctype.h> char *tachtutrai(char *s); char *tachtuphai(char *s); char *chuanhoatu(char *s); int demsotu(char *s); void main() { clrscr(); char *s; s="thanH pHO Ho Chi Minh"; cout<<tachtuphai(s); cout<<chuanhoatu(s); cout<<demsotu(s); getch();

Bài tập lập trình căn bản – SGU2010 } char *tachtutrai(char *s) { return strlen(strrev(strrchr(strrev(s),' ')+1); } char *tachtuphai(char *s) { return strrchr(s,' ')+1; } char *chuanhoatu(char *s) { strlwr(s); for (int i=0;i<strlen(s);i++) if (s[i]==' ' && s[i+1]!=' ' ) s[i+1]=toupper(s[i+1]); if (s[0]!=' ') s[0]=toupper(s[0]); return s; } int demsotu(char *s) { int l=strlen(s),d=0; for (int i=0;i<l;i++) if (s[i]==' ' && s[i+1]!=' ') d++; return d; }

Trang 97

Lưu ý: Vấn đề tách một từ bên trái chuỗi s sẽ được giải quyết nếu xác định được vị trí cuối +1 của từ bên trái; để xác định được vị trí đó có thể sử dụng vòng lặp để tìm hoặc cũng có thể sử dụng cú pháp sau: strchr(s,’ ‘) - s

Bài tập lập trình căn bản – SGU2010

Trang 98

Ví dụ 10-2.Cho chuỗi s gồm các từ, mỗi từ cách nhau đúng một khoảng trắng (giả sử đầu và cuối chuỗi không có khoảng trắng nào dư thừa, câu này chỉ chứa các ký tự chữ cái). Hãy viết hàm đếm xem chuỗi s có bao nhiêu từ có đúng hai ký tự ?
Test 1 Input S=”ta ve ta tam ao ta” Output: 5 Input S=”Dat nuoc toi thon tha giot dan bau” Output: 0 Test 2

int demtu2kytu(char *s) { int sotu=0; int demkytu=0; for (int i=0;i<strlen(s);i++) if (s[i]!=' ') demkytu++; else { if (demkytu==2) sotu++; demkytu=0; } if(demkytu==2) sotu++; return sotu; } Cách khác: int demtu2kytu(char s[]) { int l=strlen(s),d=0; for (int i=0;i<l;i++) if (s[i]==' ' && s[i+3]==' ') d++; if (s[2]==' ' || s[2]=='\0') d++; // Xử lý cho từ đầu tiên của chuỗi

Bài tập lập trình căn bản – SGU2010

Trang 99

if (s[l-3]==' ' && s[l]=='\0') d++;// Xử lý cho từ cuối cùng của chuỗi return d; } Ví dụ 10-3.Cho chuỗi s gồm các từ, mỗi từ cách nhau đúng một khoảng trắng (giả sử đầu và cuối chuỗi không có khoảng trắng nào dư thừa). Hãy viết hàm đếm xem chuỗi s có bao nhiêu từ bắt đầu bằng ký tự nguyên âm ? (các ký tự a, u, i, o, e là các nguyên âm).
Test 1 S=”ngay xua hoang thi” Output: 0 Output: 2 Test 2 S=”ao anh sut chi duong ta”

int demtu(char s[]) { int l=strlen(s),d=0; for (int i=0;i<l;i++) if (s[i]==' ' && (s[i+1]=='a' ||s[i+1]=='u' || s[i+1]=='i' || s[i+1]=='o' || s[i+1]=='e')) d++; // Kiểm tra ký tự đầu tiên if (s[0]=='a' ||s[0]=='u' || s[0]=='i' || s[0]=='o' || s[0]=='e') d++; return d; } VD10-4.Cho biết tần số xuất hiện của các chữ cái trong chuỗi (không kể ký tự trống). Input: Nếu nhập vào chuỗi là: abcabdca Ouput: Ký tự a xuất hiện 3 lần, ký tự b xuất hiện 2 lần, ký tự c xuất hiện 2 lần, ký tự d xuất hiện 1 lần. Chương trình 10-4 #include <conio.h> #include <iostream.h> #include <string.h> #include <stdio.h> void main()

Bài tập lập trình căn bản – SGU2010 {

Trang 100

char s[255]; gets(s); int l=strlen(s); int d[255]; for (int i=0;i<l;i++) d[s[i]]=0; for (i=0;i<l;i++) d[s[i]]++; for (i=0;i<l;i++) if (d[s[i]]!=0) { cout<<s[i]<<" xuat hien "<<d[s[i]]<<" lan" <<endl; d[s[i]]=0; }

} C.BÀI TẬP Viết chương trình hoàn chỉnh cho các bài tập sau đây BT10-1.Cho một chuỗi S bao gồm các chữ cái thường từ a đến z và ký tự khoảng trắng (chuỗi S tạo thành các từ). Hãy viết các hàm thực hiện các công việc sau: a.Đếm xem trong chuỗi có bao nhiêu nguyên âm a i o u e ? Bao nhiêu phụ âm ? b.Xuất bảng mã ASCII của từng ký tự (khác ký tự khoảng trắng) trong chuỗi (ví dụ nếu chuối S là AB CD thì kết quả là 65 66 67 68). c.In số lượng ký tự của mỗi từ trong chuỗi. BT10-2.Viết chương trình nhập vào một chuỗi, kiểm tra xem chuỗi đó có đối xứng hay không? (ví dụ: abccba hay ahdha là các chuỗi đối xứng). BT10-3.a.Nhập vào một câu gồm các từ; mỗi từ cách nhau đúng một khoảng trắng. a.Hãy tìm các từ có độ dài lớn nhất. b.Hãy xuất các từ theo chiều đảo ngược. BT10-4.a.Viết chương trình nhập một chuỗi ký tự. Hãy loại bỏ các khoảng

Bài tập lập trình căn bản – SGU2010

Trang 101

trắng bên trái, các khoảng trắng bên phải và giữa các từ chỉ giữ lại đúng một ký tự khoảng trắng. b.Xuất chuỗi S ra màn hình sao cho mỗi từng nằm trên một dòng và không có khoảng trắng đứng trước từ. c.Cho chuỗi S. Hãy kiểm tra xem S có chứa ký tự nào khác ngoài các ký tự a-z, A-Z và khoảng trắng ‘ ‘ không ? Nếu có hãy xóa các ký tự đó ra khỏi S. BT10-5.a.Sao chép nội dung chuỗi s2 thành chuỗi s1 (không sử dụng các hàm sao chép chuỗi của C/C++. b.Nhập chuỗi s. Hãy xóa n ký tự trong chuỗi s kể từ vị trí thứ k của chuỗi s. c.Nhập chuỗi s1, s2. Hãy chèn s2 vào vị trí thứ k của s1 BT10-6.Chuyển đổi số giữa các hệ đếm sau: a.Hệ đếm thập phân và hệ đếm La mã b.Hệ đếm thập phân và hệ đếm thập lục phân c.Hệ đếm nhị phân và hệ đếm thập phân. BT10-7.Cho hai chuỗi s1 và s2. Kiểm tra xem tất cả các ký tự của chuỗi s1 đều thuộc về chuỗi s2 hay không ? BT10-8*.Cho hai chuỗi s1 và s2.Tìm chuỗi con chung dài nhất của s1 và s2 (xâu con này không nhất thiết phải là các ký tự là liên tiếp). BT10-9.Hãy đọc tiếng việt không dấu một số nguyên ≥ 0. Ví dụ: Input: 2010 Ouput : Hai nghin khong tram muoi. BT10-10.Cho số nguyên không âm < 1000 tỷ. Hãy lập dấu chấm (.) phân cách giữa các lớp. Ví dụ: Input: s=2010101090 Output : 2.010.101.090

Bài tập lập trình căn bản – SGU2010 Chương 11

Trang 102

KIỂU CẤU TRÚC
A.TÓM TẮT LÝ THUYẾT 11.1.Kiểu dữ liệu cấu trúc Kiểu dữ liệu cấu trúc là kiểu cấu trúc do người dùng định nghĩa, có cấu trúc là một mảng nhiều phần tử; mỗi phần tử có thể có nhiều thành phần, mỗi thành phần này thuộc về một kiểu dữ liệu nào đó, kiểu dữ liệu này có thể là kiểu dữ liệu chuẩn hay cũng có thể là kiểu dữ liệu cấu trúc mà người lập trình đã định nghĩa trước đó. Ví dụ về một bảng tính lương đơn giản TT 1 2 3 Họ và tên Nguyễn Văn Thành Bùi Phương Thảo Lê Tuấn Ngày sinh 12/10/1972 01/01/1981 11/12/1983 Lương cơ bản 960000 780000 750000 thưởng 1200000 1200000 1200000 Thực lãnh 2160000 1980000 1950000

Nhìn vào bảng này, ta thấy rằng dữ liệu gồm nhiều phần tử (dòng), mỗi dòng là tập hợp nhiều thành phần con, mỗi thành phần này thuộc về một kiểu dữ liệu nào đó. Như thế ta có thể nói rằng:kiểu dữ liệu cấu trúc là một sự mở rộng của kiểu dữ liệu mảng mà mỗi phần tử của mảng lúc này có nhiều thành phần. 11.2.Khai báo cấu trúc- Khai báo biến cấu trúc Đinh nghĩa một kiểu dữ liệu có cấu trúc mới struct tên_kiểu_cấu_trúc { //khai báo các thành phần của cấu trúc <kiểu dữ liệu> <tên thuộc tính 1> <kiểu dữ liệu> <tên thuộc tính 2> <kiểu dữ liệu> <tên thuộc tính 3> … } [tên biến cấu trúc];

Bài tập lập trình căn bản – SGU2010

Trang 103

Trong đó struct là từ khóa, tên_kiểu_cấu_trúc là một tên bât kỳ do người lập trình tự đặt, thành phần của cấu trúc có thể là : biến, mảng,. . . hoặc một cấu trúc khác mà kiểu của nó đã được định nghĩa từ trước. chẳng hạn sau đây là cấu trúc của bảng lương trên struct HOSO { char hoten [30]; struct ngaysinh long luongcoban long thuong; long thuclanh; }; thành phần của cấu trúc có thể có kiểu là một cấu trúc đã được định nghĩa trước. Chẳng hạn ví dụ sau: struct NGAY { int ngay; int thang; int nam; }; struct HOSO { char hoten [30]; struct NGAY ns; long LCB; long thuong; long thuclanh; }; Khai báo biến có cấu trúc <kiểu cấu trúc> <tên biến cấu trúc>

Bài tập lập trình căn bản – SGU2010 Chẳng hạn: hoadon hoadon

Trang 104

temp; * mh;

11.3.Truy xuất đến từng thành phần của cấu trúc 11.3.1.Biến cấu trúc được khai báo tỉnh Với cấu trúc đơn tên biến cấu trúc.tên thành phần Ví dụ: nv[i].hoten; nv[i].thuong; Với cấu trúc kép Tên biến cấu trúc.tên biến cấu trúc.tên thành phần được dùng khi biến hoặc mảng là thành phần trực tiếp của một cấu trúc mà bản thân cấu trúc này lại là thành phần của một cấu trúc lớn hơn. nv[i]. ns.ngay; nv[i]. ns.thang; nv[i]. ns.nam; 11.3.2.Biến cấu trúc được khai báo động tên biến cấu trúc ® tên thành phần. Nếu dùng con trỏ kiểu cấu trúc (mh+i))->mahang; (mh+i)->dongia; B.CÁC DẠNG BÀI TẬP Dạng 1.Một số bài toán hình học Ví dụ 11-1. Trong mặt phẳng tọa độ OXY cho 3 điểm O,A,B. trong đó O có tọa độ (0;0), A có tọa độ (x,y) với x,y là hai số nguyên dương và B có tọa độ (z;0) với z là số nguyên dương. Viết chương trình đếm số điểm có tọa độ nguyên nằm bên trong tam giác OAB – không đếm các điểm trên cạnh. Thuật toán

Bài tập lập trình căn bản – SGU2010

Trang 105

Tìm hình chữ nhật nhỏ nhất bao tam giác OAB; hình chữ nhật này có các cạnh song song với các trục tọa độ và có đỉnh dưới trái là (0,0) và đỉnh trên phải là (max(x,z),y). Sau đó duyệt từng diểm trong hình chữ nhật này, điểm nào nằm trong tam giác OAB thì sẽ được đếm tăng là 1. Lưu ý: Điểm M nằm trong tam giác OAB, nếu SDMOA + SDMOB + SDMAB = SDOAB. Chương trình 11-1 #include <math.h> #include <iostream.h> struct toado { int x; int y; }; void nhap(toado &A,toado &B, toado &O); double kc(toado A, toado B); double dientich(toado A, toado B, toado C); int diemnamtrong(toado A, toado B, toado O, toado M); int max(int x, int y); void dem(toado A, toado B, toado O); void main() { toado A,B,O; nhap(A,B,O); dem(A,B,O); } void nhap(toado &A,toado &B, toado &O) { cout<<"\nNhap toa do diem A : ";cin>>A.x>>A.y; cout<<"\nNhap hoanh do diem B: ";cin>>B.x;\

Bài tập lập trình căn bản – SGU2010 cout<<"\nTung do diem B la 0"; cout<<"\nToa do diem O la (0,0)"; B.y=0; O.x=0; O.y=0;

Trang 106

} double kc(toado A, toado B) { return sqrt((B.x - A.x)*(B.x-A.x) + (B.y - A.y)*(B.y - A.y)); } int thuoccanh(toado A, toado B, toado M) { return fabs(kc(A,M)+kc(B,M)-kc(A,B))<=1.E-6; } double dientich(toado A, toado B, toado C) { double a=kc(B,C); double b=kc(A,C); double c=kc(A,B); double p=(a+b+c)/2; double s=sqrt(p*(p-a)*(p-b)*(p-c)); return s; } int diemnamtrong(toado A, toado B, toado O, toado M) { if (!thuoccanh(O,A,M) && !thuoccanh(O,B,M) && !thuoccanh(A,B,M)) if (fabs(dientich(M,A,B)+dientich(M,A,O)+dientich(M,B,O)dientich(A,B,O))<=1.E-6) return 1; return 0; }

Bài tập lập trình căn bản – SGU2010

Trang 107

int max(int x, int y) { return x>y?x:y; } void dem(toado A, toado B, toado O) { toado M; int maxx=max(A.x,B.x); int d=0; for (int i=0;i<=maxx;i++) for (int j=0;j<=A.y;j++) { M.x=i;M.y=j; if (diemnamtrong(A,B,O,M)) d++; } cout<<"\nSo diem co toa do nguyen nam trong tam giac OAB la : "<<d; }
Các bộ test mẫu Test 1 2 3 x 0 5 10 y 4 4 9 z 4 4 1 Kết quả 3 6 0

Ví dụ 11-2.Cho mảng một chiều gồm n tọa độ điểm, tọa độ điểm là các số nguyên. a.Hãy tìm một điểm trong mảng xa gốc tọa độ nhất. b.Hãy tìm tọa độ hai điểm gần nhau nhất. Ví dụ n = 5 và tọa độ 5 điểm là: (0,0); (0,3); (3,3); (4,1); (4,4). Thì kết quả câu a là điểm (4,4) và kết quả câu b là (3,3) và (4,4) Chương trình 11-2 #include <conio.h> #include <math.h>

Bài tập lập trình căn bản – SGU2010 #include <iostream.h> #include <stdio.h> struct toado { int x; int y; }; void nhap(toado diem[], int &n); float khoangcach(int xa, int ya, int xb, int yb); void diemxagoc(toado diem[], int n); void haidiemgannhau(toado diem[], int n); void main() { clrscr(); int n; toado diem[100]; nhap(diem,n); diemxagoc(diem,n); haidiemgannhau(diem,n); getch(); } void nhap(toado diem[], int &n) { cout<<"\nNhap so diem :";cin>>n; for (int i=0;i<n;i++) { cout<<"nhap hoanh do : ";cin>>diem[i].x; cout<<"nhap tung do : ";cin>>diem[i].y; } } float khoangcach(int xa, int ya, int xb, int yb)

Trang 108

Bài tập lập trình căn bản – SGU2010 { return sqrt((xb-xa)*(xb-xa)+(yb-ya)*(yb-ya));

Trang 109

} void diemxagoc(toado diem[], int n) { toado M; float kc=0; for (int i=0;i<n;i++) if (khoangcach(diem[i].x, diem[i].y,0,0)>kc) { kc=khoangcach(diem[i].x, diem[i].y,0,0); M.x=diem[i].x; M.y=diem[i].y; } cout<<"\nDiem xa goc toa do nhat co toa do:"<<M.x<<","<<M.y; } void haidiemgannhau(toado diem[], int n) { float kc=32767; toado M,N; for (int i=0;i<n-1;i++) for (int j=i+1;j<n;j++) if (khoangcach(diem[i].x, diem[i].y,diem[j].x, diem[j].y)<kc) { kc=khoangcach(diem[i].x, diem[i].y,diem[j].x, diem[j].y); M.x=diem[i].x; M.y=diem[i].y; N.x=diem[j].x; N.y=diem[j].y; }

Bài tập lập trình căn bản – SGU2010

Trang 110

cout<<"\nHai diem gan nhau nhat la: "<<M.x<<","<<M.y<<" va "<<N.x<<","<<N.y; } Ví dụ 11-3.Viết chương trình cộng hai phân số. Yêu cầu phân số kết quả phải ở dạng tối giản. Chương trình 11-3 #include <iostream.h> #include <conio.h> struct phanso { int tu; int mau; }; void nhapps(phanso &ps); void xuatps(phanso ps); phanso congps( phanso ps1, phanso ps2); int uscln(int a, int b); void main() { clrscr(); phanso ps1,ps2; nhapps(ps1); nhapps(ps2); xuatps(congps(ps1,ps2)); getch(); } void nhapps(phanso &ps) { cout<<"Nhap vao tu so : "; cin>>ps.tu;

Bài tập lập trình căn bản – SGU2010 cout<<"Nhap vao mau so : "; cin>>ps.mau; }

Trang 111

void xuatps(phanso ps) { int uc=uscln(ps.tu,ps.mau); ps.tu=ps.tu/uc; ps.mau=ps.mau/uc; cout<<"Ket qua: "<<ps.tu<<"/"<<ps.mau<<endl; } phanso congps( phanso ps1, phanso ps2) { phanso ps; ps.tu=ps1.tu*ps2.mau+ps2.tu*ps1.mau; ps.mau=ps1.mau*ps2.mau; return ps; } int uscln(int a, int b) { int r=a%b; while (r!=0) { a=b;b=r;r=a%b; } return b; } Ví dụ 11-4.Cho mảng 1 chiều các phân số (tử số và mẫu số là các số nguyên). a.Hãy tìm phân số có giá trị lớn nhất. b.Sắp xếp các phân số theo chiều tăng dần Chương trình 11-4 #include <conio.h> #include <math.h>

Bài tập lập trình căn bản – SGU2010 #include <iostream.h> #include <stdio.h> struct phanso { int tu; int mau; }; void nhapmangps(phanso ps[], int &n); void xuatmangps(phanso ps[], int &n); int sosanhps(phanso ps1, phanso ps2); void timpslonnhat(phanso ps[], int n); void hoanvi(phanso &ps1, phanso &ps2); void sapxepmangps(phanso ps[], int n); void main() { clrscr(); phanso ps[100];int n; nhapmangps(ps,n); timpslonnhat(ps,n); sapxepmangps(ps,n); xuatmangps(ps,n); getch(); } void nhapmangps(phanso ps[], int &n) { cout<<"Nhap so luong phan so n = ";cin>>n; for (int i=0; i<n;i++) { cout<<"Nhap phan so thu "<<i<<":"<<endl; cin>>ps[i].tu; cin>>ps[i].mau;

Trang 112

Bài tập lập trình căn bản – SGU2010 }

Trang 113

} void xuatmangps(phanso ps[], int &n) { cout<<endl; for (int i=0; i<n;i++) cout<<ps[i].tu<<"/"<<ps[i].mau<<";"; } int sosanhps(phanso ps1, phanso ps2) { if (ps1.tu*ps2.mau>ps2.tu*ps1.mau>0) return 1; else if (ps1.tu*ps2.mau>ps2.tu*ps1.mau<0) return -1; else return 0; } void timpslonnhat(phanso ps[], int n) { phanso psmax; psmax.tu=ps[0].tu; psmax.mau=ps[0].mau; for (int i=1; i<n;i++) if (sosanhps(ps[i],psmax)>0) psmax=ps[i]; cout<<"\nPhan so lon nhat la : "<<psmax.tu<<"/"<<psmax.mau; } void sapxepmangps(phanso ps[], int n) { for (int i=0;i<n-1;i++)

Bài tập lập trình căn bản – SGU2010 for (int j=i+1;j<n;j++) if (sosanhps(ps[i],ps[j])>0) hoanvi(ps[i],ps[j]);

Trang 114

} void hoanvi(phanso &ps1, phanso &ps2) { phanso temp; temp=ps1; ps1=ps2; ps2=temp; } Ví dụ 11-5. Cho một danh sách lưu thông tin của các thí sinh khi thi tuyển vào lớp 10 với ba môn thi là Toán, Vật Lý và Anh Văn, thông tin gồm : - Số báo danh (chuỗi, tối đa 8 ký tự) - Họ tên (chuỗi, tối đa 20 ký tự) - Điểm môn Toán (số nguyên) - Điểm môn Vật lý (số nguyên) - Điểm môn Anh Văn (số nguyên) Hãy thực hiện yêu cầu sau: a.Hãy in lên màn hình những thí sinh có điểm tổng ≥ 18 và không có môn nào dưới điểm 5; danh sách này phải được sắp theo thứ tự điểm tổng giảm dần. b.Xóa hồ sơ thí sinh có số báo danh là x. c.Cập nhật điểm thi của một thí sinh có số báo danh là y (là chuỗi ký tự) theo các giá trị mới nhập từ bàn phím. Chương trình 11-5 #include <iostream.h> #include <string.h> #include <stdio.h> #include <conio.h> struct diem {

Bài tập lập trình căn bản – SGU2010 char char int int int int sobd[8]; hoten[20]; toan; ly; anhvan; tong;

Trang 115

}; void nhap(diem hs[], int &n); void xuat(diem hs[], int n); void sapxep(diem hs[], int n); void xuatkq(diem hs[], int n); void xoahoso(diem hs[], int &n); void capnhathoso(diem hs[], int n); void main() { diem hs[100]; int n; nhap(hs,n); xuat(hs,n); sapxep(hs,n); xuatkq(hs,n); xoahoso(hs,n); xuat(hs,n); capnhathoso(hs,n); xuat(hs,n); } void nhap(diem hs[], int &n) { cin>>n; for (int i=0;i<n;i++) {

Bài tập lập trình căn bản – SGU2010 cout<<"So bao danh: "; flushall(); gets(hs[i].sobd); cout<<"Ho va ten: "; flushall(); gets(hs[i].hoten); cout<<"Diem toan:";cin>>hs[i].toan; cout<<"Diem ly:";cin>>hs[i].ly; cout<<"Diem anh van:";cin>>hs[i].anhvan; hs[i].tong=hs[i].toan+hs[i].ly+hs[i].anhvan; cout<<endl; }

Trang 116

} void xuat(diem hs[], int n) { cout<<"\nBang diem:\n"; for (int i=0;i<n;i++) cout<<hs[i].sobd<<hs[i].hoten<<hs[i].toan<<hs[i].ly<<hs[i].anhva n<<endl; } void sapxep(diem hs[], int n)// cau 1 - Sap xep { for (int i=0;i<n-1;i++) for (int j=i+1;j<n;j++) if (hs[i].tong<hs[j].tong) { diem temp=hs[i]; hs[i]=hs[j]; hs[j]=temp; } }

Bài tập lập trình căn bản – SGU2010

Trang 117

void xuatkq(diem hs[], int n)//cau 1 - Xuat ket qua { cout<<"\nBang diem da sap xep:\n"; for (int i=0;i<n;i++) if (hs[i].tong>=18 && hs[i].toan>=5 && hs[i].ly>=5 && hs[i].anhvan>=5) cout<<hs[i].sobd<<hs[i].hoten<<hs[i].toan<<hs[i].ly<<hs[i].anhva n<<endl; } void xoahoso(diem hs[], int &n)// cau 2 { char *x; cout<<"Nhap so bao danh can xoa :"; gets(x); int k=0; while (k<n && strcmp(hs[k].sobd,x)!=0) k++; for (int i=k;i<n-1;i++) hs[i]=hs[i+1]; n--; } void capnhathoso(diem hs[], int n)// cau 3 { char *y; cout<<"Nhap so bao danh can sua :"; gets(y); int k=0; while (k<n && strcmp(hs[k].sobd,y)!=0) k++; cout<<"Diem toan:";cin>>hs[k].toan; cout<<"Diem ly:";cin>>hs[k].ly; cout<<"Diem anh van:";cin>>hs[k].anhvan; hs[k].tong=hs[k].toan+hs[k].ly+hs[k].anhvan; }

Bài tập lập trình căn bản – SGU2010
Các bộ test mẫu Sobd 09001 09002 09003 09004 Kết quả: a. sobd 09002 09001 hoten Le Thi Binh Nguyen Van Thanh toan 6 6 ly 5 7 hoten Nguyen Van Thanh Le Thi Binh Nguyen Van An Tran Van Giau toan 6 6 9 5 ly 7 5 8 5

Trang 118

Hoa 5 10 4 5

Hoa 10 5

b.Nhập số báo danh cần xóa là: 09003, ta được kết quả là: sobd 09002 09001 09004 hoten Le Thi Binh Nguyen Van Thanh Tran Van Giau toan 6 6 5 ly 5 7 5 Hoa 10 5 5

c.Nhập số báo danh cần sửa là: 09004, và sửa các điểm thi của thí sinh này lần lượt là 6 6 5 ta được kết quả là: sobd 09002 09001 09004 hoten Le Thi Binh Nguyen Van Thanh Tran Van Giau toan 6 6 6 ly 5 7 6 Hoa 10 5 5

C.BÀI TẬP Viết chương trình hoàn chỉnh cho các bài toán sau đây BT11-1.Trong mặt phẳng tọa độ OXY cho n điểm xi,yi (i=1..n). a.Hãy cho biết tần số xuất hiện của các điểm. b.Hãy cho biết có bao nhiêu điểm nằm trong phần tư thứ nhất. BT11-2.Cho ma trận m dòng, n cột mỗi phần tử là một phân số ( tử số và mẫu số là các số nguyên). a.Hãy tìm phân số có giá trị lớn nhất. b.Đếm số lượng phân số tối giản c.In danh sách các phân số có giá trị lớn hơn 0 và nhỏ hơn 1.

Bài tập lập trình căn bản – SGU2010

Trang 119

BT11-3.Trong mặt phẳng tọa độ OXY, cho mảng một chiều gồm n đường thẳng. a.Hỏi n đường thẳng này có song song với nhau hay không ? b.Cho điểm P, hãy tìm các đường tròn gần điểm P nhất. BT11-4.Cho ma trận m dòng, n cột các phần tử là các phân số có tử số và mẫu số là các số nguyên. Hãy sắp xếp ma trận theo chiều tăng dần từ trên xuống dưới và từ trái qua phải. BT11-5a.Trong mặt phẳng tọa độ OXY cho 4 điểm A, B, C, D lần lượt có tọa độ là (xa,ya), (xb,yb), (xc,yc), (xd,yd). Hãy kiểm tra xem hai đoạn thẳng AB và CD có cắt nhau hay không ? BT11-5.b.Trong mặt phẳng tọa độ OXY cho ba điểm A(xa,ya); B(xb,yb), C(xc,yc) và một điểm M(xm,ym). Hãy xác định xem M nằm trong, nằm ngoài hay nằm trên biên của tam giác ABC ? BT11-6.Cho n hình chữ nhật có các cạnh song song với các trục tọa độ, mỗi hình chữ nhật biết toạ độ dưới trái, trên phải là x1[i],y1[i],x2[i],y2[i] (i=1..n). Hãy tính diện tích của hình được phủ bởi N hình trên. BT11-7.Cho một danh sách lưu thông tin của các nhân viên trong một công ty, thông tin gồm : - Mã nhân viên (chuỗi, tối đa là 8 ký tự) - Họ và tên (chuỗi, tối đa là 20 ký tự) - Năm sinh (số nguyên) - Phòng ban (chuỗi, tối đa 10 ký tự) - Lương cơ bản (số nguyên) - Thưởng (số nguyên) - Thực lãnh (số nguyên, trong đó thực lãnh = lương cơ bản + thưởng ) Hãy thực hiện yêu cầu sau: a.Tính tổng thực lãnh tháng của tất cả nhân viên trong công ty. b.In danh sách những nhân viên có mức lương cơ bản thấp nhất. c.Đếm số lượng nhân viên có mức thưởng >= 1200000. d.In danh sách các nhân viên tăng dần theo phòng ban, nếu phòng ban trùng nhau thì giảm dần theo mã nhân viên.

Bài tập lập trình căn bản – SGU2010

Trang 120

e.Cập nhật tăng lương của tất cả các nhân viên lên 5% BT11-8. Viết chương trình thực hiện các công việc sau: a.Nhập thông tin về một hoá đơn bán hàng với các thông tin: mã mặt hàng, tên mặt hàng, đơn giá, số lượng. b.Hãy in hoá đơn với các thông tin: mã mặt hàng, tên mặt hàng, đơn giá, số lượng., thành tiền, trong đó cột thành tiền = đơn giá*số lượng. c.Hãy tìm những mặt hàng có đơn giá cao nhất. d.Hãy sắp xếp mặt hàng theo chiều tăng dần của cột tên hàng. BT11-9.Viết chương trình thực hiện các công việc sau: a.Nhập vào hồ sơ của n nhân viên với các thông tin: Họ và tên, ngày sinh, lương cơ bản, thưởng, thực lãnh, trong đó thực lãnh = lương cơ bản + thưởng b.In danh sách nhân viên theo bậc lương giảm dẫn BT11-10.Viết chương trình nhập vào họ và tên (chuỗi không quá 35 ký tự) và điểm số (số nguyên từ 0 đến 10) của N thí sinh (10<N<=300). Tính và xuất bảng xếp hạng (gồm 3 cột: họ và tên, điểm số và hạng) các thí sinh theo 2 cách xếp hạng sau: Quy tắc chung cho cả 2 cách xếp hạng: -Các thí sinh có cùng điểm số sẽ có cùng hạng -Nếu thí sinh A có điểm số cao hơn thí sinh B thì hạng của thí sinh A cao hơn hạng của thí sinh B (có số thứ tự nhỏ hơn). Xếp hạng theo cách 1:Hạng được đánh liên tục từ 1 đến k với k là số nhóm các thí sinh có cùng điểm số. Xếp hạng theo cách 2:Hạng được đánh từ 1 đến N (không nhất thiết liên tục) theo quy tắc: nếu có m thí sinh hạng k thì hạng kế tiếp là m+k (k>=1).

Bài tập lập trình căn bản – SGU2010 Chương 12

Trang 121

FILE
A.TÓM TẮT LÝ THUYẾT 12.1.Khái niệm Các dữ liệu ta đã khảo sát điều hiện diện trong bộ nhớ ram khi khởi động chương trình, nhưng khi chấm dứt chương trình các dữ liệu bị xoá mất, vì vậy việc lưu trữ lâu dài hoặc sử dụng lại dữ liệu đó không thực hiện được. Chương này sẽ trình bày các thao tác cần thiết nhất đối với các loại file văn bản và file nhị phân để giải quyết được vấn đề đó. Chương này rất hữu ích cho các vấn đề bài toán cần xử lý dữ liệu vào/ra từ file như các thuật toán trong các học phần cấu trúc dữ liệu, hệ điều hành, trí tuệ nhân tạo,... 12.2. Khai báo con trỏ file Khi thao tác với các file dữ liệu, chúng ta thường không thao tác trực tiếp lên các file dữ liệu đó mà thông qua một vùng đệm của file là một phần của bộ nhớ. Để quản lý các vùng đệm của các file dữ liệu này thì C sử dụng các con trỏ kiểu FILE. Cách khai báo các con trỏ quản lý file như sau: FILE * <filepointer>; Trong đó filepointer là tên biến con trỏ kiểu FILE. 12.3.Một số hàm xử lý file văn bản thường dùng 12.3.1.Mở tập tin FILE *fopen (const char * filename, const char *mode); Lệnh này có tác dụng mở một file có tên là filename theo cách thức quy định ở trong mode. Trong đó: -filename là một chuỗi gồm đầy đủ cả đường dẫn, tên tập tin và phần mở rộng (nếu không có đường dẫn thì đường dẫn mặc nhiên là thư mục hiện hành. Khi đánh đường dẫn cần dùng hai dấu “\\”) -mode nhận các giá trị là wt khi cần mở file mới để ghi theo kiểu văn bản (nếu file đã tồn tại nó sẽ bị xoá) còn rt cho biết mở một file để đọc theo kiểu văn bản.

Bài tập lập trình căn bản – SGU2010

Trang 122

12.3.2.Đóng tập tin void fclose (FILE * filepointer); Lệnh này có tác dụng đóng file văn bản tương ứng với filepointer. Lệnh này thường được sử dụng sau khi đã kết thúc việc đọc hoặc ghi file. 12.3.3.Đưa dữ liệu vào tập tin void fprintf (FILE * filepointer,const char formattext, varname ); Lệnh này có tác dụng đưa dữ liệu varname - ứng với định dạng formattext vào file đang mở được quản lý bởi con trỏ file có tên là filepointer. Chẳng hạn nếu muốn ghi số nguyên x vào file có filepointer là f ta thực hiện câu lệnh như sau: fprintf(f,”%d”,x); Nếu muốn ghi một dòng trống vào file có filepointer là f thì ta thực hiện câu lệnh như sau: fprintf(f,"\n"); 12.3.4.Đọc dữ liệu từ tập tin void fscanf (FILE *filepointer, &varname); Lệnh này đọc dữ liệu tại vị trí con trỏ file và đưa giá trị vào varname. Nếu có nhiều varname, thì chúng cách nhau bởi một dấu phẩy. int feof (filepointer); Lệnh này nhận giá trị là khác 0 khi con trỏ file filepointer chưa được đặt ở cuối file. B.CÁC DẠNG BÀI TẬP Dạng 1: File văn bản với mảng một chiều các số nguyên Ví dụ 12-1.Viết chương trình ghi n số nguyên ngẫu nhiên vào file có tên là songuyen.inp, mỗi dòng 10 số. Sau đó đọc file này và đưa các số nguyên vào mảng một chiều. Chương trình 12-1 #include<stdio.h> #include<conio.h> #include<stdlib.h> void ghi_file(int n)

Bài tập lập trình căn bản – SGU2010 { FILE *f; int i,d=0; randomize(); f=fopen("songuyen.inp","wt"); for (i=1;i<=n;i++) { fprintf(f,"%6d",rand()); d++; if (d % 10==0) fprintf(f,"\n"); } fclose(f); } void doc_file() { FILE *f; int n=0; int a[10000]; f=fopen("songuyen.inp","rt"); while (!feof(f)) { n++; fscanf(f,"%d",&a[n]); } fclose(f); printf("%d",n); } void main() { clrscr();

Trang 123

Bài tập lập trình căn bản – SGU2010 int n; cin>>n; ghi_file (n); doc_file(); getch(); }

Trang 124

Dạng 2:File văn bản với mảng hai chiều các số nguyên Ví dụ 12-2.Viết chương trình tạo file văn bản có tên là “matran.inp” có cấu trúc như sau: -Dòng đầu ghi hai số m,n. -Trong m dòng tiếp theo mỗi dòng ghi n số các số cách nhau ít nhất một khoảng trắng. Hãy kiểm tra xem trong file đó có bao nhiêu số nguyên tố? kết quả cần ghi vào file “matran.out” với nội dung là một số nguyên duy nhất là số lượng các số nguyên tố trong file “matran.inp”. Chương trình 12-2 #include <stdio.h> #include <conio.h> #include <stdlib.h> #include <iostream.h> #define max 20 void docfile(); void ghiramang(); int ktsnt(int n); void demsont(); void ghirafile(); int a[max][max],m,n; int slnt=0; void main() { docfile();

Bài tập lập trình căn bản – SGU2010 ghiramang(); demsont(); ghirafile(); } //tao file ngau nhien void docfile() { clrscr(); file *f; f=fopen("matran.inp","wt"); cout<<"nhap vao so dong m="; cin>>m; cout<<"nhap vao so cot n="; cin>>n; randomize(); fprintf(f,"%4d%4d\n",m,n); for (int i=0;i<m;i++) { for (int j=0;j<n;j++) fprintf(f,"%4d",random(100)); fprintf(f,"\n"); } fclose(f); } //ghi file ra mang void ghiramang() { file *f; f=fopen("matran.inp","rt"); fscanf(f,"%d%d",&m,&n); for (int i=0;i<m;i++)

Trang 125

Bài tập lập trình căn bản – SGU2010 for (int j=0;j<n;j++) fscanf(f,"%4d",&a[i][j]); fclose(f); } int ktsnt(int n) { // hàm này đã có ở các chương trước } void demsont() { for (int i=0;i<m;i++) for (int j=0;j<n;j++) if (ktsnt(a[i][j])) slnt++; } void ghirafile() { file *f; f=fopen("matran.out","wt"); fprintf(f,"%4d",slnt); fclose(f); }

Trang 126

Dạng 3:File văn bản với các ký tự Hàm fputc(int ch, FILE *filepointer) ; ch là một giá trị nguyên, filepointer là con trỏ file. Hàm này ghi lên file filepointer một ký tự có mã bằng m=ch%255. Trong đó ch được xem là một số nguyên không dấu. Nếu thành công hàm cho mã ký tự được ghi, trái lại hàm cho giá trị EOF. Ví dụ 12-3.Chương trình tạo một file số nguyên chứa 255 ký tự chữ cái ngẫu nhiên (ký tự chữ thường) mỗi dòng 10 ký tự. Chương trình 12-3 #include <stdio.h>

Bài tập lập trình căn bản – SGU2010

Trang 127

#include <stdlib.h> void main() { FILE *f; char ch; randomize(); f=fopen("filechar.inp","wt"); for (int i=1;i<=255;i++) { fputc(random(25)+97,f); fputc(' ',f); if (i%10==0) fprintf(f,"\n") ; } fclose(f); } Lưu ý khi f được mở theo kiểu văn bản thì thì ký tự xuống dòng “\n” được ghi thành 2 mã 13 và 10. Do đó với ví dụ trên, khi chỉ xử các ký tự khác ký tự khoảng trắng và tất nhiên cả ký tự cuối mỗi dòng thì điều kiện là: ch!=32 && ch!=13 && ch!=10 Hàm fgetc(FILE *filepointer) Hàm đọc một ký tự từ file filepointer. Nếu thành công hàm cho mã đọc được(có giá trị từ 0 đến 255). Nếu gặp cuối file hay có lỗi hàm cho giá trị EOF. Ví dụ 12-4.Đọc từng ký tự trong file và xuất ra màn hình Chương trình 12-4 #include <stdio.h> void main() { FILE *f; char ch; f=fopen("filechar.inp","rt"); while (!feof(f))

Bài tập lập trình căn bản – SGU2010 { ch=fgetc(f); putchar(ch); } fclose(f); }

Trang 128

Dạng 4:File văn bản với chuỗi ký tự int fputs(const char*s, FILE * filepointer); Trong đó: -s là con trỏ trỏ tới địa chỉ đầu của một chuỗi ký tự kết thúc bằng ‘\0’ -filepointer là con trỏ file. Lệnh này có tác dụng ghi chuỗi s lên file filepointer (dấu ‘\0’ không ghi lên file). Khi thành công, hàm này trả về ký tự cuối cùng được ghi lên file. Khi có lỗi hàm sẽ cho giá trị EOF. Thường khi ghi nhiều dòng, mỗi phần tử trên mỗi dòng thì việc ghi một dấu kết thúc dòng có thể sử dụng lệnh fputc (10,f) hoặc cú pháp fprintf(f,”\n”) như đã có trình bày trong những phần trước. Ví dụ 12-5.Tạo một file chứa n chuỗi, mỗi chuỗi được ghi trên một dòng. Chương trình 12-5 #include <conio.h> #include <iostream.h> #include <stdio.h> void main() { clrscr(); char *s; FILE *f; int n; f=fopen("chuoi.inp","wt"); cin>>n; for (int i=1;i<=n;i++) {

Bài tập lập trình căn bản – SGU2010 gets(s); fputs(s,f); fprintf(f,"\n"); } fclose(f); getch(); }

Trang 129

char *fgets(char *s, int n, FILE *filepointe) Trong đó: -s là con trỏ kiểu char trỏ tới một vùng nhớ đủ lớn để chứa chuỗi ký tự đọc từ file -n là số nguyên xác định độ dài cực đại của dãy cần đọc. Lệnh này có tác dụng đọc một dãy ký tự từ file filepointe chứa vào vùng nhớ s. Việc đọc sẽ kết thúc khi: hoặc đã đọc n-1 ký tự hoặc gặp dấu xuống dòng (cặp mã 13 và 10). Khi đó mã 10 được đưa vào chuỗi kết quả hoặc là kết thúc file. Chuỗi kết quả sẽ được bổ sung thêm dấu hiệu kết thúc chuỗi ‘\0’. Khi thành công, hàm trả về địa chỉ vùng nhận kết quả. Khi có lỗi hoặc gặp cuối file hàm cho giá trị NULL. Ví dụ 12-6. Đọc một file chuoi.inp chứa mỗi chuỗi trên một dòng. Chương trình 12-6 #include <conio.h> #include <stdio.h> void main() { clrscr(); char *s; FILE *f; f=fopen("chuoi.inp","rt"); while (!feof(f)) { fgets(s,80,f);

Bài tập lập trình căn bản – SGU2010 puts(s); } fclose(f); getch(); }

Trang 130

Dạng 5:File nhị phân chứa các số nguyên Hàm putw: ghi một số nguyên int putw(int n, FILE *filepointe); Trong đó: n là giá trị nguyên Công dụng: Ghi giá trị n lên file filepointe, nếu thành công hàm trả về số nguyên được ghi, khi có lỗi hàm trả về EOF. Hàm getw: đọc một số nguyên int getw(FILE *filepointe); Công dụng: đọc một số nguyên từ file filepointe, nếu thành công hàm trả về số nguyên đọc được, khi có lỗi hoặc gặp cuối file hàm trả về EOF. Ví dụ 12-7.Sử dụng hàm putw để ghi 100 số nguyên từ 1 đến 100 lên file songuyen.inp và sau đó sử dụng hàm getw để đọc file songuyen.inp và in các số nguyên đó lên màn hình. Chương trình 12-7 #include <stdio.h> void main() { FILE *f; f=fopen("songuyen.inp","wb"); for (int i=1;i<=100;i++) putw(i,f); fclose(f); f=fopen("songuyen.inp","rb"); while ((i=getw(f))!=EOF) printf("%4d",i) ; }

Bài tập lập trình căn bản – SGU2010

Trang 131

Dạng 6:File nhị phân với dữ liệu có cấu trúc Hàm fwrite ghi các mẫu tin lên file int fwrite(void *ptr, int size, int n, FILE *filepointer); Trong đó: ptr là con trỏ trỏ tới vùng nhớ chứa dữ liệu cần ghi, size là kích thước của mẫu tin theo byte, n là số mẫu tin cần ghi, filepointer là con trỏ file/ Công dụng : Ghi n mẫu tin kích thước size byte từ vùng nhớ ptr lên file filepointer. Hàm trả về một giá trị bằng số mẫu tin thực sự ghi được. Hàm fread : đọc các mẫu tin từ file int fwrite(void *ptr, int size, int n, FILE *filepointer); Trong đó: ptr là con trỏ trỏ tới vùng nhớ chứa dữ liệu đọc được, size là kích thước của mẫu tin theo byte, n là số mẫu tin cần đọc, filepointer là con trỏ file Công dụng : Đọc n mẫu tin kích thước size byte từ file filepointer vào vùng nhớ ptr. Hàm trả về một giá trị bằng số mẫu tin thực sự đọc được. Các hàm fwrite, fread thường được sử dụng để đọc và ghi các đối tượng dữ liệu có cùng độ lớn như cấu trúc, số thực. Ví dụ 12-8.Tạo một file chứa n phân số (có tứ số và mẫu số là các số nguyên), sau đó đọc các phân số và xuất lên màn hình. Chương trình 12-8 #include <stdio.h> #include <iostream.h> #include <stdlib.h> #include <conio.h> struct phanso

Bài tập lập trình căn bản – SGU2010 { int tuso; int mauso; }; phanso ps; void main() { clrscr(); FILE *f; f=fopen("phanso.inp","wb"); int n; cin>>n; for (int i=1;i<=n;i++) { cin>>ps.tuso>>ps.mauso; fwrite(&ps,sizeof(ps),1,f); } fclose(f); f=fopen("phanso.inp","rb"); while (fread(&ps,sizeof(ps),1,f)) printf("\n%d/%d",ps.tuso,ps.mauso); fclose(f); }

Trang 132

C.BÀI TẬP BT12-1.a.Cho một file chứa các ký tự; mỗi ký tự cách nhau đúng một khoảng trắng. Hãy tạo ra file chứa mã ASCII của từng ký tự đó, mỗi dòng ghi 10 số. b.Cho file chứa n chuỗi, mỗi chuỗi trên một dòng. Hãy tạo file chứa các dòng (chuỗi) chứa 2 từ “Sai Gon”. c.Cho file chứa n số thực <1000. Mỗi số thực có đúng 2 số ở phần thập phân. Hãy đưa vào file khác các số thực là số chính phương. d..Số chính phương

Bài tập lập trình căn bản – SGU2010

Trang 133

Viết chương trình tạo một file văn bản có tên là “SONGUYEN.INP” chứa 10000 số nguyên ngẫu nhiên trong khoảng từ 1 đến 32767, mỗi dòng ghi 10 số. Hãy lưu các số chính phương trong file “SONGUYEN.INP” vào file văn bản “SONGUYEN.OUT”. e.Cho một file chứa các ký tự, mỗi ký tự cách nhau ít nhất một khoảng trắng. Hãy cho biết tần số xuất hiện của các ký tự. BT12-2.Dãy số Viết chương trình tạo một file văn bản có tên là “DAYSO.INP” có cấu trúc như sau: -Dòng đầu tiên ghi n (n là số nguyên dương nhập từ bàn phím). -Trong các dòng tiếp theo ghi n số nguyên ngẫu nhiên trong phạm vi từ 0 đến 100, mỗi dòng 10 số (các số cách nhau ít nhất một dấu cách). Hãy đọc/lưu dữ liệu của file “DAYSO.INP” vào mảng một chiều a và thực hiện các công việc sau đây: a.Tìm giá trị lớn lớn nhất của mảng A. b.Đếm số lượng số chẵn, số lượng số lẻ của mảng A. c.Hãy sắp xếp sao cho các số nguyên tố trong mảng tăng dần, các số khác giữ nguyên giá trị và vị trí. Hãy ghi các kết quả trên vào file văn bản có tên là “DAYSO.OUT” theo mẫu sau:

DAYSO.INP 18 87 39 78 19 89 4 40 98 29 65 20 43 1 99 38 34 58 4

DAYSO.OUT Cau a: 99 cau b: 9 9 câu c: 87 39 78 19 29 4 40 98 43 65 20 89 1 99 38 34 58 4

BT12-3.Ma trận Viết chương trình tạo file văn bản có tên là “MATRAN.INP” có cấu trúc như sau: -Dòng đầu tiên ghi hai số m và n (m, n là các số nguyên dương nhập từ bàn phím)

Bài tập lập trình căn bản – SGU2010

Trang 134

-Trong m dòng tiếp theo mỗi dòng ghi n số nguyên ngẫu nhiên trong phạm vi từ 0 đến 50 (các số cách nhau ít nhất một dấu cách) Hãy đọc dữ liệu của file “MATRAN.INP” và lưu vào mảng hai chiều a Hãy thực hiện các công việc sau: a.Hãy cho biết các dòng có chứa số nguyên tố (các dòng được đánh số từ 0 đến m-1. b.Hãy tính tổng các phần tử trên mỗi dòng.. Hãy ghi các kết quả trên vào file văn bản có tên là “MATRAN.OUT” theo như mẫu trong ví dụ sau: MATRAN.INP MATRAN.OUT

6 6 40 16 33 24 12 1 44 24 23 49 5 24 33 20 17 25 33 19 0 48 45 48 41 32 10 24 36 19 19 24 30 4 24 26 27 36

Cau a: 1,2,3,4 Cau b: 126 169 147 214 132 147

BT12-4.Chuỗi đối xứng Một chuỗi được gọi là đối xứng nếu nó không ít hơn một ký tự và nếu ta đọc từ trái sang phải hay từ phải sang trái đều được kết quả giống nhau. Ví dụ:”A” ; “TET” ; “CAOOAC” là các chuỗi đối xứng. Viết chương trình nhập vào một chuỗi ký tự S, có chiều dài n (1 £ n £ 1000). Hãy cho biết chiều dài chuỗi con đối xứng dài nhất. Chuỗi con của S là chuỗi gồm một số ký tự liên tiếp nhau trong S có độ dài nhỏ hơn hoặc bằng n. Dữ liệu vào được cho trong tập tin văn bản CHUOI.INP gồm 2 dòng. -dòng đầu ghi số n -dòng sau ghi n ký tự liên tiếp gồm các chữ cái in hoa (A ® Z) Dữ liệu ra cần được ghi vào tập tin văn bản CHUOI.OUT gồm một số duy nhất là độ dài của chuỗi con đối xứng dài nhất. Ví dụ:

Bài tập lập trình căn bản – SGU2010 CHUOI.INP 18 IKACOBEGIGEBOCAHTM CHUOI.OUT 13 CHUOI.OUT 19

Trang 135

IKACOBEGIGEMHBEGIGE CHUOI.OUT 5

BT12-5. Tính tiền điện Theo quy định, phân biệt 3 loại điện trong thanh toán: Điện tiêu dùng (loại 1), điện sản xuất (loại 2) và điện kinh doanh (loại 3). Mỗi loại có một cách thanh toán riêng. Đối với loại điện tiêu dùng 50 KWh đầu tiên mỗi KWh tính với giá A1 đồng, từ KWh thứ 51 tới KWh thứ 150 được tính với giá B1, còn từ KWh thứ 151 trở đi mỗi KWh tính với giá C1 đồng. Đối với loại điện sản xuất 200 KWh đầu tiên mỗi KWh tính với giá A2 đồng, từ KWh thứ 201 tới KWh thứ 1000 được tính với giá B2 còn từ KWh thứ 1001 trở đi mỗi KWh tính với giá C2 đồng. Đối với loại điện kinh doanh 100 KWh đầu tiên mỗi KWh tính với giá A3 đồng, từ KWh thứ 101 tới KWh thứ 200 được tính với giá B3, còn từ KWh thứ 201 trở đi mỗi KWh tính với giá C3 đồng. Công ty Alpha có 3 đồng hồ điện tương ứng với 3 loại. Chỉ số của đồng hồ đầu tháng cuối tháng đối với loại 1 lần lượt là là X1 và Y1, loại 2 là X2 và Y2, loại 3 là X3 và Y3. Yêu cầu : Tính tổng số tiền T mà công ty phải trả trong tháng. Dữ liệu: vào từ file văn bản PAY.INP: - Dòng đầu ghi 6 số nguyên X1, Y1, X2, Y2, X3 và Y3 (0 ≤ X2 ≤ Y2 ≤ 107, 0 ≤ X3 ≤ Y3 ≤ 107, 0 ≤ X1 ≤ Y1 ≤ 107). - Dòng thứ hai ghi 9 số nguyên A1, B1, C1, A2, B2, C2, A3, B3 và C3 (0 ≤ A1,B1,C1, A2, B2, C2, A3, B3, C3 ≤ 1000). Các số trên một dòng được ghi cách nhau bởi ít nhất một dấu cách. Kết quả: Ghi ra file văn bản PAY.OUT số nguyên T. Ví dụ:

Bài tập lập trình căn bản – SGU2010

Trang 136

BT12-6.Meeting Chào mừng kỷ niệm 100 năm ngày thành lập trường, nhà trường tổ chức một cuộc họp mặt thân mật giữa các thế hệ cựu học sinh sinh viên để ôn lại truyền thống vẻ vang của nhà trường. Mỗi cựu học sinh sinh viên khi về dự lễ đều có thông báo với ban tổ chức về số hiệu khóa học của mình. Biết số lượng của các cựu học sinh sinh viên về tham dự và số hiệu khóa học của mỗi cựu học sinh sinh viên. Hãy lập trình để tìm ra các khóa học có số lượng cựu học sinh sinh viên về tham dự là đông nhất.(trong trường hợp có nhiều khóa học có cùng số lượng cựu học sinh sinh viên về tham dự là đồng nhất thì in hết số hiệu của các khóa học đó). Dữ liệu vào được nhập vào từ bàn phím. Trước hết nhập một số nguyên dương n (chỉ số lượng người tham dự buổi lễ), tiếp theo là nhập n số nguyên duơng, số thứ i theo thú tự đó chỉ số hiệu khóa học của cựu học sinh sinh viên thứ i. Kết quả xuất ra màn hình là các số hiệu khóa học có nhiều cựu học sinh sinh viên về tham dự nhất. Ví dụ: Dữ liệu nhập từ bàn phím Dữ liệu xuất ra màn hình n=10 1945 1967 1970 1945 1945 1960 1952 952 1952 1980 1952 1945 BT12-7.Dự trữ nước Ở 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 đổ

Bài tập lập trình căn bản – SGU2010

Trang 137

đầ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. Dữ liệu: vào từ file văn bản WATER.INP 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. Kết quả: ghi ra file văn bản WATER.OUT chứa một số là số lượng ít nhất các thùng nước tìm được. Ví du: WATER.INP 4 01 45 02 12 WATER.OUT 1

BT12-8.Sắp xếp Để quản lý nhân sự ở một tỉnh nọ có khoảng 1 triệu người, hãy sắp xếp tuổi của dân cư ở đây theo thứ tự từ nhỏ đến lớn. Biết rằng tuổi ở đây chỉ nằm trong khoảng từ 1 đến 100. Tuổi của dân cư được cho vào từ file AGE.INP viết liên tiếp nhau, cách nhau ít nhất một dấu cách hoặc một dấu xuống dòng. Kết quả đưa ra file AGE.OUT cấu trúc như file vào nhưng đã được sắp xếp.

Bài tập lập trình căn bản – SGU2010 Ví dụ: AGE.INP AGE.OUT 1 2 20 4 45 62 3 2 4 55 2 4 5 1 2 2 2 3 4 4 4 5 20 45 100 55 62 100 BT12-9.Squares

Trang 138

Cho lưới ô vuông n x n (n £ 100), các nút lưới là các số 0 hoặc 1. Người ta cần chọn ra các hình vuông có bốn đỉnh là các số 1. Các hình vuông này có thể có chung nhiều nhất là hai đỉnh. Yêu cầu: Đếm số lượng hình vuông có bốn đỉnh là các số 1. Dữ liệu vào được ghi trong tập tin SQUARES.INP có dòng đầu chứa số nguyên n (n £ 100). n dòng tiếp theo mô tả n dòng của lưới ô vuông gồm các kí tự 0,1. Dữ liệu ra cần được ghi vào tập tin SQUARES.OUT chứa số lượng hình vuông tìm được. Ví dụ: SQUARES.INP 10 0100111111 0111101001 1000001110 0010110100 1011101100 1011011000 1001010110 1000100100 1010110001 1000111111 SQUARES.OUT 16

BT12-10.Mật khẩu Một nhóm gồm k sinh viên góp tiền mua một phần mềm dùng chung. Khi cài đặt phần mềm này, người sử dụng cần phải nhập vào một mật khẩụ Khi biết khách hàng của mình là các sinh viên say mê tin học, chủ cửa hàng thay vì đưa

Bài tập lập trình căn bản – SGU2010

Trang 139

mật khẩu đã đưa cho mỗi bạn một con số và nói rằng: “Mật khẩu để cài đặt phần mềm là số nguyên dương nhỏ nhất gồm không quá tám chữ số chia hết cho bất cứ số nào trong các số tôi đã đưa cho các bạn”. Yêu cầu: Biết tất cả các số mà chủ cửa hàng đã đưa cho các học sinh, hãy tìm mật khẩu để cài đặt phần mềm. Dữ liệu vào từ file văn bản MATKHAU.INP: - Dòng đầu tiên chứa số học sinh k (k £ 100). - Dòng thứ hai chứa k số nguyên dương mà ông chủ cửa hàng đã đưa cho các học sinh, hai số liên tiếp cách nhau bởi dấu cách. Kết quả ghi ra file văn bản MATKHAU.OUT mật khẩu tìm được. Ví dụ: MATKHAU.INP 3 463 MATKHAU.OUT 12

Bài tập lập trình căn bản – SGU2010

Trang 140

Bài tập nâng cao
BT13-1.a.Đặt 8 quân hậu lên bàn cờ vua sao cho chúng không khống chế lẫn nhau. Tìm tất cả mọi lời giải. b.Bài toán con mã đi tuần. Cho bàn cờ kích thước 8 x 8.hãy di chuyển quân mã trên khắp bàn cờ sao cho mỗi ô chỉ đi qua đúng 1 lần. BT13-2.Cho n phần tử {1,2,…,n}. a.Tìm các hoán vị của n phần tử. b.Tìm các tổ hợp chặp k của n phần tử. c.Tìm các chỉnh hợp không lặp chặp k của n phần tử. BT13-3.Người Việt Nam vốn theo truyền thống lịch âm từ lâu đời, nên ngày nay tuy đã chính thức dùng dương lịch trong tất cả các hoạt động giao tiếp văn hoá, xã hội, chính trị. Nhưng việc muốn biết năm tháng dương lịch tương ứng với âm lịch vẫn còn là một thói quen trong tâm thức của phần đông xã hội. nhất là trong mỗi dịp xuân về, chúng ta thường hay nhắc tới tuổi của nhau là sinh năm Con gì ? Can gì ? Vậy phương pháp tính năm âm lịch như thế nào ? 1 2 3 4 5 6 7 8 9 10 11 12 13 Can Giáp ất Bính Đinh Mậu Kỷ Thìn Tỵ Canh Tân Nhâm Quý Ngọ Mùi Thân Dậu Tuất Hợi

Chi Tý Sửu Dần Mão

Trước hết, bạn phải nắm thật kĩ bảng Thiên can và Địa chi như sau: Cách tính: - Tìm Can: Lấy năm dương lịch muốn đổi trừ đi 3. Lấy số hàng đơn vị tìm được, tính Can theo bảng Thiên can. Nếu số hàng đơn vị là 0 thì ứng với Quý. Ví dụ: Tìm Can của năm 1954 1954-3=1951. Số hàng đơn vị là 1, tương ứng với can Giáp. - Tìm Chi: Lấy năm muốn đổi trừ đi 3, rồi chia cho 12. Lấy số dư tìm được tính cho Chi, theo bảng Địa chi, nếu số dư là 0 thì ứng với Hợi. Ví dụ: Tìm chi của năm 1954

Bài tập lập trình căn bản – SGU2010

Trang 141

1954-3=1951; 1951:12=162 dư 7. Số dư là 7 tương ứng với chi Ngọ. Vậy năm 1954 là năm Giáp Ngọ. Chương trình đặt ra ở đây là: Nhập vào năm dương lịch, hãy cho biết năm âm lịch tương ứng ? Ví dụ: - Năm 1010, Vua Lý Thái Tổ dời kinh đô từ Hoa Lư thành Đại La và đổi tên thành Thăng Long, tính theo năm âm lịch là năm Canh Tuất. - Năm 1901, mở đầu thế kỷ XX là năm Tân Sửu. - Năm 2000, kết thúc thế kỷ XX là năm Canh Thìn. - Năm 2010, thế kỷ XXI là năm. Canh Dần BT13-4.a.Cho một lưới hình chữ nhật m dòng n cột. Mỗi ô của lưới chứa một màu trong các màu: Xanh, đỏ ,tím, vàng, đen, trắng và mỗi màu ít nhất được dùng 2 lần. Hãy sắp xếp lại các ô của lưới sao cho trên mỗi dòng hoặc mỗi cột có ít nhất 2 ô cùng màu” b.Cho một lưới hình chữ nhật n dòng m cột. Trên mỗi ô của lưới có chứa một số nguyên không âm biểu diễn cho số khối vuông được đặt chồng lên nhau trên ô đó và các khối ô vuông đó tạo thành các cột. Ví dụ a[3,2]=4 cho biết tại dòng 3 cột 2 được đặt 4 khối vuông Người ta tiến hành sơn tất cả các mặt nhìn thấy được của các cột. Hãy tính tổng số đơn vị diện tích cần sơn” Dữ liệu vào được cho bởi tệp văn bản có tên là Mang7.INP có cấu trúc như sau: -Dòng đầu ghi 2 số n,m -Trong n dòng tiếp theo mỗi dòng ghi m số .các số trên mỗi dòng cách nhau một dấu cách. BT13-5.Super Market Để quản lý các mặt hàng của mình, siêu thị ABC đánh số các mặt hàng bởi một dãy các con số từ 0 đến 9 (gọi là mã số mặt hàng). Các mã hàng có độ dài là n. Hai mặt hàng có mã số X,Y được xem là cùng nhóm hàng nếu X và Y có cùng số lượng chữ số và vị trí các chữ số lặp là như nhau, ví dụ 2 mặt hàng có mã số

Bài tập lập trình căn bản – SGU2010

Trang 142

123435 và 416563 là cùng một nhóm hàng, 2 mặt hàng có mã số 12342, 56767 không cùng một nhóm hàng. Yêu cầu: nhập vào n là độ dài mã và 2 mã X,Y. 1. Hãy kiểm tra xem X,Y có cùng một nhóm hàng hay không? Xuất ra màn hình như sau: 1:nếu X,Y cùng nhóm hàng. 0:nếu X,Y khác nhóm hàng. 2. Hãy đưa ra số lượng mã hàng cùng nhóm hàng với X. Ví dụ: Test 1 n=4,X=1 2 3 2,Y = 1 2 3 4 Câu 1: 0 Câu 2: 720 Test 2 N=6, X=1 2 1 2 6 7, Y= 3 4 3 4 8 6 Câu 1: 1 Câu 2: 5040

BT13-6.Tìm ảnh đặc trưng Một nhóm nghiên cứu xử lý ảnh của trường ĐH Khoa học tự nhiên, ĐHQG Tp.HCM đang giải quyết bài toán nhận dạng mặt người trong ảnh. Ảnh chụp mặt người sau khi đã xử lý là một bảng vuông A kích thước N x N (10 ≤ N ≤ 800) với mỗi ô (I,J) (1 ≤ I, J ≤ N) có giá trị từ 0 đến 255 là mức xám của ảnh tại ô này (trong đó 0 là màu nền). Để xác định vị trí có thể là mặt người, nhóm cần thống kê các đặc trưng có dạng hình vuông kích thước K x K (1 ≤ K ≤ 40) trong đó tất các các giá trị trong hình vuông đều phải khác 0. Yêu cầu : Từ một ảnh chụp mặt người, hãy giúp nhóm nghiên cứu đếm tất cả các đặc trưng có trong ảnh đó. Dữ liệu : Vào từ file văn bản FEATURE.INP trong đó : Dòng đầu chứa hai sô N và K Dòng thứ I trong N dòng tiếp theo chứa tương ứng dòng thứ I của bảng A. Các số ghi trên một dòng được ghi cách nhau bởi ít nhất một khoảng trắng. Mỗi dòng có N số nguyên. Dòng thứ I là các giá trị của N phần tử trong dòng thứ I-1 trong bảng vuông A Kết quả : Ghi ra file văn bản FEATURE.OUT số lượng đặc trưng tìm được. Ví dụ:

Bài tập lập trình căn bản – SGU2010 FEATURE.INP 62 0 12 15 0 33 30 17 19 23 15 16 0 11 12 0 14 14 0 0 10 11 8 10 0 0 8 7 12 0 0 0 0 11 13 0 0 FEATURE.OUT 7

Trang 143

BT13-7.CTIT Công ty CTIT cần tuyển sinh viên IT trường X về thực tập tại công ty của mình. Vì số lượng tuyển hạn chế nên công ty đưa ra 1 bài test như sau: trên tờ giấy A4 kẻ 1 lưới hình chữ nhật gồm m dòng và n cột, trên mỗi ô của lưới điền sẵn 1 số nguyên. Một hình vuông tăng là hình vuông 2x2 sao cho giá trị các ô trong hình vuông đó tăng dần theo chiều kim đồng hồ ([i][j]<[i][j+1]<[i+1][j+1]<[i+1][j]). Công ty sẽ tuyển một số ứng viên xác định đúng và nhanh nhất số lượng ô vuông như vậy trong lưới chữ nhật trên. Yêu cầu: Nhập m, n và mảng 2 chiều a từ bàn phím để biểu diễn lưới hình chữ nhật trên. Lập trình đưa ra số hình vuông tăng có trong mảng a. Ví dụ: m=3,n=4 1 5 1 Kết quả: 2. BT13-8.Đa giác Cho n đa giác lồi thoả các tính chất sau: +Với hai đa giác bất kỳ luôn có một đa giác mà mọi điểm của nó nằm trong đa giác kia. +Các cạnh của chúng không có điểm chung. 2 4 3 3 7 10 4 8 9

Bài tập lập trình căn bản – SGU2010

Trang 144

Bài toán đặt ra là: Với mỗi đa giác i, có bao nhiêu đa giác bao nó ? (đa giác i nằm trong bao nhiêu đa giác ?) Yêu cầu: Dữ liệu vào được ghi trong tập tin văn bản DAGIAC.INP Dòng đầu tiên ghi số tự nhiên n (3 £ n £ 1000) Trong n dòng tiếp theo: Dòng thứ i+1 ghi thông tin về đa giác có số hiệu thứ i. Bao gồm số đầu tiên Si là số đỉnh của đa giác (Si ≥ 3); Si cặp số nguyên tiếp theo lần lượt là hoành độ và tung độ các đỉnh của đa giác. Các số trên cùng dòng cách nhau bởi ít nhất một khoảng trắng. Dữ liệu ra cần được ghi trong tập tin văn bản DAGIAC.OUT gồm N dòng, trong đó dòng thứ i ghi số lượng đa giác bao đa giác i. Ví dụ: DAGIAC.INP 4 4 4 4 3 1 9 3 8 1 3 2 4 15 1 15 8 1 8 9 6 4 6 4 3 11 2 11 7 3 7 8 5 6 5 DAGIAC.OUT 0 2 1 3

BT13-9.Cấp số cộng Dãy số a1, a2, ..., an được gọi là một cấp số cộng nếu tồn tại một số d không âm sao cho : ai=ai-1 + d với mọi i=2,3,...,n. Yêu cầu : Cho một dãy n số nguyên a1, a2,...,an. Hãy kiểm tra xem có thể sắp lại dãy để nhận được một cấp số cộng hay không? Dữ liệu : Vào từ file văn bản SERIES.INP bao gồm : · · Dòng đầu chứa số tự nhiên N (N£20 000) Dòng thứ i trong n dòng tiếp theo chứa số ai (-1 000 000£ai£1

000 000) Kết quả : Đưa ra file văn bản SERIES.OUT một dòng duy nhất chứa duy nhất số -1 nếu dãy không thể sắp lại thành cấp số công. Trong trường hợp có thể sắp dãy thành một cấp số cộng : Dòng thứ i chứa số thứ i trong dãy đã sắp xếp.

Bài tập lập trình căn bản – SGU2010 Ví dụ : SERIES .INP 7 10 30 20 50 70 60 40 SERIES.OUT 10 20 30 40 50 60 70

Trang 145

BT13-10.Nhận dạng ảnh Cho sơ đồ ảnh là một mảng hai chiều m hàng n cột chứa các số 1(bít có ảnh), số 0(bít không có ảnh). Ảnh là các số 1 liên tiếp nhau trong sơ đồ. Hãy nhận dạng chữ T kích thước 3 x 3 trong sơ đồ ảnh biết rằng ảnh chữ T có trong 4 dạng sau: 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1

Bài tập lập trình căn bản – SGU2010

Trang 146

Một số đề thi mẫu
MÔN: CƠ SỞ LẬP TRÌNH (ĐỀ SỐ 1) Thời gian làm bài: 90 phút, không kể thời gian phát đề Câu I (3 điểm) Viết chương trình nhập vào một số nguyên dương n (0 < n < 1000000000). Hãy tính tổng các chữ số của số đó. Câu II (3 điểm) Viết chương trình nhập vào một chuỗi ký tự s. 1.Hãy cho biết từ dài nhất trong chuỗi có bao nhiêu ký tự. 2.Hãy cho biết tần số xuất hiện của các ký tự trong chuỗi. Câu III (4 điểm) Viết chương trình nhập vào một số nguyên dương n và một dãy n số nguyên dương.Hãy thực hiện các yêu cầu sau đây: 1.Tìm giá trị nhỏ nhất của dãy. 2.Số hoàn thiện là số bằng tổng các ước số thực sự của nó (chẳng hạn 6 là số hoàn thiện vì 6 = 1 + 2 + 3). Hãy đếm xem trong dãy có bao nhiêu số hoàn thiện ? 3.Tìm số nguyên dương lớn nhất là ước số của tất cả các số của dãy. --------------------------------------------------Hết-----------------------------------------

Bài tập lập trình căn bản – SGU2010

Trang 147

MÔN: CƠ SỞ LẬP TRÌNH (ĐỀ SỐ 2) Thời gian làm bài: 90 phút, không kể thời gian phát đề CÂU I (3 điểm) Cài đặt hàm kiểm tra tính chất sắp thứ tự của một mảng một chiều gồm n số nguyên với kết quả trả về là: -1: mảng có thứ tự giảm nghiêm ngặt . 1: mảng có thứ tự tăng nghiêm ngặt. 0: mảng không có thứ tự tăng mà cũng không có thứ tự giảm nghiêm ngặt. CÂU II (3 điểm) Với mỗi n ³ 1, số Yn được định nghĩa như sau : Y1= 1, Y2 = 2, Y3 = 3. Yn = Yn-1 + 2Yn-2 + 3Yn-3 với mọi n ³ 4 1.Tính Y5. 2.Viết hàm tính Yn bằng phương pháp đệ quy. 3.Viết hàm tính Yn không dùng đệ quy cũng không dùng biến mảng để lưu giá trị tạm. CÂU III (4 điểm) Ngày hiện tại được lưu vào ba biến nguyên: dd/mm/yy. Giả sử các giá trị này là đã hợp lệ - không cần kiểm tra. Hãy viết hàm xác định ngày mai (tức là ngày kề sau của ngày dd/mm/yy) --------------------------------------------------Hết-----------------------------------------

Bài tập lập trình căn bản – SGU2010

Trang 148

MÔN: CƠ SỞ LẬP TRÌNH (ĐỀ SỐ 3) Thời gian làm bài: 90 phút, không kể thời gian phát đề CÂU I (3 điểm)

x2 x3 xn + + ... + Tính tổng S ( x, n ) = x + 1+ 2 1+ 2 + 3 1 + 2 + 3 + ... + n
CÂU II (3 điểm) Cho mảng một chiều chứa n số nguyên a0, a1, a2,…,an-1. 1.Hãy viết hàm tìm vị trí của số chẵn nhỏ nhất của mảng. Nếu không tìm thấy thì trả về giá trị -1. 2.Tìm số hạng có giá trị lớn thứ k của mảng. CÂU III (4 điểm) Viết chương trình nhập vào một chuỗi S bao gồm các chũ cái thường từ a đến z và ký tự khoảng trắng (tạo thành các từ). Hãy thực hiện các công việc sau: 1.Đếm xem trong chuỗi có bao nhiêu nguyên âm a i o u e ? Bao nhiêu phụ âm ? 2.Xuất bảng mã ASCII của từng ký tự trong chuỗi (ví dụ ký tự A tương ứng với số 65). --------------------------------------------------Hết-----------------------------------------

Bài tập lập trình căn bản – SGU2010

Trang 149

MÔN: CƠ SỞ LẬP TRÌNH (ĐỀ SỐ 4) Thời gian làm bài: 90 phút, không kể thời gian phát đề CÂU I (3 điểm) Giả sử n ³1 và x là số thực. Hãy viết hàm tính giá trị của biểu thức sau đây :
S ( x, n ) = - x + x2 x3 xn + ... + (-1) n 1+ 2 1+ 2 + 3 1 + 2 + 3 + ... + n

CÂU II (3 điểm) Cài đặt hàm tính khoảng cách giữa hai ngày trong cùng một năm. CÂU III (4 điểm) Viết chương trình nhập vào từ bàn phím ma trận 2 chiều có m dòng, n cột các phân số (0 < m,n < 6) và thực hiện các công việc sau: 1.Xuất phân số lớn nhất trong số các phân số có giá trị nhỏ hơn 1 của mảng. 2.Sắp thứ tự ma trận sao cho trên mỗi dòng các phân số được sắp tăng dần từ trái qua phải và trên mỗi cột các phân số được sắp tăng dần từ trên xuống dưới. --------------------------------------------------Hết-----------------------------------------

Bài tập lập trình căn bản – SGU2010

Trang 150

MÔN: CƠ SỞ LẬP TRÌNH (ĐỀ SỐ 5) Thời gian làm bài: 90 phút, không kể thời gian phát đề CÂU I (3 điểm) Cho dãy n số nguyên dương a1, a2,..., an. Hãy viết hàm tìm chiều dài của đoạn con liên tiếp dài nhất chứa toàn số nguyên tố. Nếu không có thì trả về giá trị 0. CÂU II (3 điểm) Cho một dãy số được định nghĩa theo công thức quy nạp như sau (n là số nguyên, n≥1): f (1) = 1; f (2) = 2; f (3) = 3.

f ( n + 3) = 2 f ( n + 2) + f ( n + 1) - 3 f ( n )
1.Tính f(9). 2.Hãy viết hàm tính f(n) bằng phương pháp đệ quy. CÂU III(4 điểm) Cho mảng một chiều gồm n tọa độ điểm, tọa độ điểm là các số nguyên. 1.Hãy tìm một điểm trong mảng xa gốc tọa độ nhất. 2.Hãy tìm tọa độ hai điểm gần nhau nhất. Ví dụ n = 5 và tọa độ 5 điểm là: (0,0); (0,3); (3,3); (4,1); (4,4). Thì kết quả câu a là điểm (4,4) và kết quả câu b là (3,3) và (4,4) --------------------------------------------------Hết-----------------------------------------

Bài tập lập trình căn bản – SGU2010

Trang 151

MÔN: CƠ SỞ LẬP TRÌNH (ĐỀ SỐ 6) Thời gian làm bài: 90 phút, không kể thời gian phát đề CÂU I (3 điểm) Tìm các số nhỏ hơn 100000 sao cho các chữ số của nó là đối xứng nhau. CÂU II (3 điểm) Trong mặt phẳng tọa độ Oxy cho hai hình chữ nhật có cạnh song song với các trục tọa độ, hình chữ nhật thứ nhất có tọa độ gốc dưới trái là (x1,y1) và tọa độ gốc trên phải là (x2,y2). Hình chữ nhật thứ hai có tọa độ gốc dưới trái là (x3,y3) và tọa độ gốc trên phải là (x4,y4). Hãy tìm diên tích giao nhau giữa hai hinh chữ nhật trên? CÂU III (4 điểm) Cho mảng một chiều gồm n phần tử là các số nguyên dương. 1.Tìm số nguyên tố nhỏ nhất lớn hơn tất cả các giá trị có trong dãy. 2.Tìm số chính phuơng lẻ lớn nhất. 3.Tìm giá trị nguyên tố nhỏ nhất có 3 chữ số; nếu không có thì trả về giá trị 0. --------------------------------------------------Hết-----------------------------------------

Bài tập lập trình căn bản – SGU2010

Trang 152

MÔN: CƠ SỞ LẬP TRÌNH (ĐỀ SỐ 7) Thời gian làm bài: 90 phút, không kể thời gian phát đề CÂU I (3 điểm) Viết chương trình nhập một thông tin ngày (ngày/tháng/năm) - là các số nguyên dương). Hãy cho biết ngày đó là ngày thứ bao nhiêu trong năm ? Ví dụ: Ngày 3/2/2009 là ngày thứ 34 trong năm. CÂU II (3 điểm) Cho mảng một chiều gồm n phân số, trong đó tử số và mẫu số là các số nguyên. 1.Hãy tìm phân số có giá trị lớn nhất 2.Hãy sắp xếp các phân số theo chiều tăng dần. CÂU III (4 điểm) Cho ma trận vuông gồm n dòng, n cột; các phần tử là các số thực. Hãy viết các hàm thực hiện các công việc sau đây: 1.Tìm giá trị lớn nhất của ma trận. 2.Tính tổng các phần tử nằm trên đường chéo phụ. 3.Kiểm tra xem các phần tử nằm trên đuờng chéo chính có tăng dần hay không ? (tăng dần theo chiều từ góc trên bên trái xuống góc dưới bên phải). --------------------------------------------------Hết-----------------------------------------

Bài tập lập trình căn bản – SGU2010

Trang 153

MÔN: CƠ SỞ LẬP TRÌNH (ĐỀ SỐ 8) Thời gian làm bài: 90 phút, không kể thời gian phát đề CÂU I (3 điểm) Cho mảng một chiều a chứa n số nguyên và một số nguyên x. Hãy tìm một giá trị trong mảng xa x nhất. CÂU II (3 điểm) Cho một ma trận vuông n dòng n cột chứa các giá trị 0 hoặc 1. 1.Hãy viết hàm đếm số lượng giá trị 1 trên mỗi dòng. 2.Hãy viết hàm kiểm tra ma trận có đối xứng nhau qua đường chéo chính hay không? CÂU III (4 điểm) Với mỗi n ³ 1, số Yn được định nghĩa như sau : Y1= 1, Y2 = 2, Y3 = 3. Yn = Yn-1 + 2Yn-2 + 3Yn-3 với mọi n ³ 4 1.Tính Y7. 2.Hãy viết hàm tính Yn bằng phương pháp đệ quy. --------------------------------------------------Hết-----------------------------------------

Bài tập lập trình căn bản – SGU2010

Trang 154

MÔN: CƠ SỞ LẬP TRÌNH (ĐỀ SỐ 9) Thời gian làm bài: 90 phút, không kể thời gian phát đề CÂU I(3 điểm) Viết hàm tính A(m,n) biết:

ìn + 1, khi m = 0 ï A( m, n) = í A(m - 1,1), khi n = 0 ï A(m - 1, A( m, n - 1)) î
CÂU II (3 điểm) Cho chuỗi s gồm các từ, mỗi từ cách nhau đúng một khoảng trắng (giả sử đầu và cuối chuỗi không có khoảng trắng nào dư thừa). Hãy viết hàm đếm xem chuỗi s có bao nhiêu từ bắt đầu bằng ký tự nguyên âm ? (các ký tự a, u, i, o, e là các nguyên âm). Test 1 S=”ngay xua hoang thi” Output: 0 Output: 2 Test 2 S=”ao anh sut chi duong ta”

CÂU III (4 điểm) Cho mảng một chiều chứa n số nguyên dương a0, a1, a2,…,an-1. Hãy viết hàm kiểm tra trong mảng có chứa số chính phương nào có đúng ba chữ số không ? Nếu có thì trả về giá trị 1, nếu không có thì trả về giá trị 0. --------------------------------------------------Hết-----------------------------------------

Bài tập lập trình căn bản – SGU2010

Trang 155

MÔN: CƠ SỞ LẬP TRÌNH (ĐỀ SỐ 10) Thời gian làm bài: 90 phút, không kể thời gian phát đề CÂU I (3 điểm) Giả sử n ³1. Hãy viết hàm tính giá trị của biểu thức sau đây :
S ( n) = 1 + 1 1 1 + + 1 + 2 1 + 2 + 3 1 + 2 + 3 + ... + n

CÂU II (3 điểm) Cho mảng một chiều a các số nguyên có n phần tử (n <10000). Viết các hàm thực hiện các thao tác sau: 1.Kiểm tra xem mảng có chứa số nguyên lẻ là bội của cả 3 số 3, 5, 7 nào không ? 2.Hãy cho biết có bao nhiêu giá trị phân biệt trong mảng a ? CÂU III (4 điểm) Cho trước ma trận a các số nguyên có m dòng và n cột (0 < m,n < 150). Viết hàm thực hiện các thao tác sau: 1.In ra chỉ số các dòng có các phần tử được sắp tăng dần. 2.Tìm phần tử âm có giá trị lớn nhất. --------------------------------------------------Hết-----------------------------------------

Bài tập lập trình căn bản – SGU2010

Trang 156

MÔN: CƠ SỞ LẬP TRÌNH (ĐỀ SỐ 11) Thời gian làm bài: 90 phút, không kể thời gian phát đề CÂU I (3 điểm) Tính tổng S =

2 2+4 2+4+6 2 + 4 + 6 + ... + 2n + + + ... + với n > 0 3 3+5 3+5+7 3 + 5 + ... + ( 2 n + 1)

Ví dụ : Nếu n = 1 thì kết quả S=0.67 Nếu n = 3 thì kết quả S=2.22 CÂU II (3 điểm) Cài đặt hàm tìm chỉ số của phần tử duơng nhỏ nhất trong mảng một chiều a các số nguyên kích thước n (nếu mảng không có số dương trả về -1) CÂU III (4 điểm) Cho ma trận 2 chiều M x N phần tử (M<100, N<100), các phần tử là các số nguyên dương (dòng và cột bắt đầu bằng 0). 1.Tìm phần tử nguyên tố lớn nhất. 2.Nhập vào một số nguyên y, hãy cho biết các dòng có tổng dòng nhỏ hơn y. 3.Sắp xếp ma trận lại theo quy tắc sau: cột có chỉ số lẻ giảm dần và cột có chỉ số chẵn tăng dần. --------------------------------------------------Hết-----------------------------------------

Bài tập lập trình căn bản – SGU2010

Trang 157

MÔN: CƠ SỞ LẬP TRÌNH (ĐỀ SỐ 12) Thời gian làm bài: 90 phút, không kể thời gian phát đề CÂU I (3 điểm) Viết chương trình nhập chuỗi ký tự S. Hãy thực hiện các thao tác sau: 1.Đổi tất cả các ký tự đầu mỗi từ trong S (các từ phân biệt bằng khoảng trắng) thành ký tự hoa. 2.In số lượng ký tự của mỗi từ trong chuỗi. Câu Ii (3 điểm) Cho mảng vuông n dòng, n cột ; các phần tử là các số 0 hoặc 1. Hãy tìm hình chữ nhật lớn nhất chứa toàn giá trị 1. CÂU IiI (4 điểm) 1.Đếm số lượng các giá trị phân biệt trong mảng một chiều a các số nguyên kích thước n. 2.Biến đổi từng phần tử của mảng thành số chính phương nhỏ nhất lớn hơn hoặc bằng nó. --------------------------------------------------Hết-----------------------------------------

Bài tập lập trình căn bản – SGU2010

Trang 158

MÔN: CƠ SỞ LẬP TRÌNH (ĐỀ SỐ 13) Thời gian làm bài: 90 phút, không kể thời gian phát đề CÂU I (2điểm) Cho tổng S=1+3+5+...+(2n+1) với n≥0 và số nguyên M. Hãy tìm giá trị n nhỏ nhất sao cho S >M. Ví dụ M=20 thì n = 4 CÂU II (3 điểm) Cho f(0)=0;f(1)=1;f(2)=1; và f(n)=3*(n-3)+ 2*f(n-2) +f(n-1) với mọi n>2. 1.Hãy tính f(7) 2.Hãy viết hàm tính f(n). 3.Viết hàm tính f(n) không dùng đệ quy cũng không dùng biến mảng để lưu giá trị tạm. Câu III (5 điểm) Cho mảng gồm n số nguyên dương. Hãy thực hiện các yêu cầu sau: 1.Kiểm tra xem trong mảng có tồn tại số chính phương nào hay không ? Nếu có trả về giá trị 1, nếu không có trả về giá trị 0. 2.Tìm k giá trị khác nhau lớn nhất của mảng. 3.Hãy tìm hạng của các phần tử. --------------------------------------------------Hết-----------------------------------------

Bài tập lập trình căn bản – SGU2010

Trang 159

MÔN: CƠ SỞ LẬP TRÌNH (ĐỀ SỐ 14) Thời gian làm bài: 90 phút, không kể thời gian phát đề CÂU I (3 điểm) Nhập vào số nguyên n. Hãy tìm số nguyên tố gần nó nhất. Ví dụ : Nếu n=25 thì kết quả là 23, nếu n=37 thì kết quả là 41. CÂU II (3 điểm) Cho hai hình chữ nhật. Hình chữ nhật thứ nhất có tọa độ góc dưới trái là x1,y1 và tọa độ góc trên phải là x2,y2. Hình chữ nhật thứ hai có tọa độ góc dưới trái là x3,y3 và tọa độ góc trên phải là x4,y4. Giả thiết các tọa độ là các số nguyên và các hình chứ nhật có các cạnh song song với các trục tọa độ. Hãy tìm diện tích hình được phủ bởi hai hình chữ nhật trên. Câu III (4 điểm) Cho mảng vuông n dòng, n cột. Các phần tử là các số nguyên dương. 1.Tìm giá trị lớn nhất trên từng dòng 2.Hãy sắp sao cho các số lớn nhất nằm trên đường chéo chính 3.Hãy sắp xếp các số nguyên tố tăng dần trên từng dòng còn các số khác giữ nguyên giá trị và vị trí. --------------------------------------------------Hết-----------------------------------------

Bài tập lập trình căn bản – SGU2010 MÔN: CƠ SỞ LẬP TRÌNH (ĐỀ SỐ 15) Thời gian làm bài: 90 phút, không kể thời gian phát đề

Trang 160

CÂU I (3 điểm) Một số nguyên có k chữ số được gọi là số Amstrong khi nó bẳng tổng lũy thừa k của từng chữ số. Hãy viết ham in ra các số Amstrong nhỏ hơn 10000. Ví dụ: 153=13+53+33 Câu II (3 điểm) Ngày 01/01/2010 là ngày thứ Sáu. Hãy viết hàm in ra các ngày thứ Sáu cuối cùng của mỗi tháng trong năm 2010. Ví dụ: 29/1/2010 26/2/2010 26/3/2010 ... 31/12/2010 CÂU III (4 điểm) 1.Hãy viết hàm đếm số các đoạn con liên tiếp tăng của mảng một chiều a chứa n phần tử. Ví dụ: n = 9 4 7 7 2 21 34 56 7 9 Thì kết quả là 3 2.Hãy viết hàm tìm chiều dài dãy con liên tiếp tăng dài nhất của mảng một chiều a chứa n phần tử. Ví dụ: n = 9 4 7 7 2 21 34 56 7 9 Thì kết quả là 4 --------------------------------------------------Hết-----------------------------------------

Bài tập lập trình căn bản – SGU2010 MÔN: CƠ SỞ LẬP TRÌNH (ĐỀ SỐ 16) Thời gian làm bài: 90 phút, không kể thời gian phát đề

Trang 161

CÂU I (3 điểm) Giả sử n≥1 và x là số thực. Hãy viết hàm tính giá trị của biểu thức sau đây:
n x x 2 x3 n x + - ... + ( -1) 1! 2! 3! n! CÂU II(3 điểm) Cho chuỗi s gồm các từ, mỗi từ cách nhau đúng một khoảng trắng (giả sử đầu và cuối chuỗi không có khoảng trắng nào dư thừa). Từ có k ký tự gọi là từ loại k; k có thể là 1,2,3,4,5,6,7. Hãy tìm từ loại xuất hiện nhiều lần nhất. Ví dụ chuỗi s là ”Thanh Pho Ho Chi Minh Gia Dinh” thì kết quả là từ loại 3. CÂU III (4 điểm)

Cho ma trận vuông a các số nguyên dương kích thước n (1 ≤ n ≤ 8). Mỗi vị trí (i,j) của mảng lưu trữ 4 số nguyên có một chữ số. Các dòng, cột được đánh số từ 1 đến n. Khi nhập liệu thì nhập theo từng 4 số cho mỗi phần tử a[i][j] ví dụ như bảng dưới đây (bảng bên trái) thì các số lần lượt được nhập vào là 1,2,3,4. 1.Tìm ma trận b có cùng kích thước với ma trận a biết b[i][j] tổng của 4 phần tử tại ví trị i,j của mảng a. 2.Tìm một vị trí (i,j) của mảng a chứa cả 4 giá trị chẵn và có tổng của 4 giá trị này là lớn nhất. Nếu không tìm thấy trả về giá trị 0.

Ví dụ: n=4 1 2 3 2 4 3 1 2 1 4 4 3 4 3 3 2 3 4 9 4 2 3 5 6 5 5 1 5 4 7 7 8 7 4 4 8 6 7 2 4

4 4 6 8 5 6 2 2

2 9 8 8 1 1 7 8

3 3 8 7 2 2 9 8 20 25 10 32 10 25 24 6 9 14 26 31 10 10 16 17

(Ghi chú: Với dữ liệu ở bảng bên trái thì kết quả câu a là dữ liệu bảng bên phải và kết quả câu b là vị trí (2,3)).

--------------------------------------------------Hết-----------------------------------------

Bài tập lập trình căn bản – SGU2010

Trang 162

MÔN: CƠ SỞ LẬP TRÌNH (ĐỀ SỐ 17) Thời gian làm bài: 90 phút, không kể thời gian phát đề CÂU I (3 điểm) Ngày hiện tại được lưu vào ba biến nguyên: dd/mm/yy. Giả sử các giá trị này là đã hợp lệ - không cần kiểm tra. Hãy viết hàm xác định ngày hôm qua (tức là ngày kề trước của ngày dd/mm/yy) CÂU II (3 điểm) Với mỗi n ³ 1, số Yn được định nghĩa như sau : Y1= 1, Y2 = 2, Y3 = 3. Yn = Yn-1 (5Yn-2 + 6Yn-3) với mọi n ³ 4 1.Tính Y5. 2.Viết hàm tính Yn bằng phương pháp đệ quy. 3.Viết hàm tính Yn không dùng đệ quy cũng không dùng biến mảng để lưu giá trị tạm. CÂU III (4 điểm) Cho một mảng 2 chiều A các số nguyên kích thước n x n (2<n<100). Hãy viết hàm thực hiện việc tạo ra mảng B có cùng thước từ mảng A đã cho theo công thức sau: B[i][j]=Trung bình cộng của 8 phần tử kề với A[i][j] trong mảng A nếu 0<i,j<n-1. B[i][j]= A[i][j] trong các trường hợp còn lại. --------------------------------------------------Hết-----------------------------------------

Bài tập lập trình căn bản – SGU2010

Trang 163

MÔN: CƠ SỞ LẬP TRÌNH (ĐỀ SỐ 18) Thời gian làm bài: 90 phút, không kể thời gian phát đề CÂU I (3 điểm) Tìm các bộ ba số tự nhiên x,y,z thỏa 1£ x,y,z £ 10000 và thỏa mãn x2 + y2 = z2. CÂU II (3 điểm) Cho hai 2 ma trận vuông A,B cấp n. Hãy thực hiện các công việc sau: 1.Tính tổng của hai ma trận trên. 2.Tính tích của hai ma trận trên. 3,Tạo ma trận mới bằng cách nhân các phần tử của mỗi dòng của ma trận A với giá trị lớn nhất của dòng tương ứng của ma trận B CÂU III (4 điểm) Với mỗi hóan vị A(a1,a2,a3,…aN) của N số tự nhiên đầu tiên, ta ký hiệu b=(b1,b2,…,bN) là một mảng mà bi bằng số các phần tử đứng trước số i và lớn hớn i (1<= i <=n). Mảng B được gọi là mảng nghịch thế của mảng A. Ví dụ : Nếu A là một hóan vị của 9 số tự nhiên đầu tiên 5 9 1 8 2 6 4 7 3 Thì mảng nghịch thế sẽ là: 236402210 Viết chương trình cho một hóan vị tìm nghịch thế tương ứng --------------------------------------------------Hết-----------------------------------------

Bài tập lập trình căn bản – SGU2010

Trang 164

MÔN: CƠ SỞ LẬP TRÌNH (ĐỀ SỐ 19) Thời gian làm bài: 90 phút, không kể thời gian phát đề CÂU I (3 điểm) Viết các hàm thực các công việc sau: 1.Tìm các số nguyên tố có 4 chữ số 2.Tìm 100 số nguyên tố đầu tiên lớn hơn 1000. CÂU II (3 điểm) Hãy kiểm tra xem ngày 1/1/1 (ngày đầu tiên sau công nguyên) là ngày thứ mấy? CÂU III (4 điểm) Với mỗi hóan vị A(a1,a2,a3,…aN) của N số tự nhiên đầu tiên, ta ký hiệu b=(b1,b2,…,bN) là một mảng mà bi bằng số các phần tử đứng trước số i và lớn hớn i (1<= i <=n). Mảng B được gọi là mảng nghịch thế của mảng A. Ví dụ : Nếu A là một hóan vị của 9 số tự nhiên đầu tiên 5 9 1 8 2 6 4 7 3 Thì mảng nghịch thế sẽ là: 236402210 Viết chương trình cho một nghịch thế tìm hóan vị tương ứng (nếu có) --------------------------------------------------Hết-----------------------------------------

Bài tập lập trình căn bản – SGU2010

Trang 165

MÔN: CƠ SỞ LẬP TRÌNH (ĐỀ SỐ 20) Thời gian làm bài: 90 phút, không kể thời gian phát đề CÂU I (3 điểm) Trong mặt phẳng tọa độ OXY cho 3 điểm A(xa;ya), B(xb;yb), C(xc;yc). 1.Hãy tìm tọa độ điểm D(xd,yd) để tứ giác ABDC là hình bình hành. 2.Tìm khoảng cách từ đỉnh A đến cạnh BD. Ví dụ: A(2 ;4), B(1 ;0), C(8 ;4) thì kết quả là D(7 ;0) và khoảng cách giữa hai đường thẳng AC và BD là 4. CÂU II (3 điểm) Giả sử A và B là 2 số nguyên cho trước và x,y,z là 3 số nguyên thỏa mãn đồng thời các bất phương trình: x2+2y2+3z2 ≤ A2 y2+z2 ≤ B2 Hãy viết hàm tìm giá trị lớn nhất của biểu thức F(x,y,z)=x2+y4+z8 CÂU III (4 điểm) Hãy viết các hàm thực hiện các công việc sau đây: 1.Xác định số lượng bit 1 của một số nguyên dương D (D<65000) trong biểu diễn nhị phân của nó. 2.Tính số phần tử mà giá trị của nó có số bít 1 (trong biểu diễn nhị phân của nó) là một số lẻ trong một mảng một chiều các số nguyên dương A gồm n phần tử (0<N<10000, A[i]<65000) --------------------------------------------------Hết-----------------------------------------

Bài tập lập trình căn bản – SGU2010

Trang 166

Gợi ý và hướng dẫn giải bài tập
Chương 1 BT1-1. Hiển nhiên là n không chia hết cho các số lớn hơn n/2, nên ta chỉ cần cho một biến i chạy từ 1 đến n/2. Nếu mỗi giá trị i như vậy mà là ước số của n thì cộng dồn i vào tổng s. Khi kết thúc vòng lặp, nếu s đúng bằng n thì nghĩa là s là số hoàn thiện, ngược lại n không phải là số hoàn thiện. s=0; for (int i=1;i<=n/2;i++) if (n % i ==0) s=s+i; if (s==n) cout<<”n la so hoan thien”; else cout<<”n la so hoan thien”; BT1-2. Có nhiều cách để kiểm tra n có phải là số nguyên tố hay không. Thuật toán 1: Dựa vào định nghĩa “n là số nguyên tố khi n có đúng hai ước số là 1 và chính nó”. Gọi d là số lượng các ước số của n tại thời điểm đang xét, lúc đầu d=0 ta có đoạn mã sau đây: d=0; for (int i=1;i<=n;i++) if (n % i==0) d++; if (d==2) cout<<”n la so nguyen to”; else cout<<”n khong la so nguyen to”;

Bài tập lập trình căn bản – SGU2010

Trang 167

Dễ thấy thuật toán 1 bộc lộ nhược điểm là khi đã phát hiện n có một ước số khác 2 và n (nghĩa là n không thể là số nguyên tố) nhưng thuật toán vẫn không dừng lại mà vẫn tiếp tục thực hiện vòng lặp đến khi i bằng n. Định lý sau đây cho ta một thuật toán khắc phục được nhược điểm trên. Thuật toán 2: Dựa vào định lý “n là số nguyên tố nếu n không có ước số nào trong khoảng từ 2 đến căn bậc hai của nó”. int flag=1; int m=int(sqrt(n));// m là phần nguyên của căn bậc hai của n for (int i=2;i<=m;i++) if (n %i==0) { flag=0; break; } if (flag) cout<<”n la so nguyen to”; else cout<<”n khong la so nguyen to”; Nếu sử dụng chương trình con để thiết kế cho thuật toán này thì chương trình sẽ dễ diễn đạt hơn, trong sáng hơn. Bạn đọc hãy sử dụng vòng lặp while để minh họa lại thuật toán này. BT1-4. Sủ dụng vòng lặp while cho biến i giảm từ n về 1; cứ mỗi giá trị của i như thế thì kiểm tra xem i có là số nguyên tố hay không ? Đến khi tìm được i là số nguyên tố thì dừng thuật toán. Trong trường hợp i giảm đến 1 (nghĩa là n nhập vào là 1) thì kết luận là không có số nguyên tố thỏa điều kiện. BT1-5. Tìm ước số chung lớn nhất của n số. int uc=a[0]; for (i=1;i<n;i++)

Bài tập lập trình căn bản – SGU2010

Trang 168

uc=uscln(uc,a[i]);// uscln(a,b) là hàm tìm ước số chung lớn nhất của a và b; hàm này đã được trình bày trong chương 1. Việc tìm bội số chung nhỏ nhất của n số là tương tự. BT1-6. Bài này nên sử dụng vòng lặp for để giải. Trước hết ta dễ dàng tìm được các cận cho các biến điều khiển vòng lặp for ứng với hệ phương trình trên. Sau đó chỉ cần sử dụng 2 vòng lặp for lồng nhau cho hai biến x,y là đủ (không phải là 3 vòng lặp); còn biến z sẽ được tính dựa vào 2 biến x,y như đoạn mã sau: for (int x=1;x<=20;x++) for (int y=1;y<=33;y++) { int z=100-x-y; if (5*x+3*y+z/3==100 && z%3==0) cout<<x<<" "<<y<<" "<<z<<endl; } BT1-7. Cũng như BT1-6, bài tập này ta quan tâm đến việc tối ưu hóa cấu trúc. Bài này sử dụng 3 vòng lặp for như sau đây là đủ (chứ không cần 5 vòng lặp for). for (int x=1;x<=9;x++) for (int y=0;y<=9;y++) for (int z=0;z<=9;z++) cout<<x<<y<<z<<y<<x<<endl; BT1-9. Điều kiện cần và đủ để M thuộc đoạn thẳng AB là MA + MB = AB. Lưu ý khi thực hiện phép so sánh bằng trên kiểu số thực thì cần chú ý là a=b khi và chi khi fabs(a-b)<=1.E-n, thường e được chọn là 6 (1.E-n bằng 1.0/10n), điều này có nghĩa là các số thực có trị tuyệt đối nhỏ hơn 1.E-n thì được xem như bằng 0 (với các bài toán hình học kiểu này nên sử dụng kiểu dữ liệu double thay cho kiểu dữ liệu float).

Bài tập lập trình căn bản – SGU2010

Trang 169

Chương 2 BT2-5. Sử dụng hàm random để tạo ra từng chữ số (nhắc lại random(n) sẽ trả về một số nguyên trong khoảng từ 0 đến n-1). #include <stdlib.h> #include <iostream.h> void main() { randomize(); unsigned int a1,a2,a3,a4,a5,a6; a1=random(9); a2=random(9); a3=random(9); a4=random(9); a5=random(9); a6=random(9); cout<<a1<<a2<<a3<<a4<<a5<<a6; } BT2-6 #include <stdio.h> #include <conio.h> void main() { clrscr(); int t; printf("Nhap vao so giay t = ");scanf("%d",&t); int h=t/3600; int m=(t%3600)/60; int s=(t%3600)%60; printf("Ket qua la: %dh %dm 3%ds",h,m,s); getch();

Bài tập lập trình căn bản – SGU2010 }

Trang 170

BT2-10.a. Nhắc lại khi tính sin, cos, tan theo góc alpha thì alpha được tính bằng radian. Khi tính tg(alpha) thì cần kiểm tra điều kiện cos(alpha) khác 0 và tương tự khi tính cotg thì cần kiểm tra sin(alpha) khác 0 (do C/C++ không có hàm tính cotg nên phải tính cotg dựa vào hàm tính tg). Còn việc kiểm tra số thực e khác 0 thì điều kiện tương đương là e<1.E-6 như đã đề cập trong bài tập BT110. #include<conio.h> #include<stdio.h> #include<math.h> void main() { clrscr(); int alpha; printf("Nhap vao so do goc alpha: ");scanf("%d",&alpha); double radian=M_PI*alpha/180; printf("\nsin(%d) =%6.2lf",alpha,sin(radian)); printf("\ncos(%d) =%6.2lf",alpha,cos(radian)); (cos(radian)>1.E-6)?printf("\ntg(%d) =%6.2lf",alpha,tan(radian)): printf("\ntg khong xac dinh"); (sin(radian)>1.E-6)?printf("\ncotg(%d)=%6.2lf",alpha,1/tan(radian)): printf("\ncotg khong xac dinh"); getch(); } b. Điểm M(x,y) lệch với phương ngang góc alpha thì x= r*cos(alpha) và y= r*cos(alpha) trong đó r là bán kính đường tròn ngoại tiếp tam giác điều. Do đây là tam giác điều nên đỉnh tiếp theo sẽ lệch so với đỉnh hiện một xgóc 2*M_PI/3. #include<conio.h>

Bài tập lập trình căn bản – SGU2010 #include<iostream.h> #include<math.h> void main() { int r; double alpha; cout<<"nhap toa do tam duong tron: "; cout<<"Ban kinh R = "; cin>>r; alpha=M_PI/2; int x1,y1,x2,y2,x3,y3; float phi=2*M_PI/3; x1=int(r*cos(alpha)+0.5); y1=int(r*sin(alpha)+0.5); alpha=alpha+phi; x2=int(r*cos(alpha)+0.5); y2=int(r*sin(alpha)+0.5); alpha=alpha+phi; x3=int(r*cos(alpha)+0.5); y3=int(r*sin(alpha)+0.5); cout<<x1<<";"<<y1; cout<<x2<<";"<<y2; cout<<x3<<";"<<y3; getch(); }

Trang 171

Bài tập lập trình căn bản – SGU2010 Chương 3 BT3-1. #include <stdio.h> #include <conio.h> #include <ctype.h> void main() { clrscr(); char ch; scanf("%c",&ch); if (islower(ch)) printf("%c",toupper(ch)); else if (isupper(ch)) printf("%c",tolower(ch)); else if (isdigit(ch)) printf("%d",toascii(ch)); else if (ch=='+' || ch=='-' || ch=='*' || ch=='/' ) printf("phep toan"); else if (ch==' ') printf("khoang trang"); else printf("khong phai thuoc cac truong hop tren"); getch(); } BT3-3. #include <conio.h> #include <iostream.h>

Trang 172

Bài tập lập trình căn bản – SGU2010 void main() { clrscr(); int a,b,c,d; cin>>a>>b>>c>>d; int max=a>b?a:b; int sln=a+b-max; if (c>max) { sln=max; max=c; } else if (c>sln) sln=c; if (d>max) { sln=max; max=d; } else if (d>sln) sln=d; cout<<"kq: "<<sln; getch(); }

Trang 173

BT3-5. Thuật toán Tìm giá trị lớn nhất và nhỏ nhất của 4 số này. Từ đó biết tổng hai số còn lại là a+b+c+d-max-min. Như vậy nếu được giá trị của một số trong 2 số ở giữa còn lại thì ta sẽ biết được giá trị số còn lại.

Bài tập lập trình căn bản – SGU2010

Trang 174

Gọi số nhỏ nhì là sonhonhi. Ta có sonhonhi là số khác giá trị min và lớn hơn trung bình cộng của 2 số giữa. #include <conio.h> #include <iostream.h> void main() { clrscr(); int a,b,c,d; cin>>a>>b>>c>>d; int max=a; if (b>max) max=b; if (c>max) max=c; if (d>max) max=d; int min=a; if (b<min) min=b; if (c<min) min=c; if (d<min) min=d; int tong2sogiua=a+b+c+d-max-min, sonhonhi; if (a <(tong2sogiua/2.0) && a!=min) sonhonhi=a; if (b <(tong2sogiua/2.0) && b!=min) sonhonhi=b; if (c <(tong2sogiua/2.0) && c!=min) sonhonhi=c; if (d <(tong2sogiua/2.0) && d!=min) sonhonhi=d; cout<<min<<" "<<sonhonhi<<" "<<tong2sogiua-sonhonhi<<" "<<max; getch(); } BT3-6.a. Việc tìm được số ngày của tháng, năm vừa hiện hành được thực hiện dễ dàng và gọi giá trị tìm được là songay. Việc tìm ngày/tháng/năm kế sau ngày hiện hành được thực hiện qua đoạn mã sau.

Bài tập lập trình căn bản – SGU2010 if (ngay<songay) ngay++; else { ngay=1; thang++; if (thang>12) { thang=1; nam++; } } #include <iostream.h> void main() { int ngay,thang,nam,songay;// so ngay cua thang cin>>ngay>>thang>>nam; //Cho biet so ngay cua 1 thang nao do trong nam switch (thang) { case 1: case 3: case 5: case 7: case 8: case 10: case 12:songay=31;break; case 4: case 6: case 9: case 11:songay=30;break;

Trang 175

Bài tập lập trình căn bản – SGU2010 case 2: if (nam %4==0 && nam %400!=0) songay=29; else songay=28; break; } //Tim ngay ke sau cua ngay/thang/nam if (ngay<songay) ngay++; else { ngay=1; thang++; if (thang>12) { thang=1; nam++; } } cout<<ngay<<" "<<thang<<" "<<nam; }

Trang 176

BT3-9. M nằm trong hình chữ nhật, thì M phải thỏa điều kiện x1<=x<=x2 và y1<=y<=y2

Bài tập lập trình căn bản – SGU2010 Chương 4 BT4-1. #include<conio.h> #include<iostream.h> #include<ctype.h> void main() { clrscr(); cout<<"Cac chu cai hoa"<<endl; for (char ch='A';ch<='Z';ch++) cout<<ch<<" "<<toascii(ch)<<endl; cout<<"Cac chu cai thuong"<<endl; for (ch='a';ch<='z';ch++) cout<<ch<<" "<<toascii(ch)<<endl; cout<<"Cac chu so"<<endl; for (ch='0';ch<='9';ch++) cout<<ch<<" "<<toascii(ch)<<endl; getch(); } BT4-2.a. #include<iostream.h> void main() { int n; float s=0; cin>>n; for (int i=0;i<=n;i++) s=s+1.0/(2*i+1); cout<<s; } BT4-2.b.

Trang 177

Bài tập lập trình căn bản – SGU2010 #include<iostream.h> void main() { int n; float s=0; cin>>n; for (int i=1;i<=n;i++) s=s+1.0/(2*i); cout<<s; } BT4-2.c. tu=1; mau=0; s=0; for (i=1;i<=n;i++) { tu=tu*x; mau=mau+i; s=s+(float)tu/mau; } cout<<s; BT4-2.d. tu=1; mau=1; s=0; dau=-1; for (i=1;i<=n;i++) { tu=tu*x; mau=mau*i;

Trang 178

Bài tập lập trình căn bản – SGU2010 s=s+(float)dau*tu/mau; dau=-dau; } cout<<s; BT4-2.d (cải tiến) #include<conio.h> #include<iostream.h> void main() { clrscr(); int n; float x,s=0; int dau=-1; cin>>n; cin>>x; float k=1; for (int i=1;i<=n;i++) { k=k*(float)x/i; s=s+dau*k; dau=-dau; } cout<<s; getch(); } BT4-3. #include<iostream.h> #include<conio.h> void main() {

Trang 179

Bài tập lập trình căn bản – SGU2010 clrscr(); int n; long s,k; cin>>n; s=0; for (int i=1;i<=n;i++) { k=1; for (int j=i;j<=2*i;j++) k=k*j; s=s+k; } cout<<s; getch(); } BT4-4.a. #include<iostream.h> #include<conio.h> #include<math.h> void main() { clrscr(); int n,x; float s,alpha; cin>>n>>x; s=0; alpha=x*M_PI/180; for (int i=1;i<=n;i++) { alpha=sin(alpha); s=s+alpha;

Trang 180

Bài tập lập trình căn bản – SGU2010 } cout<<s; getch(); }

Trang 181

BT4-5.b. Với n là số nguyên tố nhập vào. Đặt i=n+1; Kiểm tra xem i có phải là số nguyên tố hay không? Nếu đúng thì i là kết quả cần tìm, nếu không thì tăng i lên 1 đơn vị và tiếp tục vòng lặp. #include<conio.h> #include<iostream.h> void main() { clrscr(); int n; cout<<"Nhap vao so nguyen to n = ";cin>>n; int flag=1,i=n+1,d; if (n==2) cout<<"So nguyen to can tim la : "<<3; else while (flag) { int d=0; for (int j=1;j<=i;j++) if (i%j==0) d++; if (d==2) { cout<<"So nguyen to can tim la : "<<i; flag=0; } i=i+1; }

Bài tập lập trình căn bản – SGU2010

Trang 182

getch(); } Bạn đọc có thể tối ưu chương trình trên bằng cách thay đổi cách kiểm tra i có phải là số nguyên tố hay không ? Hoặc là cho biến i tăng mỗi lần 2 đơn vị thay cho việc cho biến i tăng 1 đơn vị - đều này là đúng khi n không phải là 2. (Bạn đọc sẽ gặp lại cách trình bày bài này theo một cách hiệu quả hơn sau khi học xong vấn đề hàm). BT4-6. #include<conio.h> #include<iostream.h> int thang,ngay,songay,d; void main() { clrscr(); d=6; for (thang=1;thang<=12;thang++) { switch (thang) { case 1: case 3: case 5: case 7: case 8: case 10: case 12:songay=31; break; case 4: case 6: case 9: case 11:songay=30;break; case 2: songay=28;break;

Bài tập lập trình căn bản – SGU2010

Trang 183

} for (ngay=1;ngay<=songay;ngay++) { d=d+1; if (d%7==0 && ngay<=7) if (thang!=7 && thang !=8) cout<<"\nThu Sau ngay "<<ngay<< "thang "<<thang<< " nam 2010"; } } getch(); }

Bài tập lập trình căn bản – SGU2010 Chương 5 BT5-1.a. #include <conio.h> #include <iostream.h> int tongchuso(int n); void main() { clrscr(); int n; cin>>n; cout<<tongchuso(n); getch(); } int tongchuso(int n) { int s=0; while(n>0) { s=s+n%10; n=n/10; } return s; }

Trang 184

BT5-2. a.Viết hàm kiểm tra số nguyên tố. Gọi d là số lượng số nguyên tố (đầu tiên cho d=0). Cho for i=1 đến n. Nếu i là số nguyên tố thì d++; d chính là kết quả cần tìm. b.Viết hàm kiểm tra số nguyên tố. Cho i = n+1, kiểm tra i có phải là số nguyên tố hay không ? Nếu đúng thì i là kết quả và dừng thuật toán. Nếu không phải thì tăng i lên 1 đơn vị và tiếp tục vòng lặp. c.Tìm số nguyên tố gần nhất

Bài tập lập trình căn bản – SGU2010 int nguyentogannhat(int n) { int u=n,v=n; while (!nguyento(u)) u++; while (!nguyento(v)) v--; return u-n>=n-v?v:u; }

Trang 185

BT5-3. Do ước số tự nhiên nhỏ nhất k của một số n là một số nguyên tố. Do đó ta chỉ cần tìm k của n, sau đó cập nhật n=n/k. Vòng lặp tiếp tục đến khi k=0 thì dừng lại. Dãy số k tìm được chính là kết quả cần tìm. #include <conio.h> #include <iostream.h> int nguyentonhonhat(int n); void phantich(int n); void main() { clrscr(); int n; cout<<"Nhap vao so tu nhien n>=1:";cin>>n; phantich(n); getch(); } int nguyentonhonhat(int n) { for (int i=2;i<=n;i++) if (n%i==0) return i; } void phantich(int n) { int k;

Bài tập lập trình căn bản – SGU2010 while (n>1) { k=nguyentonhonhat(n); cout<<k<<" "; n=n/k; } } BT5-7. #include<conio.h> #include<iostream.h> float tim(float a1,float a2,int d) { float kq; switch (d) { case 1:kq = a1+a2;break; case 2:kq = a1-a2;break; case 3:kq = a1*a2;break; case 4:kq = a1/a2;break; }; return kq; } void main() { clrscr(); char dau[5]; dau[1]='+'; dau[2]='-'; dau[3]='*'; dau[4]='/'; int a1,a2,a3,a4,a5,a6; cin>>a1>>a2>>a3>>a4>>a5>>a6;

Trang 186

Bài tập lập trình căn bản – SGU2010 for (int i=1;i<=4;i++) for (int j=1;j<=4;j++) for (int k=1;k<=4;k++) for (int l=1;l<=4;l++) if (tim(tim(tim(tim(a1,a2,i),a3,j),a4,k),a5,l)==a6)

Trang 187

cout<<"\n((("<<a1<<dau[i]<<a2<<")"<<dau[j]<<a3<<")"<<dau[k]<<a 4<<")"<<dau[l]<<a5<<'='<<a6; getch(); } BT5-8. Một lởi giải hiển nhiên nhất cho bài tóan này là tìm giao điểm của hai đoạn, sau đó kiểm tra xem giao điểm này có thuộc vào cả hai đoạn thẳng đang xét hay không ? Thế nhưng với những trường hợp khá đặc biệt như khi bốn đầu mút của hai đoạn thẳng thằng hàng hay đặc biệt hơn nữa khi đoạn này chứa đoạn kia, hoặc cả bốn đầu mút của hai đoạn trùng nhau,...thì thuật giải này sẽ gây ra một chút phiền hà. Ở đây chúng tôi có thể tìm được kết quả mà không cần tìm giao điểm của hai đoạn thẳng với ý tưởng là hai đoạn thẳng AB và CD cắt nhau nếu thoả một trong các điều kiện sau: Điều kiện a)Mỗi đầu mút của đoạn này thuộc đoạn kia. Điều kiện b)Hai đầu mút của mỗi đoạn thẳng nằm trên hai miền khác nhau được chia bởi đường thẳng chứa đoạn thẳng kia. Sau đây ta sẽ lần lượt xét 2 điều kiện này. Điều kiện a) Điểm M(xm,ym) thuộc vào đoạn AB nếu AM + MB = AB Hàm sau sẽ kiểm tra xem điểm M có thuộc đoạn thẳng AB hay không ? int thuoc(int xa,int ya,int xb,int yb,int xm,int ym) { return fabs(kc(xa,ya,xm,ym)+kc(xm,ym,xb,yb)-kc(xa,ya,xb,yb))<=1.E-6; } Với kc là hàm tính khoảng cách giữa hai điểm AB:

Bài tập lập trình căn bản – SGU2010 float kc(int xa,int ya,int xb,int yb) { return sqrt((xb-xa)*(xb-xa)+(yb-ya)*(yb-ya)); }

Trang 188

Điều kiện B) Giả sử phương trình đường thẳng AB là dt(xa,ya,xb,yb,xm,ym) = 0 (với M(xm,ym) là một điểm bất kỳ thuộc đường thẳng AB), hai điểm C, D nằm trên 2 miền khác nhau đối với đường thẳng chứa đoạn thẳng AB nếu: dt(xa,ya,xb,yb,xc,yc) * dt(xa,ya,xb,yb,xd,yd) < 0, khi đó hai đoạn AB và CD giao nhau theo điều kiện b) nếu (dt(xa,ya,xb,yb,xc,yc)*dt(xa,ya,xb,yb,xd,yd)<0) && (dt(xc,yc,xd,yd,xa,ya)*dt(xc,yc,xd,yd,xb,yb)<0); Trong đó hàm dt được viết dễ hiểu như sau: float dt(int xa,int ya,int xb,int yb,int xm,int ym) { if (xa == xb) return xm-xa; else if (ya == yb) return ym-ya; else return (xm-xa)/(xb-xa) - (ym-ya)/(yb-ya); } Tóm lại 2 đoạn thẳng AB và CD là giao nhau nếu hàm Catdoan sau trả về giá trị đúng. int catdoan(int xa,int ya,int xb,int yb,int xc,int yc,int xd,int yd) { return (thuoc(xa,ya,xb,yb,xc,yc) || thuoc(xa,ya,xb,yb,xd,yd) || thuoc(xc,yc,xd,yd,xa,ya) || thuoc(xc,yc,xd,yd,xb,yb)) || (dt(xa,ya,xb,yb,xc,yc)*dt(xa,ya,xb,yb,xd,yd)<0) &&

Bài tập lập trình căn bản – SGU2010 (dt(xc,yc,xd,yd,xa,ya)*dt(xc,yc,xd,yd,xb,yb)<0); }

Trang 189

#include <iostream.h> #include <conio.h> #include <math.h> float kc(int xa,int ya,int xb,int yb) { return sqrt((xb-xa)*(xb-xa)+(yb-ya)*(yb-ya)); } int thuoc(int xa,int ya,int xb,int yb,int xm,int ym) { return fabs(kc(xa,ya,xm,ym)+kc(xm,ym,xb,yb)-kc(xa,ya,xb,yb))<=1.E-6; } float dt(int xa,int ya,int xb,int yb,int xm,int ym) { if (xa == xb) return xm-xa; else if (ya == yb) return ym-ya; else return (xm-xa)/(xb-xa) - (ym-ya)/(yb-ya); } int catdoan(int xa,int ya,int xb,int yb,int xc,int yc,int xd,int yd) { return (thuoc(xa,ya,xb,yb,xc,yc) || thuoc(xa,ya,xb,yb,xd,yd) || thuoc(xc,yc,xd,yd,xa,ya) || thuoc(xc,yc,xd,yd,xb,yb)) || (dt(xa,ya,xb,yb,xc,yc)*dt(xa,ya,xb,yb,xd,yd)<0) && (dt(xc,yc,xd,yd,xa,ya)*dt(xc,yc,xd,yd,xb,yb)<0); }

Bài tập lập trình căn bản – SGU2010 void main() { clrscr(); cout<<catdoan(0,0,4,4,2,2,6,6); getch(); }
Các bộ test mẫu: A (0,0) (0,0) (0,0) (0,0) B (2,2) (4,4) (4,4) (0,0) C (4,4) (2,2) (2,2) (4,4) D (6,6) (6,6) (0,2) (4,4)

Trang 190

Kết quả 0 1 1 0

BT5-9. Sử dụng các hàm ở BT5-8. M nằm trên các cạnh của tam giác nếu M thuộc về một trong ba cạnh của tam giác. M nằm trong tam giác khi và chỉ khi M với mỗi đỉnh của tam giác luôn nằm cùng một phía đối với hai đỉnh còn lại. BT5-10. Trước hết viết hàm kiểm tra xem một điểm (x,y) có thuộc về một hình chữ nhật hay không (xem BT3-9). Tiếp theo là tìm hình chữ nhật nhỏ nhất bao hai hình chữ nhật đã cho. Giả sử được hình chữ nhật có góc dưới trái là (xa,ya) và góc trên phải là (xb,yb). Cuối cùng là dùng hai vòng lặp for để duyệt từng ô vuông của hình chữ nhật (xa,ya), (xb,yb). Ô vuông nào thuộc về một trong hai hình chữ nhật đã cho thì sẽ được tính vào diện tích cần tìm (việc kiểm tra một ô vuông thuộc về hình chữ nhật có thể xét giao điểm của hai đường chéo ô vuông có thuộc về hình chữ nhật đó hay không ? tất nhiên có nhiều cách để giải quyết vấn đề này).

Bài tập lập trình căn bản – SGU2010 Chương 6 BT6-3. #include<conio.h> #include<iostream.h> void nhap(int a[], int &n); int tongday(int a[], int n); int demchan(int a[], int n); void main() { clrscr(); int a[100],n; nhap(a,n); getch(); } int demchan(int a[], int n) { if (n==0) return 0; return (a[n-1]%2==0)+dem(a,n-1); } void nhap(int a[], int &n) { cin>>n; for (int i=0; i<n;i++) cin>>a[i]; } int tongday(int a[], int n) { if (n>0)

Trang 191

Bài tập lập trình căn bản – SGU2010 return a[n-1]+tongday(a,n-1); return 0; } BT6-3. #include<iostream.h> #include<conio.h> int uscln(int a, int b); void main() { clrscr(); int a,b; cin >>a>>b; cout<<uscln(a,b); getch(); } int uscln(int a, int b) { if (a%b!=0) return uscln(b,a%b); return b; } BT6-5. #include <iostream.h> int f(int n) { if (n==1) return 1; else if (n%2==0) return 2*f(n/2); else return 2*f(n/2)+3*f(n/2+1); }

Trang 192

Bài tập lập trình căn bản – SGU2010 void main() { cout<<f(5); } BT6-6.b &c. #include <conio.h> #include <iostream.h> long y(int n); long yn(int n); void main() { clrscr(); cout<<y(5)<<endl; cout<<yn(5); getch(); } long y(int n) { if (n<=3) return n; return y(n-1)+2*y(n-2)+3*y(n-3); } long yn(int n) { long y1=1,y2=2,y3=3,s=n; for (int i=4;i<=n;i++) { s=y3+2*y2+3*y1;

Trang 193

Bài tập lập trình căn bản – SGU2010 y1=y2; y2=y3; y3=s; } return s; }

Trang 194

Bài tập lập trình căn bản – SGU2010

Trang 195

Chương 7 BT7-1.a.Trước hết tìm giá trị lớn nhất của các phần tử trong mảng; giả sử đó là max. Tiếp theo là viết một hàm kiểm tra một số có phải là số nguyên tố hay không ? Cuối cùng là cho một biến i bắt đầu từ max+1. Cứ mỗi giá trị của i thì kiểm tra xem i có phải là số nguyên tố hay không ? Nếu đúng thì i là kết quả và dừng thuật toán. Nếu không thì tăng i lên 1 đơn vị và tiếp tục vòng lặp. b và c.Dùng kỹ thuật đặt cờ hiệu. d và e.Dùng kỹ thuật lính canh. f và g.Dùng kỹ thuật đếm BT7-2.Viết hàm đếm tần số xuất hiện của các phần tử. Sử dụng thêm mảng phụ d chứa tần số xuất hiện của các số, đầu tiên cho mảng d toàn bằng 1. Sau đó duyệt từng cặp phần tử ai,aj của mảng (i<j). Nếu ai=aj và với d[i]>0 thì tăng d[i] lên một đơn vị và giảm d[j] xuống bằng 0. d[i] chính là tần số xuất hiện của các phần tử. void tansoxuathien(int a[], int n) { int d[1000]; for (int i=0;i<n;i++) d[i]=1; for (i=0;i<n-1;i++) for (int j=i+1;j<n;j++) if (a[i]==a[j] && d[i]>0) { d[i]=d[i]+1; d[j]=0; } for (i=0;i<n;i++) if (d[i]>0) cout<<"\n"<<a[i]<<" xuat hien "<<d[i]<<" lan "; }

Bài tập lập trình căn bản – SGU2010 BT7-3. int uscln(int a, int b) { int r=a%b; while (r!=0) { a=b; b=r; r=a%b; } return b; } void nguyentocungnhau(int a[], int n) { cout<<endl; for (int i=0;i<n-1;i++) for (int j=i+1;j<n;j++) if (uscln(a[i],a[j])==1) cout<<a[i]<<","<<a[j]<<endl; } BT7-5. int uc=a[0]; for (i=1;i<n;i++) uc=uscln(uc,a[i]); cout<<"Uoc so chung lon nhat cua n so la: "<<uc<<endl;

Trang 196

BT7-10. Thuật toán 1 Thuật toán đơn giản nhất có thể viết ngay là: xét tất cả các cặp số nguyên L và U thỏa mãn 1 £ L £ U £ n; đối với mỗi cặp như vậy ta tính tổng của dãy con a[L..U] và so sánh tổng này với giá trị lớn nhất hiện có: for (L=1;L<=n;L++)

Bài tập lập trình căn bản – SGU2010

Trang 197

for (U=L;U<=n;U++) { sum=0; for (int I=L;I<=U;I++) sum=sum+a[I]; maxsofar=max(maxsofar,sum); } chương trình này tuy ngắn và dễ hiểu, tuy nhiên nó chạy khá chậm. Thuật toán này có độ phức tạp là O(n3) Thuật toán 2 Ta có thể cải tiến thuật toán trên để có thuật toán với độ phức tạp là 2 O(n ) bằng cách sử dụng hệ thức : Tổng a[L..U]= Tổng a[L..U-1]+a[U] maxsofar=0; for (L=1;L<=n;L++) { sum=0; for (U=L;U<=n;U++) { sum=sum+a[U]; maxsofar=max(maxsofar,sum); } } Thuật toán 3 Tổng lớn nhất trong dãy con a[1..i] là tổng lớn nhất trong dãy con a[1..i-1](gọi là maxsofar) hoặc tổng lớn nhất trong tất cả các tổng của các dãy con kết thúc tại i (gọi là maxendinghere) . Chúng ta có nhận xét rằng: Dãy con lớn nhất kết thúc tại i là dãy con lớn nhất kết thúc tại vị trí i-1 được bổ sung thêm phần tử a[i] ở cuối hoặc là dãy con rỗng trong trường hợp tổng của dãy con nhận được là số âm. Ta có thuật toán như sau: maxsofar=0;

Bài tập lập trình căn bản – SGU2010 maxendinghere=0; for (i=1; i<=n;i++) { maxendinghere=max(maxendinghere+a[i],0); maxsofar=max(maxsofar,maxendinghere); } Minh họa cho thuật toán 3 1 a[i] maxendinghere maxsofar 4 4 4 2 -5 0 4 3 6 6 6 4 -4 2 6 5 2 4 6

Trang 198

6 3 7 7

7 -7 0 7

Thuật toán này có độ phức tạp là O(n). Các bộ test mẫu n 7 6 3 a1 4 4 -7 a2 -5 -3 -4 a3 6 0 0 a4 -4 0 a5 2 3 a6 3 -5 a7 -7 Kết quả 7 4 0

#include <iostream.h> #include <conio.h> void algorithm1(int a[], int n); void algorithm2(int a[], int n); void algorithm3(int a[], int n); int max(int a,int b); void input(int a[],int &n); void main() { int a[100],n; input(a,n); algorithm1(a,n); getch();

Bài tập lập trình căn bản – SGU2010 } void input(int a[],int &n) { clrscr(); cin>>n; for (int i=1;i<=n;i++) cin>>a[i]; } void algorithm1(int a[], int n) { int maxsofar=0; for (int L=1;L<=n;L++) for (int U=L;U<=n;U++) { int sum=0; for (int I=L;I<=U;I++) sum=sum+a[I]; maxsofar=max(maxsofar,sum); } cout<<maxsofar; } void algorithm2(int a[], int n) { int maxsofar=0; for (int L=1;L<=n;L++) { int sum=0; for (int U=L;U<=n;U++)

Trang 199

Bài tập lập trình căn bản – SGU2010 { sum=sum+a[U]; maxsofar=max(maxsofar,sum); } } cout<<maxsofar; } void algorithm3(int a[], int n) { int maxsofar=0; int maxendinghere=0; for (int i=1; i<=n;i++) { maxendinghere=max(maxendinghere+a[i],0); maxsofar=max(maxsofar,maxendinghere); } cout<<maxsofar; } int max(int a,int b) { return a>b?a:b; }

Trang 200

Bài tập lập trình căn bản – SGU2010 Chương 8 BT8-3.a & b. #include <conio.h> #include <iostream.h> const maxn=20; void nhapmang(int a[maxn][maxn], int &n); int tongtgduoi(int a[maxn][maxn], int n); int gtlntgtren(int a[maxn][maxn], int n); void main() { clrscr(); int a[maxn][maxn],n; nhapmang(a,n); cout<<"\nTong cac phan tu trong ma tran tg duoi: "<<tongtgduoi(a,n); cout<<"\nGia tri lon nhat trong ma tran tam gia tren :"<<gtlntgtren(a,n); getch(); } void nhapmang(int a[maxn][maxn],int &n) { cout<<"Nhap vao n : ";cin>>n; for (int i=0;i<n;i++) for (int j=0;j<n;j++) cin>>a[i][j]; } int tongtgduoi(int a[maxn][maxn], int n) { int tong=0; for (int i=1;i<n;i++) for (int j=0;j<i;j++) tong+=a[i][j]; return tong;

Trang 201

Bài tập lập trình căn bản – SGU2010 } int gtlntgtren(int a[maxn][maxn], int n) { int max=a[0][1]; for (int i=0;i<n-1;i++) for (int j=i+1;j<n;j++) if (a[i][j]>max) max=a[i][j]; return max; }
Các bộ test mẫu n=5 4 1 3 5 4 6 6 6 2 7 7 3 4 8 9 8 19 0 2 10 15 4 3 3 3

Trang 202

Kết quả: a. b. 55 19

BT8-5. #include<conio.h> #include<iostream.h> #include<iomanip.h> void main() { clrscr(); int a[100][100]; int n; cout<<"Tam giac Pascal : \n"; cout<<"Nhap vao so n = ";cin>>n;

Bài tập lập trình căn bản – SGU2010 for (int i=0;i<=n;i++) { a[i][0]=1; a[i][i]=1; } for (i=2;i<=n;i++) for (int j=1;j<i;j++) a[i][j]=a[i-1][j-1]+a[i-1][j]; for (i=0;i<=n;i++) { for (int j=0;j<=i;j++) cout<<setw(4)<<a[i][j]; cout<<endl; } getch(); } BT8-10.a. #include <iostream.h> #include <conio.h> #include <iomanip.h> int i,j,n,t; int a[100][100]; void khoitri() { clrscr(); cout<<"Nhap n ";cin>>n; for (i=1;i<=n;i++) for (j=1;j<=n;j++)

Trang 203

Bài tập lập trình căn bản – SGU2010 a[i][j]=0; i=n; j=(n/2)+1; a[i][j]=1; } void xuly() { for (t=2;t<=n*n;t++) { i=i+1; j=j+1; if (i>n && j>n) {i=i-2;j=j-1;} if (i>n && j<=n) i=1; if (j>n && i<=n) j=1; if (a[i][j]!=0) {i=i-2;j=j-1;} a[i][j]=t; } } void inmaphuong() { for (i=1;i<=n;i++) { for (j=1;j<=n;j++) cout<<setw(4)<<a[i][j]; cout<<endl; } } void main() { khoitri(); xuly();

Trang 204

Bài tập lập trình căn bản – SGU2010 inmaphuong(); getch(); }

Trang 205

Bài tập lập trình căn bản – SGU2010 Chương 9 BT9-2. #include <alloc.h> #include <iostream.h> #include <conio.h> #include <iomanip.h> void nhap(int *a, int n); void sochanle(int *a, int n); void main() { clrscr(); int *a,n; cout<<"Nhap so phan tu cua mang :";cin>>n; a=new int [n]; nhap(a,n); sochanle(a,n); getch(); } void nhap(int *a, int n) { for (int i=0;i<n;i++) cin>>*(a+i); } void sochanle(int *a, int n) { cout <<endl<<"Cac so chan : "; for (int i=0;i<n;i++) if (*(a+i) % 2==0) cout<<setw(4)<<*(a+i); cout <<endl<<"Cac so le : ";

Trang 206

Bài tập lập trình căn bản – SGU2010 for (i=0;i<n;i++) if (*(a+i)%2==1) cout<<setw(4)<<*(a+i); delete a; } BT9-6. #include <conio.h> #include <alloc.h> #include <iostream.h> #include <iomanip.h> void nhap(int *px, int m, int n); void xuat(int *px, int m, int n); int tongmang(int *px, int m, int n); void tongdong(int *px, int m, int n); void sapdong(int *px, int m, int n); void sapbang(int *px, int m, int n);

Trang 207

void main() { int *px,m,n; cout<<"Nhap vao so dong:";cin>>m; cout<<"Nhap vao so cot"; cin>>n; px=new int [m*n]; cout<<"Nhap ma tran:\n "; nhap(px,m,n); cout<<"\nTong cac phan tu cua mang: "<< tongmang(px,m,n); cout<<"\nTong cua tung dong\n"; tongdong(px,m,n); cout<<"\nsap tang theo moi dong:"; sapdong(px,m,n);

Bài tập lập trình căn bản – SGU2010

Trang 208

xuat(px,m,n); cout<<"\nsap tang theo chieu tu trai->phai va tren -> duoi:"; sapbang(px,m,n); xuat(px,m,n); } void nhap(int *px, int m, int n) { for (int i=0;i<m;i++) for (int j=0;j<n;j++) cin>>*(px+n*i+j); } void xuat(int *px, int m, int n) { cout<<endl; for (int i=0;i<m;i++) { for (int j=0;j<n;j++) cout<<*(px+n*i+j)<<setw(4); cout<<endl; } } int tongmang(int *px, int m, int n) { int s=0; for (int i=0;i<m;i++) for (int j=0;j<n;j++) s=s+*(px+n*i+j);

Bài tập lập trình căn bản – SGU2010 return s; } void tongdong(int *px, int m, int n) { int *pd; pd=new int [m]; for (int i=0;i<m;i++) { *(pd+i)=0; for (int j=0;j<n;j++) *(pd+i)=*(pd+i) + *(px+n*i+j); cout<<*(pd+i)<<endl; } } void sapdong(int *px, int m, int n) { for (int i=0;i<m;i++) { for (int j=0;j<n-1;j++) for (int k=j+1;k<n;k++) if (*(px+n*i+j) >*(px+n*i+k)) { int temp=*(px+n*i+j); *(px+n*i+j)=*(px+n*i+k); *(px+n*i+k)=temp; } } }

Trang 209

Bài tập lập trình căn bản – SGU2010

Trang 210

void sapbang(int *px, int m, int n) { int *pd,t=0; pd=new int [m*n]; for (int i=0;i<m;i++) for (int j=0;j<n;j++) *(pd+(t++))=*(px+n*i+j); for (i=0;i<t-1;i++) for (int j=i+1;j<t;j++) if (*(pd+i)>*(pd+j)) { int temp=*(pd+i); *(pd+i)=*(pd+j); *(pd+j)=temp; } t=0; for (i=0;i<m;i++) for (int j=0;j<n;j++) *(px+n*i+j)=*(pd+(t++)); }

Bài tập lập trình căn bản – SGU2010 Chương 10. BT10-1.a. void demnguyenamphuam(char *s) { int nguyenam=0,phuam=0; for (int i=0;i<strlen(s);i++) if (s[i]!=' ') if (s[i]=='a' || s[i]=='o' || s[i]=='u' || s[i]=='e' ||s[i]=='i') nguyenam++; else phuam++; cout<<"\nNguyen am: "<<nguyenam; cout<<"\nPhu am: "<<phuam; }

Trang 211

BT10-2. Dùng kỹ thuật đặt cờ hiệu. Chuỗi s được gọi là đối xứng nếu điều kiện s[i]!= s[l-i-1] với i đi từ 0 đến l/2 luôn luôn sai, trong đó l=strlen(s). #include <stdio.h> #include <conio.h> #include <string.h> #include <iostream.h> int chuoidoixung(char *s); void main() { clrscr(); char s[255]; gets(s); cout<<chuoidoixung(s); getch(); } int chuoidoixung(char *s)

Bài tập lập trình căn bản – SGU2010 { int l=strlen(s); for (int i=0,b=1;i<l/2;i++) if (s[i]!= s[l-i-1]) return 0; return 1; } BT10-3. #include <iostream.h> #include <string.h> #include <conio.h> #include <stdio.h> void tudainhat(char s[]) { int dem=0, tam=0, tu=1; int n= strlen(s); for (int i=0; i<n; i++) { if (s[i]==' ') { tu++; if (dem <tam) dem=tam; tam=0; } else tam++; } if (tu==1) puts(s); tam=0; for (int i=0; i<n; i++) {

Trang 212

Bài tập lập trình căn bản – SGU2010 if(s[i]!=' ') tam++; if(s[i]==' ') { if (dem==tam) { tam++; for(int j=i-tam; j<i; j++) cout<<s[j]; } tam=0; } if(i==n-1 && dem==tam) for (int j=i-tam; j<n; j++) cout<< s[j]; } } void innguoc(char s[]) { int n=strlen(s); int j=0; s[n]=' '; for(int i=n-1; i>0; i--) { if (s[i]==' ') { j=i; while (s[++j]!=' ') cout<<s[j]; cout<<" "; } }; int i=-1;

Trang 213

Bài tập lập trình căn bản – SGU2010 while (s[++i]!=' ') cout<<s[i]; } void main() { char s[100]; cout<<"nhap chuoi: "; gets (s); cout<< "chuoi da nhap: "; puts(s); cout<<"tu dai nhat: "; tudainhat(s); printf("\n"); cout<<"chuoi in nguoc: "; innguoc(s); getch(); }

Trang 214

BT10-4.a. #include <iostream.h> #include <conio.h> #include <string.h> char *catkhoangtrong(char *s); void main() { clrscr(); char *s="Thanh Pho Ho Chi Minh"; cout<<catkhoangtrong(s); getch(); } Tìm chuỗi con có 2 ký tự trắng, nếu tìm được thì trả về vị trí p. Sau đó chuyển chuỗi s về trước một vị trí. Lặp công việc này ta sẽ được chuỗi mà giữa các từ chỉ có duy nhất một khoẳng trắng. Vấn đề tiếp theo là có thể chuỗi còn ký tự khoảng trắng đầu chuỗi và cuối chuỗi.

Bài tập lập trình căn bản – SGU2010

Trang 215

-Trường hợp nếu ký tự đầu chuỗi là ký tự khoảng trắng thì giải quyết như trên (nghĩa là chuyển chuỗi về trước một vị trí) -Trường hợp nếu ký tự cuối chuỗi là ký tự khoảng trắng thì đặt dấu kết thúc chuỗi tại vị trí đó. char* catkhoangtrong(char *s) { char *p; while (p = strstr(s, " ")) strncpy(p, p+1, strlen(s) - (p - s)); if (s[0] == ' ') strncpy(s, s+1, strlen(s) - 1); if (s[strlen(s)] == ' ') s[strlen(s)]='\0'; return s; } BT10-5.a. Đặt chuỗi s2=s+k+n; nghĩa là s2 chứa các ký tự phía sau các ký tự cần xóa. Đặt chuỗi s1[k]='\0'; nghĩa là s1 chứa các ký tự phía trước các ký tự cần xóa. Nối chuỗi s2 vào sau chuỗi s1 ta được kết quả cần tìm s1 s+k+n s2 char *xoankytu(char *s,int n, int k) { char *s1,*s2; strcpy(s1,s); s1=s+k+n; strcpy(s2,s); s2[k]='\0'; return strcat(s2,s1); } BT10-5.b. Đặt s1temp là chuỗi s1 kết thúc tại vị trí d.

Bài tập lập trình căn bản – SGU2010 Đặt s2temp là chuỗi gồm các ký tự từ vị trí d đến cuối chuỗi . Sau đó nối s2 vào giữa s1temp và s2temp đó chính là chuỗi cần tìm. char *chenchuoikytu(char *s1, char *s2,int d) { char *s1temp,*s2temp; strcpy(s1temp,s1); s1temp[d]='\0'; s2temp=s1+d; strcat(s1temp,s2); return strcat(s1temp,s2temp); } BT10-9. #include <stdio.h> #include <string.h> #include <conio.h> #include <iostream.h> char s[50] = ""; char *bachuso(unsigned int n) { char kyso[10][5]= {"", "mot", "hai", "ba", "bon", "nam", "sau", "bay", "tam", "chin"}; int donvi, chuc, tram; s[0] = 0; donvi = n % 10; n /= 10; chuc = n % 10; tram = n / 10; if (tram > 0) { strcat(s, kyso[tram]);

Trang 216

Bài tập lập trình căn bản – SGU2010 strcat(s, " tram "); } if (chuc > 0) { if (chuc == 1) strcat(s, "muoi "); else { strcat(s, kyso[chuc]); strcat(s, " muoi "); } } if (donvi > 0) { if (chuc == 0 && tram != 0) strcat(s, "le "); if (donvi == 1) strcat(s, "mot"); else if (donvi == 5 && (chuc != 0 || tram != 0)) strcat(s, "lam"); else if (donvi == 5 && (chuc == 0 || tram != 0)) strcat(s, "nam"); else strcat(s, kyso[donvi]); } return s; } void main() {

Trang 217

Bài tập lập trình căn bản – SGU2010 unsigned long n; unsigned ngan, trieu, ty, donvi; char chuoi[200]; printf("\nNhap mot so khong dau : "); scanf("%ld", &n); printf("So %ld doc bang chu la :\n", n); if (n == 0) printf("khong"); else { donvi = n % 1000; n /= 1000; ngan = n % 1000; n /= 1000; trieu = n % 1000; ty = n / 1000; chuoi[0] = 0; if (ty > 0) printf("%s ty", bachuso(ty)); if (trieu > 0) printf("%s trieu ", bachuso(trieu)); if (ngan > 0) printf("%s ngan ", bachuso(ngan)); if (donvi > 0) printf("%s", bachuso(donvi)); } getch(); }

Trang 218

Bài tập lập trình căn bản – SGU2010 Chương 11 BT11-1.a. #include <conio.h> #include <iostream.h> struct toado { int x; int y; }; void nhap(toado diem[], int &n); void tansuat(toado diem[], int n); void main() { clrscr(); int n;toado diem[100]; nhap(diem,n); tansuat(diem,n); getch(); } void nhap(toado diem[], int &n) { cin>>n; for (int i=0;i<n;i++) cin>>diem[i].x>>diem[i].y; } void tansuat(toado diem[], int n) { int d[100]; for (int i=0; i<n;i++) d[i]=1;

Trang 219

Bài tập lập trình căn bản – SGU2010

Trang 220

for (i=0; i<n-1;i++) for (int j=i+1; j<n;j++) if(diem[i].x==diem[j].x && diem[i].y==diem[j].y) { d[i]++; d[j]=0; } for (i=0; i<n;i++) if (d[i]!=0) { cout<<"\nToa do "<<diem[i].x<<"/"<<diem[i].y<<" xuat hien "<<d[i]<<" lan"; d[i]=0; } } BT11-5.a. #include <conio.h> #include <math.h> #include <iostream.h> #include <stdio.h> struct toado { int x; int y; }; void nhap(toado &A,toado &B, toado &C, toado &D); double kc(toado A, toado B); int thuoccanh(toado A, toado B, toado M); double dt(toado A, toado B, toado M); int catdoan(toado A,toado B, toado C, toado D);

Bài tập lập trình căn bản – SGU2010 void { main() clrscr(); toado A,B,C,D; nhap(A,B,C,D); cout<<catdoan(A,B,C,D); getch(); } void nhap(toado &A,toado &B, toado &C, toado &D) { cout<<"\nNhap toa do diem A : ";cin>>A.x>>A.y; cout<<"\nNhap toa do diem B : ";cin>>B.x>>B.y; cout<<"\nNhap toa do diem C : ";cin>>C.x>>C.y; cout<<"\nNhap toa do diem D : ";cin>>D.x>>D.y; } double kc(toado A, toado B) { return sqrt((B.x - A.x)*(B.x-A.x) + (B.y - A.y)*(B.y - A.y)); } int thuoccanh(toado A, toado B, toado M) { return fabs(kc(A,M)+kc(B,M)-kc(A,B))<=1.E-6; } double dt(toado A, toado B, toado M) { if (A.x == B.x) return M.x-A.x; else if (A.y == B.y) return M.y-A.y; else return (M.x-A.x)/(B.x-A.x) - (M.y-A.y)/(B.y-A.y); }

Trang 221

Bài tập lập trình căn bản – SGU2010 int catdoan(toado A,toado B, toado C, toado D) { return thuoccanh(A,B,C) || thuoccanh(A,B,D) || thuoccanh(C,D,A) || thuoccanh(C,D,B) || (dt(A,B,C)*dt(A,B,D)<0) && (dt(C,D,A)*dt(C,D,B)<0); } BT11-5.b #include <math.h> #include <iostream.h> #include <conio.h> struct toado { int x; int y; }; void nhap(toado &A,toado &B, toado &C, toado &M); double kc(toado A, toado B); int thuoccanh(toado A, toado B, toado M); double dientich(toado A, toado B, toado C); int xetvitri(toado A, toado B, toado C, toado M); void main() { toado A,B,C,M; nhap(A,B,C,M); if (xetvitri(A,B,C,M) ==0) else if (xetvitri(A,B,C,M) ==1) else

Trang 222

cout<<"M nam tren canh tam giac ABC "; cout<<"M nam trong tam giac ABC ";

Bài tập lập trình căn bản – SGU2010

Trang 223

cout<<"M nam ngoai tam giac ABC "; getch(); } void nhap(toado &A,toado &B, toado &C,toado &M) { clrscr(); cout<<"Nhap toa do diem A : \n";cin>>A.x>>A.y; cout<<"Nhap toa do diem B : \n";cin>>B.x>>B.y; cout<<"Nhap toa do diem C : \n";cin>>C.x>>C.y; cout<<"Nhap toa do diem M : \n";cin>>M.x>>M.y; } double kc(toado A, toado B) { return sqrt((B.x - A.x)*(B.x-A.x) + (B.y - A.y)*(B.y - A.y)); } int thuoccanh(toado A, toado B, toado M) { return fabs(kc(A,M)+kc(B,M)-kc(A,B))<=1.E-6; } double dientich(toado A, toado B, toado C) { double a=kc(B,C); double b=kc(A,C); double c=kc(A,B); double p=(a+b+c)/2; double s=sqrt(p*(p-a)*(p-b)*(p-c)); return s;

Bài tập lập trình căn bản – SGU2010 } int xetvitri(toado A, toado B, toado C, toado M) { if (thuoccanh(A,B,M) || thuoccanh(A,C,M) || thuoccanh(B,C,M)) return 0; if(fabs(dientich(M,A,B)+dientich(M,A,C)+dientich(M,B,C)dientich(A,B,C))<=1.E-6) return 1; return -1; } BT11-7. #include<conio.h> #include<iostream.h> #include<stdlib.h> #include<stdio.h> #include<string.h> struct nhanvien { char manv[8]; char hoten[20]; unsigned namsinh; char phongban[10]; float luongcb; float thuong; float thuclanh; }; int n; struct nhanvien nv[100],temp; void nhap(nhanvien nv[], int &n); void xuat(nhanvien nv[], int n);

Trang 224

Bài tập lập trình căn bản – SGU2010 void void void void void tongthuclanh(nhanvien nv[], int n); luongcbthapnhat(nhanvien nv[], int n); mucthuong(nhanvien nv[], int n); sapxep(nhanvien nv[], int n); capnhatluong(nhanvien nv[], int n);

Trang 225

void main() { clrscr(); nhap(nv,n); tongthuclanh(nv,n); luongcbthapnhat(nv,n); mucthuong(nv,n); sapxep(nv,n); xuat(nv,n); capnhatluong(nv,n); xuat(nv,n); getch(); } void nhap(nhanvien nv[], int &n) { cout<<"Ho so co bao nhieu nhan vien:"; cin>>n; for(int i=0;i< n;i++) { cout<<"\nManv:"; fflush(stdin); gets(nv[i].manv); cout<<"Ho ten:"; fflush(stdin); gets(nv[i].hoten); cout<<"Nam sinh:"; cin>>nv[i].namsinh; cout<<"Phong Ban:"; fflush(stdin);

Bài tập lập trình căn bản – SGU2010 gets(nv[i].phongban); cout<<"Luong CB:"; cin>>nv[i].luongcb; cout<<"Thuong:"; cin>>nv[i].thuong; nv[i].thuclanh = nv[i].luongcb + nv[i].thuong; } }

Trang 226

void xuat(nhanvien nv[], int n) { cout<<endl; cout<<"Manv Ho ten Nam sinh Phong ban LuongCB Thuong Thuc lanh"<<endl; for(int i=0;i<n;i++) cout<<nv[i].manv<<nv[i].hoten<<nv[i].namsinh<<nv[i].phongban< <nv[i].luongcb<<nv[i].thuong<<nv[i].thuclanh; } void tongthuclanh(nhanvien nv[], int n) { long tong=0; for(int i=0;i<n;i++) tong=tong +nv[i].thuclanh; cout<<"\nTong thuc lanh la "<<tong; } void luongcbthapnhat(nhanvien nv[], int n) { long min=nv[0].luongcb; for(int i=1;i<n;i++) if (nv[i].luongcb<min) min=nv[i].luongcb;

Bài tập lập trình căn bản – SGU2010 cout<<"\nLuong co ban thap nhat la:"<<min; }

Trang 227

void mucthuong(nhanvien nv[], int n) { int dem=0; for(int i=0;i<n;i++) if (nv[i].thuong>=1200000) dem++; cout<<"\nSo luong nhan vien co muc thuong >=1200000 la: "<<dem; } void sapxep(nhanvien nv[], int n)// cau 5 { for(int i=0;i<n-1;i++) for(int j=i+1;j<n;j++) if ( strcmp(nv[i].phongban,nv[j].phongban) > 0 || (strcmp(nv[i].phongban,nv[j].phongban)==0 && strcmp(nv[i].manv,nv[j].manv)<0)) { temp = nv[i]; nv[i] = nv[j]; nv[j] = temp; } } void capnhatluong(nhanvien nv[], int n)//cau 6 { for(int i=0;i<n;i++) { nv[i].luongcb=nv[i].luongcb+nv[i].luongcb*5.0/100;

Bài tập lập trình căn bản – SGU2010 nv[i].thuclanh = nv[i].luongcb + nv[i].thuong; } } BT11-8. #include <conio.h> #include <iostream.h> #include <alloc.h> #include <stdio.h> #include <string.h> struct hoadon { char mahang[4]; char tenhang[25]; long dongia; int soluong; long thanhtien; }; hoadon *mh; int n; void Nhap(hoadon *mh, int n); void Xuat(hoadon *mh, int n); void Dongiacaonhat(hoadon *mh, int n); void Saptenhang(hoadon *mh, int n); void main() { clrscr(); cout<<"Nhap n = ";cin>>n; mh=new hoadon [n]; Nhap(mh,n); Xuat(mh,n);

Trang 228

Bài tập lập trình căn bản – SGU2010 Dongiacaonhat(mh,n); Saptenhang(mh,n); Xuat(mh,n); free(mh); getch();

Trang 229

} void Nhap(hoadon *mh, int n) { for (int i=0;i<n;i++) { cout<<"Nhap ma hang :";fflush(stdin);gets(((mh+i))>mahang); cout<<"Nhap ten hang :";fflush(stdin);gets(((mh+i))>tenhang); cout<<"Nhap don gia :"; cin>>(mh+i)->dongia; cout<<"Nhap so luong :"; cin>>(mh+i)->soluong; (mh+i)->thanhtien=(mh+i)->soluong*(mh+i)->dongia; cout<<endl; } } void Xuat(hoadon *mh, int n) { for (int i=0;i<n;i++) cout<<(mh+i)->mahang <<(mh+i)->tenhang <<(mh+i)>dongia <<(mh+i)->soluong <<(mh+i)->thanhtien<<endl; } void Dongiacaonhat(hoadon *mh, int n) {

Bài tập lập trình căn bản – SGU2010

Trang 230

cout<<"Tim nhung mat hang co don gia cao nhat"; long max=mh->dongia; for (int i=1;i<n;i++) if ((mh+i)->dongia>max) max=(mh+i)->dongia; cout<<"\nNhung mat hang co don gia cao nhat\n"; for (i=0;i<n;i++) if ((mh+i)->dongia==max) cout<<(mh+i)->mahang<<(mh+i)->tenhang<<(mh+i)->dongia <<(mh+i)->soluong <<(mh+i)->thanhtien<<endl; } void Saptenhang(hoadon *mh, int n) { cout<<"sap xep"; hoadon temp; for (int i=0;i<n-1;i++) for (int j=i+1;j<n;j++) if (strcmp((mh+i)->tenhang,(mh+j)->tenhang)>0) { temp=*(mh+i); *(mh+i)=*(mh+j); *(mh+j)=temp; } } BT11-9. #include<conio.h> #include<iostream.h> #include<stdlib.h> #include<stdio.h> #include<iomanip.h> struct NGAY

Bài tập lập trình căn bản – SGU2010 { int ngay; int thang; int nam; }NGAY; struct HOSO { char hoten [30]; struct NGAY ns; long LCB; long thuong; long thuclanh; } HOSO; int n; struct HOSO nv[50],temp; void nhap(); void xuat(); void sapxep(); void main() { clrscr(); nhap(); sapxep(); xuat(); getch(); } void nhap() { cout<<"Ho so co bao nhieu nhan vien:"; cin>>n; for(int i=1;i<=n;i++)

Trang 231

Bài tập lập trình căn bản – SGU2010 { cout<<"\Nhap nhan vien thu: "<<i; cout<<"\nHo ten:"; fflush(stdin); gets(nv[i].hoten); cout<<"Ngay:"; fflush(stdin); cin>>nv[i]. ns.ngay; cout<<"Thang:"; fflush(stdin); cin>>nv[i]. ns.thang; cout<<"Nam:"; fflush(stdin); cin>>nv[i]. ns.nam; cout<<"LCB:";fflush(stdin); cin>>nv[i].LCB; out<<"Thuong:";fflush(stdin); cin>>nv[i].thuong; nv[i].thuclanh = nv[i].LCB + nv[i].thuong; } }

Trang 232

void xuat() { cout<<" Ho ten Ngay sinh LCB Thuong Thuc lanh"<<endl; for(int i=1;i<=n;i++) cout<<nv[i].hoten<<setw(5)<<nv[i]. ns.ngay<<setw(5)<<nv[i]. ns.thang<<setw(5)<<nv[i]. ns.nam <<setw(5)<<nv[i].LCB<<setw(5)<<nv[i].thuong<<setw(5)<<nv[i].thuclanh ; } void sapxep() { for(int i=1;i<=n-1;i++) for(int j=i+1;j<=n;j++) if(nv[i].thuclanh > nv[j].thuclanh)

Bài tập lập trình căn bản – SGU2010 { temp = nv[i]; nv[i] = nv[j]; nv[j] = temp; } } BT11-10. #include <iostream.h> #include <conio.h> #include <stdio.h> #include <string.h> struct hoadon { char mahang[8]; char tenhang[20]; float dongia; char donvi[10]; }; void nhap(hoadon mh[], int &n); void xuat(hoadon mh[], int n); void tenhanggiacao(hoadon mh[], int n); void main() { int n; hoadon mh[100]; nhap(mh,n); xuat(mh,n); tenhanggiacao(mh,n); } void nhap(hoadon mh[], int &n)

Trang 233

Bài tập lập trình căn bản – SGU2010 {

Trang 234

clrscr(); cout<<"Nhap vao so luong mat hang: ";cin>>n; for (int i=0; i<n;i++) { fflush(stdin); cout<<"Ma hang: ";gets(mh[i].mahang); fflush(stdin); cout<<"Ten hang: ";gets(mh[i].tenhang); cout<<"Don gia: ";cin>>mh[i].dongia; fflush(stdin); cout<<"don vi: ";gets(mh[i].donvi); } } void xuat(hoadon mh[], int n) { cout<<endl; for (int i=0; i<n;i++) if (strcmp(mh[i].donvi,"kg")==0) cout<<mh[i].mahang<<endl; } void tenhanggiacao(hoadon mh[], int n) { float max=-1; for (int i=0; i<n;i++) if (strcmp(mh[i].donvi,"kg")==0 && mh[i].dongia>max) max=mh[i].dongia; for (i=0; i<n;i++) if (strcmp(mh[i].donvi,"kg")==0 && mh[i].dongia==max) cout<<mh[i].tenhang; if (max!=-1) cout<<"khong co mat hang co don vi tinh la kg"; getch(); }

Bài tập lập trình căn bản – SGU2010 Bài tập nâng cao BT13-1.a. #include <conio.h> #include <iostream.h> int a[8],b[15],c[15],x[8],i,d=0; void Queen(int i) { if (i>8) { for (int j=1;j<=8;j++) cout<<x[j]; cout<<endl; d++; // Số lời giải } else for (int j=1;j<=8;j++) if ((a[j]==0) && (b[i+j]==0) && (c[i-j+8]==0)) { x[i]=j; a[j]=1;b[i+j]=1;c[i-j+8]=1; Queen(i+1); a[j]=0;b[i+j]=0;c[i-j+8]=0; } } void main() { clrscr(); Queen(1); cout<<"Tong so loi giai la: "<<d; getch(); }

Trang 235

Bài tập lập trình căn bản – SGU2010 BT13-2.a. #include <iostream.h> #include <conio.h> int x[1000],b[1000],n; void xuat(); void hoanvi(int i); void main() { clrscr(); cout<<"Nhap vao so phan tu n = ";cin>>n; for (int i=1;i<=n;i++) b[i]=1; hoanvi(1); getch(); } void xuat() { for (int i=1;i<=n;i++) cout<<x[i]<<" "; cout<<endl; } void hoanvi(int i) { for (int j=1;j<=n;j++) if (b[j]==1) { x[i]=j; b[j]=0; if (i==n) xuat();

Trang 236

Bài tập lập trình căn bản – SGU2010 else hoanvi(i+1); b[j]=1; } }

Trang 237

BT13-3. #include<stdio.h> #include<conio.h> #include<iostream.h> #include<stdlib.h> int nam; char a[11][6]={"","giap","at","binh","dinh","mau","ky","canh","tan","nham","quy "}; char b[13][6]={"hoi","ty'","suu","dan","mao","thin","ty.","ngo","mui","than","dau ","tuat","0"}; void main() { cin>>nam; nam-=3; cout<<a[nam%10]<<" "<<b[nam%12]; } BT13-8. #include <stdio.h> #include <math.h> #define fi "dagiac.inp" #define fo "dagiac.out" FILE *f; int n, kq[1001]; float chuvi[1001];

Bài tập lập trình căn bản – SGU2010

Trang 238

void read(); void process(); void write(); //----------------------void main() { read(); process(); write(); } //----------------------void read() { f=fopen(fi,"rt"); int sodinh; float x1, y1, x2, y2; fscanf(f,"%d",&n); for(int i=1; i<=n; i++) { fscanf(f,"%d%f%f",&sodinh,&x1,&y1); for(int j=1; j<sodinh; j++) { fscanf(f,"%f%f",&x2,&y2); chuvi[i]+=sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)); x1=x2; y1=y2; } } fclose(f); } //----------------------void process()

Bài tập lập trình căn bản – SGU2010 { for(int i=1; i<=n; i++) for(int j=1; j<=n; j++) if(chuvi[i]<chuvi[j]) kq[i]++; } //----------------------void write() { f=fopen(fo,"wt"); for(int i=1; i<=n; i++) fprintf(f,"%d\n",kq[i]); fclose(f); } BT13-9. #include <iostream.h> #include <conio.h> #include <stdio.h> #include <iomanip.h> #define N 20000 long a[N]; int n; FILE *f; void doc() { f=fopen("series.inp","rt"); fscanf(f,"%d",&n); for (int i=0;i<n;i++) fscanf(f,"%ld",&a[i]); fclose(f);

Trang 239

Bài tập lập trình căn bản – SGU2010 } void Swap(long &a,long &b) { long t=a; a=b; b=t; } void quicksort(long a[N],int l,int r) { long k=a[(l+r)/2]; int i=l; int j=r; do { while (a[i]<k) i++; while (a[j]>k) j--; if (i<=j) Swap(a[i++],a[j--]); } while (i<j); if (l<j) quicksort(a,l,j); if (i<r) quicksort(a,i,r); } void Process() { f=fopen("series.out","wt"); quicksort(a,0,n-1); long d=a[1]-a[0];

Trang 240

Bài tập lập trình căn bản – SGU2010 int i=1; while (a[i+1]-a[i]==d) i++; if (i!=n-1) fprintf(f,"%d",-1); else for (i=0;i<n;i++) fprintf(f,"%d\n",a[i]); fclose(f); } void main() { doc(); Process(); } BT13-10. #include <stdio.h> #define fi "chut.inp" #define fo "chut.out" FILE *f; int m, n, a[100][100], kq; void read(); void process(); void write(); int tren(int i, int j); int duoi(int i, int j); int trai(int i, int j); int phai(int i, int j); //----------------------void main() { read(); process();

Trang 241

Bài tập lập trình căn bản – SGU2010 write(); } //----------------------void read() { f=fopen(fi,"rt"); fscanf(f,"%d%d",&m,&n); int tmp; for(int i=1; i<=m; i++) for(int j=1; j<=n; j++) { fscanf(f,"%d",&tmp); a[i][j]=tmp; } fclose(f); } //----------------------void process() { for(int i=1; i<=m; i++) for(int j=i; j<=n; j++) if(a[i][j]==1) { if(tren(i,j)) kq++; if(duoi(i,j)) kq++; if(trai(i,j)) kq++; if(phai(i,j)) kq++;

Trang 242

Bài tập lập trình căn bản – SGU2010 }

Trang 243

} //----------------------int tren(int i, int j) { if(a[i][j+1]==1&&a[i][j+2]==1&a[i+1][j+1]==1&&a[i+2][j+1]= =1&&j+2<=n&&i+2<=m) return 1; return 0; } //----------------------int duoi(int i, int j) { if(a[i+1][j]==1&&a[i+2][j]==1&&a[i+2][j1]==1&&a[i+2][j+1]==1&&j+1<=n&&i+2<=m&&j-1>0) return 1; return 0; } //----------------------int trai(int i, int j) { if(a[i+1][j]==1&&a[i+2][j]==1&&a[i+1][j+1]==1&&a[i+1][j+2] ==1&&j+2<=n&&i+2<=m) return 1; return 0; } //----------------------int phai(int i, int j) { if(a[i+1][j]==1&&a[i+2][j]==1&&a[i+1][j-1]==1&&a[i+1][j2]==1&&i+2<=m&&j-2>0)

Bài tập lập trình căn bản – SGU2010 return 1; return 0; } //----------------------void write() { f=fopen(fo,"wt"); fprintf(f,"%d",kq); fclose(f); }

Trang 244

Bài tập lập trình căn bản – SGU2010

Trang 245

Một số đề thi mẫu
ĐỀ SỐ 1 Câu 1. #include <iostream.h> void main() { long n; cin>>n; int s=0; while (n>0) { s=s+n%10; n=n/10; } cout<<s; } Câu 2.1. int tudainhat(char *s) { int l=strlen(s); s[l]=' '; int max=0; int sokytu=0; for (int i=0;i<=l;i++) if (s[i]!=' ') sokytu++; else { if (sokytu>max) max=sokytu;

Bài tập lập trình căn bản – SGU2010 sokytu=0; } return max; } Câu 2.2. #include <conio.h> #include <iostream.h> #include <string.h> #include <stdio.h> void main() { char s[100]; gets(s); int l=strlen(s); int d[255]; for (int i=0;i<l;i++) d[s[i]]=0; for (i=0;i<l;i++) d[s[i]]++; for (i=0;i<l;i++) if (d[s[i]]!=0) { cout<<s[i]<<" xuat hien "<<d[s[i]]<<" lan" <<endl; d[s[i]]=0; } } Câu 3. #include <iostream.h> int uscln(int a, int b); int ktsoht(int n);

Trang 246

Bài tập lập trình căn bản – SGU2010 void main() { int a[100],n; cin>>n; for (int i=0; i<n;i++) cin>>a[i]; int min=a[0]; for (i=1; i<n;i++) if (a[i]<min) min=a[i]; cout<<"Gia tri nho nhat la: "<<min<<endl; int uc=a[0]; for (i=1;i<n;i++) uc=uscln(uc,a[i]); cout<<"Uoc so chung cua n so la: "<<uc<<endl; int ht=0; for (i=0;i<n;i++) if (ktsoht(a[i])) ht++; cout<<"So luong cac so hoan thien la: "<<ht<<endl; } int uscln(int a, int b) { int r=a%b; while (r!=0) { a=b; b=r; r=a%b; } return b;

Trang 247

Bài tập lập trình căn bản – SGU2010 } int ktsoht(int n) { int s=0; for (int i=1;i<n;i++) if (n%i==0) s=s+i; return (s==n); } ĐỀ SỐ 2. Câu 3. #include <conio.h> #include <math.h> #include <iostream.h> #include <stdio.h> int songaythang(int thang, int nam) { switch (thang) { case 1: case 3: case 5: case 7: case 8: case 10: case 12:return 31; case 4: case 6: case 9: case 11:return 30; case 2:if (nam %4==0 && nam %400!=0)

Trang 248

Bài tập lập trình căn bản – SGU2010 return 29; return 28; } } void ngaymai(int &ngay, int &thang, int &nam) { if (ngay<songaythang(thang,nam)) ngay++; else { ngay=1; thang++; if (thang>12) { thang=1; nam++; } } } void main() { clrscr(); int ngay,thang,nam; cin>>ngay>>thang>>nam; ngaymai(ngay,thang,nam); cout<<ngay<<" "<<thang<<" "<<nam; getch(); } ĐỀ SỐ 3. Câu 2.2.

Trang 249

Bài tập lập trình căn bản – SGU2010 #include <conio.h> #include <iostream.h> void nhap(int a[], int &n); int giatrithuk(int a[], int n,int k); void sapgiam(int a[], int n); void main() { clrscr(); int a[100],n,k; nhap(a,n); sapgiam(a,n); cout<<giatrithuk(a,n,k); getch(); } int giatrithuk(int a[], int n,int k) { cin>>k; if(k==1) return a[0]; int d=1; for (int i=0;i<n-1;i++) if (a[i]!=a[i+1]) { d++; if (d==k) return a[i+1]; } return 0; }

Trang 250

Bài tập lập trình căn bản – SGU2010 void sapgiam(int a[], int n) { for (int i=0;i<n-1;i++) for (int j=i+1;j<n;j++) if (a[i]<a[j]) { int temp=a[i];a[i]=a[j];a[j]=temp; } } void nhap(int a[], int &n) { cin>>n; for (int i=0;i<n;i++) cin>>a[i]; } ĐỀ SỐ 6. Câu 1. #include<iostream.h> int sodoixung(long n); void main() { for (long i=1;i<100000;i++) if (sodoixung(i)) cout<<i<<" "; } int sodoixung(long n) { if (n<10) return 1; if (n<100) return n%10==n/10; if (n<1000) return n%10==n/100;

Trang 251

Bài tập lập trình căn bản – SGU2010

Trang 252

if (n<10000) return (n%10==n/1000 && n%100/10 == n%1000/100); if (n<100000) return (n%10==n/10000 && n%100/10 == n%10000/1000); } ĐỀ SỐ 7. Câu 1. #include<stdio.h> #include<conio.h> #include<iostream.h> #include<stdlib.h> int songay(int thang, int nam); void main() { int ngay, thang, nam; cin>>ngay>>thang>>nam; int t=ngay; for (int i=1;i<thang;i++) t+=songay(i,nam); cout<<t; getch(); } int songay(int thang, int nam) { switch (thang) { case 1: case 3: case 5: case 7: case 8: case 10:

Bài tập lập trình căn bản – SGU2010 case 12:return 31; case 4: case 6: case 9: case 11:return 30; case 2:if (nam %4==0 && nam %400!=0) return 29; return 28; } } ĐỀ SỐ 11. Câu 1. #include<iostream.h> void main() { int n,tuso=0,mauso=0; float s=0; cin>>n; for (int i=1;i<=n;i++) { tuso=tuso+2*i; mauso=mauso+2*i+1; s=s+(float)tuso/mauso; } cout<<s; }

Trang 253

Bài tập lập trình căn bản – SGU2010 ĐỀ SỐ 13. Câu 1. #include<iostream.h> void main() { /* int s=0,i=0,m; cin>>m; while (s<=m) s=s+(2*i+++1); cout<<--i; */ int n=0,s=0,m,i=0; cin>>m; while (s<m) { if (i%2!=0) { s=s+i; n++; } i++; } cout<<n; } Câu 2. #include<iostream.h> int f(int n) ; int f1(int n) ; void main()

Trang 254

Bài tập lập trình căn bản – SGU2010 { cout<<f1(9); } int f(int n) { if (n==0) return 0; if (n==1) return 1; if (n==2) return 1; return 3*f(n-3)+2*f(n-2)+f(n-1); } int f1(int n) { int u0=0, u1=1, u2=1,f; int i=3; while (i<=n) { f=3*u0+2*u1+u2; u0=u1; u1=u2; u2=f; i++; } return f; } Câu 3 #include<conio.h> #include<iostream.h> void main() { clrscr();

Trang 255

Bài tập lập trình căn bản – SGU2010 int a[100],n; cin>>n; for (int i=0;i<n;i++) cin>>a[i]; for (i=0;i<n-1;i++) for (int j=i+1;j<n;j++) if (a[i]<a[j]) { int temp=a[i];a[i]=a[j];a[j]=temp; } int k; cin>>k; int d=0; a[n]=a[n-1]-1; for (i=0;i<n;i++) if (a[i]!=a[i+1]) { d++; cout<<a[i]<<" "; if (d==k) break; } getch(); } ĐỀ SỐ 14. Câu 3.2. #include <iostream.h> const maxm=20, maxn=20; void nhapmang(int a[maxm][maxn], int &n); void xuatmang(int a[maxm][maxn], int n); void hoanvi(int &a, int &b); int vitrigtlndong(int a[maxm][maxn], int n, int k);

Trang 256

Bài tập lập trình căn bản – SGU2010 void biendoimang(int a[maxm][maxn], int n); void main() { int a[maxm][maxn],n; nhapmang(a,n); biendoimang(a,n); xuatmang(a,n); } void nhapmang(int a[maxm][maxn], int &n) { cout<<"Nhap vao n = ";cin>>n; for (int i=0;i<n;i++) for (int j=0;j<n;j++) cin>>a[i][j]; } void xuatmang(int a[maxm][maxn], int n) { for (int i=0;i<n;i++) { for (int j=0;j<n;j++) cout<<a[i][j]<<" "; cout<<endl; } } void hoanvi(int &a, int &b) { int temp=a; a=b; b=temp; }

Trang 257

Bài tập lập trình căn bản – SGU2010

Trang 258

int vitrigtlndong(int a[maxm][maxn], int n, int k) { int maxdong=a[k][0],vitri=0; for (int i=1;i<n;i++) if (a[k][i]>maxdong) { maxdong=a[k][i]; vitri=i; } return vitri; } void biendoimang(int a[maxm][maxn], int n) { for (int i=0;i<n;i++) hoanvi(a[i][i],a[i][vitrigtlndong(a,n,i)]); } ĐỀ SỐ 15. Câu 1. #include<iostream.h> #include<math.h> int amstrong(int n); void main() { for (int i=1;i<10000;i++) if (amstrong(i)) cout<<i<<" "; } int amstrong(int n)

Bài tập lập trình căn bản – SGU2010

Trang 259

{ if (n<10) return n; if (n<100) return n==pow(n/10,2)+pow(n%10,2); if (n<1000) return n==pow(n/100,3)+pow(n%100/10,3)+pow(n%10,3); if (n<10000) return n==pow(n/1000,4)+pow(n%1000/100,4)+pow(n%100/10,4)+pow(n%10,4); } Câu 2. #include<stdio.h> #include<iostream.h> #include<stdlib.h> int ngay, thang, nam; int demngay(int thang) { if (thang==1||thang==3||thang==5||thang==7||thang==8||thang==10||thang= =12) return 31; if (thang==2) return 28; return 30; }

void main() { thang=1; ngay=1; cout<<"cac ngay thu sau cuoi thang nam 2010:"<<endl; while (thang<=12)

Bài tập lập trình căn bản – SGU2010 { if (ngay>demngay(thang)) { cout<<ngay-7<<"/"<<thang<<endl; ngay-=demngay(thang); thang+=1; } ngay+=7; } } Câu 3. #include<iostream.h> #include<values.h> void nhap(int a[], int &n); int somangconlientiep(int a[], int n); int mangtangdainhat(int a[], int n); void main() { int a[100],n; nhap(a,n); cout<<somangconlientiep(a,n); cout<<mangtangdainhat(a,n); } int somangconlientiep(int a[], int n) { int dem=1; for (int i=0;i<n-1;i++) if (a[i]>a[i+1]) dem++;

Trang 260

Bài tập lập trình căn bản – SGU2010 return dem; } int mangtangdainhat(int a[], int n) { int dem=1, max=0; for (int i=0;i<n-1;i++) { if (a[i]>a[i+1]) { if (dem>max) max=dem; dem=1; } else dem++; } return dem>max?dem:max; } void nhap(int a[], int &n) { cin>>n; for (int i=0;i<n;i++) cin>>a[i]; } ĐỀ SỐ 16 Câu 2. #include<conio.h> #include<string.h> #include<stdio.h> #include<iostream.h>

Trang 261

Bài tập lập trình căn bản – SGU2010 int demtukkytu(char *s, int k); int tudainhat(char *s); void main() { clrscr(); char *s; gets(s); int b[8]; for (int i=1;i<=7;i++) b[i]=0; for (i=1;i<=7;i++) b[i]=demtukkytu(s,i); int max=0; for (i=1;i<=7;i++) if (b[i]>max) max=b[i]; for (i=1;i<=7;i++) if (b[i]==max) cout<<i<<" "; getch(); } //Dem tu co k ky tu int demtukkytu(char *s, int k) { int l=strlen(s); s[l]=' '; int dem=0; int sokytu=0; for (int i=0;i<=l;i++) if (s[i]!=' ') sokytu++; else

Trang 262

Bài tập lập trình căn bản – SGU2010 { if (sokytu==k) dem++; sokytu=0; } return dem; } Câu 3. #include<iostream.h> struct hv { int so1; int so2; int so3; int so4; }; #define maxn 20 void nhapmanga(hv a[maxn][maxn], int &n); void timmangb(hv a[maxn][maxn], int n); void vitritoanchan(hv a[maxn][maxn], int n); int kiemtra4sochan(hv a[maxn][maxn],int i,int j); int tong4so(hv a[maxn][maxn],int i,int j); void main() { hv a[maxn][maxn]; int n; nhapmanga(a,n); timmangb(a,n); vitritoanchan(a,n); }

Trang 263

Bài tập lập trình căn bản – SGU2010 void nhapmanga(hv a[maxn][maxn], int &n) { cout<<"Nhap vao so n = ";cin>>n; for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) cin>>a[i][j].so1>>a[i][j].so2>>a[i][j].so3>>a[i][j].so4; } void timmangb(hv a[maxn][maxn], int n) { int b[maxn][maxn]; // Tinh mang b for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) b[i][j]=tong4so(a,i,j); // Xuat mang b for (i=1;i<=n;i++) { for (int j=1;j<=n;j++) cout<<b[i][j]<<" "; cout<<endl; } } void vitritoanchan(hv a[maxn][maxn], int n) { int max=0; int x=1,y=1; for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) if (kiemtra4sochan(a,i,j) && tong4so(a,i,j)>max ) { max=tong4so(a,i,j);

Trang 264

Bài tập lập trình căn bản – SGU2010 x=i; y=j; } if (max==0) cout<<0; else cout<<endl<<x<<","<<y; } int kiemtra4sochan(hv a[maxn][maxn],int i,int j) { if (a[i][j].so1%2!=0) return 0; if (a[i][j].so2%2!=0) return 0; if (a[i][j].so3%2!=0) return 0; if (a[i][j].so4%2!=0) return 0; return 1; } int tong4so(hv a[maxn][maxn],int i,int j) { return a[i][j].so1+a[i][j].so2+a[i][j].so3+a[i][j].so4; } ĐỀ SỐ 17 Câu 2. #include<iostream.h> int tinhyn(int n); int tinhyn1(int n); void main() { cout<<tinhyn1(5); } int tinhyn(int n) { if (n<=3) return n;

Trang 265

Bài tập lập trình căn bản – SGU2010 return tinhyn(n-1)*(5*tinhyn(n-2)+6*tinhyn(n-3)); } int tinhyn1(int n) { int y1=1,y2=2,y3=3,yn=n; for (int i=4;i<=n;i++) { yn=y3*(5*y2+6*y1); y1=y2; y2=y3; y3=yn; } return yn; } ĐỀ SỐ 18 Câu 3. #include<iostream.h> void main() { for (long x=1;x<10000;x++) for (long y=1;y<10000;y++) for (long z=1;z<10000;z++) if (x*x+ y*y==z*z) cout<<x<<" "<<y<<" "<<z<<endl; } Câu 3. #include<iostream.h> void main() { int a[100],d[100],n;

Trang 266

Bài tập lập trình căn bản – SGU2010 cout<<"Nhap vao so n = ";cin>>n; cout<<"Nhap vao 1 hoan vi cua n phan tu : \n" ; for (int i=1;i<=n;i++) cin>>a[i]; for (i=1;i<=n;i++) { d[i]=0; for (int j=1;j<=n;j++) if (a[j]==i) for (int k=1;k<j;k++) if (a[k]>a[j]) d[i]++; cout<<d[i]<<" "; } } ĐỀ SỐ 20 Câu 1. #include<iostream.h> #include<math.h> void main() { float xa,ya,xb,yb,xc,yc; cin>>xa>>ya; cin>>xb>>yb; cin>>xc>>yc; float xtdbc=(xb+xc)/2.0; float ytdbc=(yb+yc)/2.0; float xd=2*xtdbc-xa; float yd=2*ytdbc-ya; float kc=fabs((yd-yb)*xa+(xb-xd)*ya+xd*yb-xb*yd)/ sqrt(pow(yd-yb,2)+pow(xb-xd,2));

Trang 267

Bài tập lập trình căn bản – SGU2010 cout<<"Toa do diem D la : "<<xd<<","<<yd<<endl; cout<<"Khoang cach giua AC va BD la : "<<kc; }

Trang 268

Câu 2. #include <iostream.h> #include <math.h> long f(long x, long y, long z); void main() { long A,B; cout<<"Nhap vao 2 so nguyen A,B: "; cin>>A>>B; long max; long nghiemx,nghiemy,nghiemz; for (long x=0;x<=A;x++) for (long y=0;y<=A/2;y++) for (long z=0;z<=A/3;z++) if (x*x+2*y*y+3*z*z<=A*A && y*y+z*z<=B*B && f(x,y,z)>max) { max=f(x,y,z); nghiemx=x; nghiemy=y; nghiemz=z; } cout<<"Gia tri lon nhat cua bieu thuc f la : "<<max<<endl; cout<<"Tai cac gia tri x,y,z la: "<<nghiemx<<","<<nghiemy<<","<<nghiemz; } long f(long x, long y, long z) { return pow(x,2)+pow(y,4)+pow(z,8);

Bài tập lập trình căn bản – SGU2010 } Câu 2. #include <stdio.h> #include <conio.h> #include <iostream.h> void nhap(int a[], int &n) { cin>>n; for (int i=0;i<n;i++) cin>>a[i]; } int dembit1(int n) { int count=0; while (n>0){ if (n%2==1) count++; n/=2; }; return count; } int demsobitle(int a[], int n) { int count=0; for (int i=0;i<n; i++) if (dembit1(a[i]%2==1)) count++; return count; }

Trang 269

Bài tập lập trình căn bản – SGU2010 void main() { int a[1000],n; nhap(a,n); cout<<demsobitle(a,n); }

Trang 270

Bài tập lập trình căn bản – SGU2010 PHỤ LỤC

Trang 271

Phụ lục A.

Một số lệnh liên quan đến màn hình thường dùng
1.Tọa độ màn hình
Hệ toạ độ trên màn hình nhận điểm ở gốc trên bên trái làm điểm gốc, trục hoành là trục nằm ngang chạy từ trái sang phải, trục tung là trục thẳng đứng từ trên xuống dưới. Các tọa độ màn hình thường được ký kiệu là x và y, với x là chỉ số cột; còn y chỉ số hàng. Góc trái bên trên của màn hình có tọa độ (1:1); góc phải bên dưới có tọa độ (80:25) – giới hạn này tùy thuộc lại màn hình. Ta có thể di chuyển con trỏ tới một vị trí mới trên màn hình bằng lệnh gotoxy(x,y).

2.Giá trị bảng màu
BLACK = 0 BLUE = 1 GREEN = 2 CYAN = 3 RED = 4 MAGENTA = 5 BROWN = 6 LIGHTGRAY = 7 DARKGRAY = 8 LIGHTBLUE = 9 LIGHTGREEN = 10 LIGHTCYAN = 11 LIGHTRED = 12 LIGHTMAGENTA = 13 YELLOW = 14 WHITE = 15 BLINK = 128 Cách ghi giá trị màu là chuỗi in hoa như trên hay số tương ứng là tương đương.

Bài tập lập trình căn bản – SGU2010

Trang 272

3.Một số lệnh liên quan đến màn hình
void textbackground (int color); Đặt màu nền void textcolor (int color); Đặt màu chữ void gotoxy(int x, int y); Di chuyển con trỏ trong phạm vi cửa sổ

Bài tập lập trình căn bản – SGU2010

Trang 273

Phụ lục B

Một số hàm chuẩn thường sử dụng
stdio.h void putchar (char c); Xuất ký tự void getchar (char c); Nhập ký tự void puts(char *s); Xuất chuỗi void gets(char *s); Nhập chuỗi void fflush(stdin); Xoá vùng đệm bàn phím conio.h void clrscr(); Xoá màn hình void gotoxy(int x, int y); Đưa điểm nháy đến toạ độ x,y trên màn hình void textcolor(int color) Đặt màu chữ mới void textbackground(int color) Đặt màu nền mới void getch(); Nhập ký tự( không hiện ra màn hình) void getche(); Nhập ký tự(có hiện ra màn hình) stdlib.h void randomize(); Khởi động cơ chế tạo số ngẫu nhiên void random(int n) Trả về số nguyên trong khoảng 0 đến n-1.

Bài tập lập trình căn bản – SGU2010

Trang 274

unsigned int rand(); Cho một giá trị ngẫu nhiên trong khoảng 1.. 32767 void flushall(); Xoá vùng đệm bàn phím, lệnh này thường được sử dụng trước các lệnh nhập liệu như gets hoặc scanf math.h double sqrt(double x) ; Căn bậc hai double exp(double x) ; Tính ex double pow(double x, double y); Tính xy int abs(int x) ; Trị tuyệt đối của kiểu số int double fabs(double x) ; Trị tuyệt đối của kiểu số float,double long int labs(long int x) ; Trị tuyệt đối của kiểu số long double ceil(double x) ; Làm tròn số lên (đối với số thực) double floor(double x) ; Làm tròn số xuống(đối với số thực) double log(double x) ; Tính logarit tụ nhiên của x double sin(double x) ; Tính sin của x double cos(double x) ; Tính cos của x double tan(double x) ; Tính tg của x asin,acos,atan

Bài tập lập trình căn bản – SGU2010

Trang 275

Các hàm lượng giác ngược (tham số các hàm lượng giác là radian) dos.h void gettime(struct time *t) Hàm nhận giờ hệ thống và đặt vào các thành phần của một biến cấu trúc time do con trỏ t trỏ tới. Kiểu cấu trúc time được định nghĩa sẳn như sau: struct time { unsigned ti_hour; unsigned ti_min; unsigned ti_sec; unsigned ti_hund; }; void settime(struct time *t); Hàm đặt lại giờ hệ thống theo giá trị các thành phần của một biến cấu trúc kiểu time do con trỏ t trỏ tới. long time(long *t); Hàm cho thời gian hiện tại theo giây bắt đầu tính từ 0 giờ 0 phút 0 giây (giờ GMT) ngày 1 tháng 1 năm 1970. void getdate(struct date *d); Kiểu cấu trúc date được định nghĩa sẳn như sau: struct date { int da_year; char da_mon; char da_day; }; void setdate (struct date *d); Hàm đặt lại ngày hệ thống theo giá trị các thành phần của một biến cấu trúc kiểu date do con trỏ d trỏ tới. ctype.h int isalnum(int c);

Bài tập lập trình căn bản – SGU2010

Trang 276

Kiểm tra c là ký tự (chữ cái hoặc chữ số) hay không ? int isalpha(int c); Kiểm tra c là chữ cái hay không ? int isdigit(int c); Kiểm tra c là chữ số hay không ? int isalower (int ct); Kiểm tra c là chữ cái thường hay không ? isupper(int c); Kiểm tra c là chữ cái hoa hay không ? int isspace(int c); Kiểm tra xem ký tự c là ký tự trống ? int tolower(int c); Chuyển ký tự c thành chữ thường int toupper(int c); Chuyển ký tự c thành chữ hoa. int toascii(int c); Chuyển ký tự c thành mã ASCII

Bảng mã ASCII
Bộ mã ASCII gồm 256 ký tự được phân bố như sau: -32 ký tự đầu tiên là các ký tự điều khiển không in được như ký tự enter (mã 13), ký tự ESC (mã 27), 32 là ký tự khoảng trắng. -Các mã ASCII 33-47,58-64,91-96 và 123-127 là các ký tự đặc biệt như dấu chấm, dấu phẩy, dấu cách, dấu ngoặc, dấu móc, dấu hỏi,… -Các mã ASCII 48-57 là 10 chữ số. -Các mã ASCII 65-90 là các chữ cái hoa từ A đến Z. -Các mã ASCII 97-122 là các chữ cái thường từ a đến z. -Các mã ASCII 128-255 là các ký tự đồ họa. string.h char *gets(char * str);

Bài tập lập trình căn bản – SGU2010

Trang 277

Chờ nhập vào từ bàn phím chuỗi ký tự, hàm trả về con trỏ trỏ tới địa chỉ đầu chuỗi str. Chú ý rằng để đảm bảo bộ đệm bàn phím được làm rỗng trước khi nhập dữ liệu chuỗi, chúng ta nên sử dụng hàm fflush(stdin). char *puts (char * str); Xuất chuỗi str lên màn hình. unsigned *strlen(const char *str); Xác định chiều dài của chuỗi str. char* strcpy(char *dest, const char * src); Sao chép nội dung trong src vào trong dest. Hàm trả về con trỏ trỏ tới địa chỉ đầu của chuỗi đích (con trỏ dest) int strcmp(char *s1, char *s2); (so sánh có phân biệt chữ hoa và chữ thường) Trả về kết quả so sánh hai chuỗi s1 và s2. Nếu giá trị trả về > 0 thì chuỗi s1 chứa chuỗi s1 Nếu giá trị trả về < 0 thì chuỗi s2 chứa chuỗi s1 Nếu giá trị trả về = 0 thì chuỗi s2 giống chuỗi s1 int stricmp(char *s1, char *s2); (so sánh không phân biệt chữ hoa và chữ thường) char * strrev(char *st); Đảo ngược các kỹ tự trong chuỗi st, hàm trả về con trỏ st. strlwr(char *s); Đổi chuỗi s thành chữ thường. strupr(char *s); Đổi chuỗi s thành chữ hoa. strcat(char *s1, char *s2); Ghép chuỗi s2 vào sau chuỗi s1. strchr(char *s,char c); Tìm ký tự c trong chuỗi s, không có trả về NULL. strrchr(char *s,char c); Giống hàm trên nhưng bắt đầu tìm từ bên phải. strstr(char *s1, char *s2);

Bài tập lập trình căn bản – SGU2010

Trang 278

Tìm chuỗi s2 trong chuỗi s1 trả về vị trí chuỗi s2 trong chuỗi s1. int atoi(char *s); Đổi chuỗi s thành số kiểu int. int atol(char *s); Đổi chuỗi s thành số kiểu long. int atof(char *s); Đổi chuỗi s thành số kiểu float. void flushall(); Xoá vùng đệm bàn phím, lệnh này thường được sử dụng trước các lệnh nhập liệu như gets hoặc scanf.

Bài tập lập trình căn bản – SGU2010

Trang 279

Phụ lục C

Chuyển đổi C/C++ sang C#
1. Giới thiệu C# -C# là ngôn ngữ lập trình do Microsoft công bố vào tháng 7 năm 2000 làm việc trên nền tảng .NET. Ngôn ngữ C# có các đặc trưng giống C/C++, Java và là ngôn ngữ lập trình hướng đối tượng. 2. Cơ bản về C# - Ngôn ngữ C# phân biệt chữ hoa thường và tất cả các lệnh đều kết thúc bằng dấu chấm phẩy (;). STT 1 2 3 4 5 6 7 LỆNH Ký hiệu bắt đầu Ký hiệu kết thúc Chỉ thị tiền xử (preprocessor directive) Lớp đối tượng Lệnh nhập Lệnh xuất Lệnh gán lý C/C++ { } #include class scanf, cin printf, cout = C# { } using class Console.ReadLine Console.WriteLine =

- Các phép toán : + , - , * , / , % (tương tự C/C++) - Toán tử so sánh: < , > , >= , <= , == , != (tương tự C/C++ ) - Toán tử logic : ! , && , || (tương tự C/C++) - Các kiểu dữ liệu cơ bản: + Kiểu số nguyên, số nguyên dài, số thực, luận lý (int, long, float, bool) (tương tự C/C++) + Kiểu chuỗi: string (C/C++: char*, char[]) + Hàm chuyển đổi kiểu dữ liệu: · Từ chuỗi sang số: <KiểuDữLiệu>.Parse(<Chuỗi>) Ví dụ: string s = “123”; int n = int.Parse(s);

Bài tập lập trình căn bản – SGU2010 · Từ số sang chuỗi: <TênBiến>.ToString() Ví dụ: int n = 123; string s = n.ToString();

Trang 280

3. Cấu trúc rẽ nhánh - Có 3 dạng tương tự C/C++: if, if…else, switch…case… 4. Cấu trúc lặp - Có 3 dạng tương tự C/C++: for, while, do…while - Ngoài ra, còn có cấu trúc lặp khác foreach 5. Hàm - Tham trị : giống C/C++ - Tham biến: dùng từ khoá ref (C/C++: &) 6. Mảng - Khai báo: <KiểuDữLiệu> []<TênBiến> = new <KiểuDữLiệu>[<HằngSố>]; KiểuDữLiệu: là kiểu dữ liệu của 1 phần tử trong mảng. HằngSố: là một số nguyên dương chỉ số lượng tối đa có thể có trên một chiều trong mảng. - Ví dụ: Mảng một chiều các số nguyên a có tối đa 50 phần tử int []a = new int[50]; - Cách duyệt mảng và truy xuất các phần tử trong mảng tương tự C/C++ 7. Ví dụ Viết chương trình nhập vào số nguyên dương n. Hãy tính S = 1 + 2 + … + n C/C++ #include "stdio.h" #include "conio.h" void main () { int n; int S; printf ("Nhap so nguyen n: "); scanf ("%d", &n);

Bài tập lập trình căn bản – SGU2010 S = 0; for (int i = 1; i <= n; i++) S = S + i; printf ("S = %d", S); getch(); } C# using System; using System.Collections.Generic; using System.Text; namespace ConsoleApplication { class Program { static void Main(string[] args) { int n; int S; string chuoi; Console.Write("Nhap so nguyen n:"); chuoi = Console.ReadLine(); //chuyen tu chuoi sang so n = int.Parse(chuoi); S = 0; for (int i = 1; i <= n; i++) S = S + i; Console.Write("S = {0}", S); Console.ReadLine(); } }

Trang 281

Bài tập lập trình căn bản – SGU2010

Trang 282

Tài liệu tham khảo
[1]Kỹ thuật lập trình C - Cơ sở và nâng cao Phạm văn Ất, Nhà xuất bản khoa học kỹ thuật, 2007. [2]Những viên ngọc trong kỹ thuật lập trình John Bentley. [3]Bộ đề thi môn Cơ sở lập trình dành cho các lớp đại học Khoa Công nghệ thông tin, trường Đại học Sài Gòn. [4]Bộ đề thi OLYMPIC Tin học sinh viên Việt Nam (Trích một số đề thi khối cao đẳng và khối không chuyên các năm 2004-2009) - Hội tin học Việt Nam. [5]Bài tập kỹ thuật lập trình tập 1 Nguyễn Tấn Trần Minh Khang, 2003. [6]Bộ đề thi hoàn chỉnh đại học môn Kỹ thuật lập trình Đại học Khoa học tự nhiên, ĐHQG TPHCM

Bài tập lập trình căn bản – SGU2010

Trang 283

Mục lục
Trang 01 02 18 28 37 45 55 64 75 86 95 102 121 140 146 166 271 283

Chương 1: Chương 2: Chương 3: Chương 4: Chương 5: Chương 6: Chương 7: Chương 8: Chương 9: Chương 10: Chương 11: Chương 12:

Lời giới thiệu Thuật toán Mở đầu về ngôn ngữ lập trình C/C++ Các cấu trúc rẽ nhánh Các cấu trúc lặp Chương trình con Kỹ thuật lập trình đệ quy Mảng một chiều Mảng nhiều chiều Con trỏ Chuỗi Kiểu cấu trúc File dữ liệu Bài tập nâng cao Một số đề thi mẫu Gợi ý và hướng dẫn giải bài tập Phụ lục Tài liệu tham khảo

You're Reading a Free Preview

Tải về
scribd
/*********** DO NOT ALTER ANYTHING BELOW THIS LINE ! ************/ var s_code=s.t();if(s_code)document.write(s_code)//-->