Việc giảng dạy các thuật toán cơ bản và kỹ thuật lập trình hiệu quả đóng vai trò then chốt trong việc nâng cao chất lượng giáo dục và đào tạo học sinh giỏi.. Để hệ thống lại các chuyên đ
Trang 11 MỞ ĐẦU 1.1 Lí do chọn đề tài
Trong thời đại công nghệ số phát triển nhanh chóng như hiện nay, kỹ năng lập trình và tư duy thuật toán ngày càng trở nên quan trọng đối với học sinh Môn Tin học không chỉ giúp học sinh tiếp cận với công nghệ mới mà còn phát triển tư duy logic, khả năng giải quyết vấn đề và sáng tạo Việc giảng dạy các thuật toán cơ bản và kỹ thuật lập trình hiệu quả đóng vai trò then chốt trong việc nâng cao chất lượng giáo dục và đào tạo học sinh giỏi
Trong các kỳ thi học sinh giỏi Tin học, nhiều bài toán yêu cầu học sinh phải đếm số lượng dãy con, tìm kiếm các cặp phần tử thỏa mãn điều kiện, và nhiều dạng bài toán đếm khác Để giải quyết các bài toán này một cách hiệu quả, thuật toán lùa bò vào chuồng (hay còn gọi là kỹ thuật hai con trỏ) là một công cụ mạnh mẽ và cần thiết Tuy nhiên, nhiều học sinh vẫn gặp khó khăn trong việc hiểu và áp dụng thuật toán này vào thực tế
Đề tài này không chỉ giúp học sinh nắm vững kỹ thuật thuật toán mà còn phát triển tư duy logic và khả năng giải quyết vấn đề, từ đó nâng cao kết quả học tập và chất lượng giảng dạy môn Tin học cho học sinh THPT Đặc biệt là trong bồi dưỡng học sinh giỏi, yêu cầu giáo viên phải có phương pháp và kỹ thuật phù hợp để giúp học sinh phát triển tư duy lập trình và giải quyết vấn đề Thuật toán lùa bò vào chuồng (hay còn gọi là kỹ thuật hai con trỏ) là một trong những thuật toán hiệu quả, giúp giải quyết nhiều bài toán đếm phức tạp Đề tài này sẽ trình bày chi tiết cách sử dụng thuật toán này, từ cơ sở lý thuyết đến các bài toán ứng dụng trong việc đếm các dãy con thỏa mãn điều kiện cho trước
Từ thực tiễn giảng dạy học sinh đại trà cũng như học sinh đội tuyển học sinh giỏi Tin học của trường THPT, tôi thấy rằng học sinh gặp khó khăn khi chuyển lời giải các bài toán từ toán sang ngôn ngữ lập trình Đặc biệt là việc phân tích bài toán, nhận biết bài toán đó có thể giải quyết bằng phương pháp nào
và lời giải có tối ưu hay không Để hệ thống lại các chuyên đề bồi dưỡng học sinh giỏi Tin học mà tôi đã dạy trong nhiều năm qua, đồng thời qua quá trình nghiên cứu, giảng dạy, tham khảo ý kiến đồng nghiệp, tôi mạnh dạn chọn đề tài:
“Sử dụng thuật toán lùa bò vào chuồng để giải quyết các bài toán đếm trong bồi dưỡng học sinh giỏi môn Tin ở trường phổ thông ” góp phần nâng cao chất lượng học tập của học sinh và kết quả cho học sinh giỏi
1.2 Mục đích nghiên cứu
Mục đích của việc nghiên cứu và áp dụng thuật toán lùa bò vào chuồng trong giảng dạy môn Tin học là để nâng cao chất lượng giáo dục, phát triển kỹ năng và tư duy cho học sinh, chuẩn bị cho các kỳ thi học sinh giỏi, xây dựng nền tảng kiến thức vững chắc và khơi dậy niềm đam mê học tập Những mục đích này không chỉ giúp cải thiện kết quả học tập trước mắt mà còn góp phần định hướng và phát triển lâu dài cho học sinh trong lĩnh vực Tin học và các ngành nghề liên quan Bằng cách áp dụng một thuật toán cụ thể và hiệu quả, giáo viên
có thể giúp học sinh tiếp thu kiến thức nhanh chóng và chính xác hơn Điều này làm tăng hiệu quả giảng dạy và giảm bớt gánh nặng cho giáo viên trong việc giải thích và minh họa các khái niệm khó, cải thiện hiệu quả giảng dạy
Trang 2Tăng cường kỹ năng lập trình cho học sinh, thuật toán lùa bò vào chuồng, với tính ứng dụng cao trong các bài toán đếm, sẽ giúp học sinh thực hành lập trình một cách thường xuyên và hiệu quả, qua đó nâng cao kỹ năng lập trình và khả năng giải quyết vấn đề nhằm phát triển tư duy thuật toán và tư duy logic cho học sinh Thuật toán lùa bò vào chuồng là một trong những kỹ thuật phổ biến và quan trọng trong các kỳ thi Tin học Việc nắm vững và thành thạo thuật toán này
sẽ giúp học sinh tự tin hơn và đạt kết quả cao hơn trong các kỳ thi học sinh giỏi các cấp Điều này rất quan trọng cho sự phát triển lâu dài và khả năng tiếp cận các kiến thức cao hơn trong tương lai
1.3 Đối tượng nghiên cứu
Đối tượng nghiên cứu của sáng kiến này là các em học sinh học môn Tin học, các em HSG môn Tin học, giáo viên và chương trình học môn Tin học tại trường PT Nguyễn Mộng Tuân Mục tiêu của sáng kiến là nâng cao chất lượng giảng dạy và học tập, phát triển kỹ năng và tư duy của học sinh, đồng thời cung cấp các phương pháp giảng dạy hiệu quả cho giáo viên Việc định rõ đối tượng nghiên cứu giúp sáng kiến tập trung vào những nhu cầu cụ thể và thiết thực, từ
đó mang lại những kết quả tích cực và cải thiện toàn diện chất lượng giáo dục môn Tin học trong nhà trường.
1.4 Phương pháp nghiên cứu
Để đạt được các mục tiêu của sáng kiến sử dụng thuật toán lùa bò vào chuồng để giải các bài toán đếm trong bồi dưỡng học sinh giỏi môn Tin học, chúng tôi áp dụng một số phương pháp nghiên cứu sau đây:
1.4.1 Nghiên cứu tài liệu
- Thu thập và nghiên cứu các tài liệu liên quan đến thuật toán lùa bò vào
chuồng, bao gồm sách giáo khoa, sách tham khảo, bài báo khoa học, và các tài liệu trên Internet Từ đó, xây dựng nền tảng kiến thức vững chắc về thuật toán
- Phân tích các tài liệu để hiểu rõ nguyên lý, cách triển khai và ứng dụng của thuật toán lùa bò vào chuồng Tổng hợp các kiến thức quan trọng và có giá trị để làm cơ sở cho việc xây dựng giáo án và bài tập
1.4.2 Thiết kế giáo án và tài liệu giảng dạy
- Xây dựng giáo án chi tiết: Dựa trên kiến thức thu thập được, thiết kế giáo án chi tiết về thuật toán lùa bò vào chuồng, bao gồm lý thuyết, ví dụ minh họa và bài tập thực hành Giáo án cần được thiết kế sao cho phù hợp với trình độ
và nhu cầu của học sinh
- Tạo bài thực hành: Xây dựng bộ bài tập từ cơ bản đến nâng cao, giúp học sinh luyện tập và củng cố kiến thức Các bài tập cần đa dạng về mức độ khó
và phong phú về nội dung để học sinh có thể áp dụng thuật toán vào nhiều bài toán khác nhau.
1.4.3 Thực nghiệm giảng dạy
- Giảng dạy thử nghiệm: Tiến hành giảng dạy thử nghiệm cho các nhóm
học sinh khác nhau để đánh giá hiệu quả của giáo án và bài tập Qua quá trình giảng dạy, thu thập phản hồi từ học sinh để điều chỉnh và hoàn thiện giáo án
Trang 3- Quan sát, ghi chép: Quan sát quá trình học tập của học sinh, ghi chép lại những khó khăn và thuận lợi mà học sinh gặp phải khi áp dụng thuật toán Từ
đó, tìm ra các phương pháp giải quyết và cải tiến cách giảng dạy
- Phương pháp nghiên cứu của sáng kiến này bao gồm việc nghiên cứu tài liệu, thiết kế giáo án và tài liệu giảng dạy, thực nghiệm giảng dạy, đánh giá, phân tích kết quả và ứng dụng công nghệ thông tin Sự kết hợp của các phương pháp này nhằm đảm bảo sáng kiến được triển khai một cách khoa học, hiệu quả
và mang lại kết quả tích cực trong giảng dạy và học tập môn Tin học tại trường
PT Nguyễn Mộng Tuân
1.4.4 Đánh giá và phân tích kết quả
- Đánh giá kết quả học tập: Sử dụng các bài kiểm tra, bài thi và bài tập thực hành để đánh giá kết quả học tập của học sinh So sánh kết quả trước và sau khi áp dụng sáng kiến để đánh giá hiệu quả của phương pháp giảng dạy
- Phân tích phản hồi: Thu thập và phân tích phản hồi từ học sinh và giáo viên để đánh giá mức độ hài lòng và hiệu quả của sáng kiến Dựa trên phản hồi này, điều chỉnh và cải tiến phương pháp giảng dạy
1.4.5 Ứng dụng công nghệ thông tin
- Sử dụng phần mềm hỗ trợ: Sử dụng các phần mềm lập trình và mô phỏng để minh họa thuật toán lùa bò vào chuồng Các phần mềm này giúp học sinh dễ dàng hình dung và hiểu rõ cách hoạt động của thuật toán
- Phát triển tài liệu trực tuyến: Xây dựng các tài liệu giảng dạy trực tuyến,
bao gồm video hướng dẫn, bài giảng điện tử và hệ thống bài tập trực tuyến Học sinh có thể truy cập và học tập mọi lúc, mọi nơi, nâng cao tính linh hoạt và hiệu quả học tập
2 NỘI DUNG SÁNG KIẾN KINH NGHIỆM 2.1 Cơ sở lí luận của sáng kiến kinh nghiệm
Cơ sở lý luận của sáng kiến sử dụng thuật toán lùa bò vào chuồng để giải các bài toán đếm trong bồi dưỡng học sinh giỏi môn Tin học tại trường PT Nguyễn Mộng Tuân dựa trên những khái niệm và lý thuyết nền tảng trong các lĩnh vực sau:
2.1.1 Thuật toán lùa bò vào chuồng (Two-pointer Technique)
- Khái niệm và nguyên lý: Thuật toán lùa bò vào chuồng, hay còn gọi là
kỹ thuật hai con trỏ (two-pointer technique), là một phương pháp tối ưu để giải quyết các bài toán liên quan đến việc duyệt và xử lý các dãy số hoặc chuỗi ký tự
Kỹ thuật này sử dụng hai con trỏ (hoặc nhiều hơn) để di chuyển qua các phần tử của dãy, giúp tiết kiệm thời gian và không gian so với các phương pháp duyệt truyền thống
- Ưu điểm: Thuật toán lùa bò vào chuồng có độ phức tạp thấp hơn so với
nhiều thuật toán khác, thường là O(n) thay vì O(n^2) Điều này làm cho nó trở thành một công cụ mạnh mẽ trong việc giải các bài toán đếm, đặc biệt là khi cần
xử lý các tập dữ liệu lớn
Trang 4- Ứng dụng: Thuật toán này được sử dụng rộng rãi trong các bài toán tìm
kiếm các cặp phần tử thỏa mãn điều kiện cho trước, đếm số đoạn con có tính chất đặc biệt, và nhiều bài toán khác trong lĩnh vực Tin học và thuật toán
2.1.2 Phương pháp giảng dạy Tin học
- Giảng dạy thuật toán: Việc giảng dạy thuật toán không chỉ tập trung vào
lý thuyết mà còn cần thực hành nhiều để học sinh hiểu và áp dụng được Phương pháp dạy học theo hướng tiếp cận thực hành, giải quyết bài toán cụ thể giúp học sinh nắm vững kiến thức và kỹ năng lập trình
- Tích hợp công nghệ thông tin: Sử dụng công nghệ thông tin trong giảng dạy, như các phần mềm lập trình, mô phỏng, và các hệ thống học tập trực tuyến, giúp tăng cường hiệu quả giảng dạy và học tập Học sinh có thể tự học và thực hành qua các tài liệu trực tuyến, video hướng dẫn, và các bài tập tương tác
- Phương pháp học tập tích cực: Khuyến khích học sinh tham gia tích cực vào quá trình học tập, từ việc tự nghiên cứu, thảo luận nhóm, đến việc thực hiện các dự án nhỏ Điều này giúp phát triển tư duy sáng tạo và kỹ năng giải quyết vấn đề
2.1.3 Tâm lý học giáo dục
- Động lực học tập: Động lực là yếu tố quan trọng thúc đẩy học sinh học tập và nghiên cứu Việc sử dụng các phương pháp giảng dạy hấp dẫn, gần gũi và thực tiễn giúp khơi dậy niềm đam mê và động lực học tập của học sinh
- Phát triển tư duy logic và sáng tạo: Học sinh cần được phát triển tư duy logic và sáng tạo thông qua việc giải quyết các bài toán Tin học Thuật toán lùa
bò vào chuồng, với các bài toán đếm đa dạng, là một công cụ hiệu quả giúp rèn luyện và phát triển các kỹ năng tư duy này
Cơ sở lý luận của sáng kiến này dựa trên các khái niệm và lý thuyết cơ bản về thuật toán, đặc biệt là thuật toán lùa bò vào chuồng, cùng với các phương pháp giảng dạy Tin học và tâm lý học giáo dục Việc kết hợp các yếu tố này tạo nên một nền tảng vững chắc cho sáng kiến, giúp nâng cao hiệu quả giảng dạy và học tập, phát triển kỹ năng và tư duy của học sinh, và đạt được các mục tiêu giáo dục mong muốn
2.2 Thực trạng vấn đề trước khi áp dụng sáng kiến kinh nghiệm
Trước khi áp dụng sáng kiến sử dụng thuật toán lùa bò vào chuồng để giải các bài toán đếm trong bồi dưỡng học sinh giỏi môn Tin học tại trường PT Nguyễn Mộng Tuân, tôi đã tiến hành khảo sát và đánh giá thực trạng giảng dạy
và học tập môn Tin học Kết quả cho thấy một số vấn đề tồn tại như sau:
- Chất lượng giảng dạy và học tập chưa cao: Phương pháp giảng dạy
truyền thống chủ yếu tập trung vào việc giảng giải lý thuyết, ít chú trọng đến thực hành và ứng dụng Điều này làm giảm tính hấp dẫn và hiệu quả trong việc
tiếp thu kiến thức của học sinh Các tài liệu giảng dạy và bài tập hiện có chưa
đầy đủ và phong phú, chưa đáp ứng được nhu cầu học tập nâng cao của học sinh giỏi Học sinh thiếu cơ hội tiếp cận với các bài toán đếm phức tạp và các thuật toán tối ưu như thuật toán lùa bò vào chuồng
- Kỹ năng lập trình và tư duy thuật toán của học sinh còn hạn chế: Mặc dù học sinh đã được học các khái niệm cơ bản về lập trình và thuật toán, nhưng
Trang 5kiến thức nền tảng của các em vẫn chưa thực sự vững chắc Nhiều học sinh gặp khó khăn trong việc áp dụng các kiến thức đã học vào giải quyết các bài toán cụ thể
- Thiếu kỹ năng tư duy thuật toán: Học sinh thường gặp khó khăn trong
việc phát triển tư duy thuật toán, đặc biệt là trong việc tìm ra các phương pháp tối ưu để giải quyết các bài toán đếm Các em thường sử dụng các phương pháp đơn giản, không hiệu quả và tốn nhiều thời gian Hạn chế trong việc chuẩn bị cho các kỳ thi học sinh giỏi
- Thiếu phương pháp luyện tập hiệu quả: Các phương pháp luyện tập hiện tại chưa thực sự hiệu quả trong việc nâng cao kỹ năng giải bài toán của học sinh Học sinh thiếu các bài tập phong phú và thử thách, khiến cho việc chuẩn bị cho các kỳ thi học sinh giỏi trở nên khó khăn
- Kết quả thi chưa cao: Kết quả thi học sinh giỏi môn Tin học của trường
PT Nguyễn Mộng Tuân trong những năm gần đây chưa đạt được kết quả như mong muốn Học sinh chưa có đủ kỹ năng và kiến thức để cạnh tranh với các bạn cùng trang lứa ở các trường khác
- Tâm lý học sinh chưa sẵn sàng: Nhiều học sinh thiếu động lực và sự tự tin khi học tập môn Tin học, đặc biệt là khi đối mặt với các bài toán khó và phức tạp Điều này ảnh hưởng đến quá trình học tập và phát triển kỹ năng của các em
Thực trạng giảng dạy và học tập môn Tin học tại trường PT Nguyễn Mộng Tuân trước khi áp dụng sáng kiến kinh nghiệm cho thấy nhiều vấn đề cần được cải thiện Chất lượng giảng dạy và học tập chưa cao, kỹ năng lập trình và
tư duy thuật toán của học sinh còn hạn chế, phương pháp chuẩn bị cho các kỳ thi chưa hiệu quả và tâm lý học sinh chưa sẵn sàng là những thách thức cần được giải quyết Việc áp dụng sáng kiến sử dụng thuật toán lùa bò vào chuồng hứa hẹn sẽ mang lại những thay đổi tích cực, nâng cao chất lượng giảng dạy và học tập, giúp học sinh phát triển kỹ năng, tư duy và đạt được kết quả cao trong các
kỳ thi học sinh giỏi
2.3 Giải pháp áp dụng chiến lược lùa bò vào chuồng để giải các bài toán đếm
2.3.1 Phân tích và áp dụng thuật toán lùa bò vào chuồng
a Khái niệm:
Thuật toán lùa bò vào chuồng (hay còn gọi là kỹ thuật hai con trỏ, tiếng Anh: Two Pointer Technique) là một kỹ thuật lập trình mạnh mẽ và hiệu quả, thường được sử dụng để giải quyết các bài toán liên quan đến mảng và chuỗi
Kỹ thuật này sử dụng hai con trỏ để duyệt qua mảng hoặc chuỗi theo cách tối ưu nhất, giúp giảm độ phức tạp thời gian từ O(n^2) xuống O(n) trong nhiều trường hợp Tầm quan trọng của thuật toán này nằm ở khả năng cải thiện hiệu suất chương trình, đặc biệt khi xử lý các tập dữ liệu lớn Điều này làm cho thuật toán lùa bò vào chuồng trở thành một công cụ không thể thiếu trong kho tàng thuật toán của bất kỳ lập trình viên nào, đặc biệt là các học sinh tham gia các kỳ thi học sinh giỏi Tin học
Tư tưởng của thuật toán được xây dựng dựa trên suy nghĩ thực tế là đếm
số lượng bò trên một vùng xác định thì người ta phải tìm cách lùa chúng vào các
Trang 6chuồng để chúng khỏi chạy rông cho dễ đếm Đương nhiên những con bò phải được lùa vào cùng một chuồng để dễ phân biệt hoặc phải lùa mỗi con vào một chuồng thì càng tốt Tương tự như vậy, muốn giải bài toán đếm các đối tượng thì
ta dùng một cấu trúc dữ liệu hợp lý (thường dùng kiểu mảng hoặc kiểu con trỏ) với ý nghĩa giống như các “chuồng” để lưu các đối tượng, mỗi phần tử của mảng tương ứng với một chuồng, trên cơ sở đó ta dễ dàng thực hiện được mục đích của mình là thực hiện thao tác đếm
b Các bước thực hiện thuật toán
Để cụ thể hóa việc áp dụng thuật toán lùa bò vào chuồng, dưới đây là các bước thực hiện chi tiết:
* Khởi tạo các biến:
- left: Con trỏ trái, bắt đầu từ vị trí đầu tiên của mảng (index 0)
- right: Con trỏ phải, bắt đầu từ vị trí đầu tiên của mảng (index 0)
- current_sum: Biến lưu trữ giá trị tính toán hiện tại (ví dụ: tổng của đoạn con)
count: Biến lưu trữ số lượng đoạn con thỏa mãn điều kiện (nếu cần).
* Duyệt mảng bằng con trỏ right:
Di chuyển con trỏ right qua từng phần tử của mảng, cập nhật current_sum
- Kiểm tra và điều chỉnh con trỏ left:
- Khi current_sum vượt quá giá trị mục tiêu hoặc không thỏa mãn điều kiện, di chuyển con trỏ left sang phải để thu hẹp phạm vi của đoạn con, đồng thời cập nhật lại current_sum
* Cập nhật kết quả khi điều kiện thỏa mãn:
Nếu current_sum thỏa mãn điều kiện (ví dụ: bằng giá trị mục tiêu), cập nhật biến count hoặc lưu đoạn con vào danh sách kết quả
* Lặp lại các bước trên:
Tiếp tục di chuyển con trỏ right và điều chỉnh con trỏ left cho đến khi con trỏ right duyệt hết mảng
c Ưu điểm và hạn chế của thuật toán
Ưu điểm:
- Hiệu quả cao: Giảm độ phức tạp thời gian từ O(n^2) xuống O(n) trong nhiều trường hợp, giúp giải quyết bài toán nhanh chóng và hiệu quả
- Dễ triển khai: Kỹ thuật hai con trỏ dễ hiểu và dễ triển khai trong các ngôn ngữ lập trình khác nhau
- Ứng dụng rộng rãi: Thuật toán này có thể được áp dụng trong nhiều bài toán khác nhau liên quan đến mảng và chuỗi, từ bài toán đếm đến bài toán tìm kiếm và tối ưu hóa
Hạn chế:
- Chỉ áp dụng cho dãy con liên tiếp: Thuật toán lùa bò vào chuồng chỉ hiệu quả khi áp dụng cho các bài toán liên quan đến dãy con liên tiếp trong mảng hoặc chuỗi
- Phức tạp hơn khi điều kiện phức tạp: Khi điều kiện bài toán trở nên phức tạp, việc điều chỉnh con trỏ có thể đòi hỏi các bước xử lý phức tạp hơn
Trang 72.3.2 Bài toán “lùa bò vào chuồng” (đếm phân phối): Tên file: luabo1.cpp
Có n con bò, con bò thứ i được mã hóa giống bò là a[i], với a[i] trong khoảng (a[1],a[2],…a[n]) (điều kiện: -106<=a[i]<=106) Các con bò rất hung dữ, chúng sẽ húc nhau nếu được nhốt chung vào một chuồng Hỏi cần bao nhiêu chuồng để nhốt bò, mỗi chuồng nhốt bao nhiêu con để không xảy ra xung đột giữa các con bò
Ví dụ: Có 10 con bò có mã giống như sau:
10
-2 -3 0 2 0 2 1 2 -3 5
Hỏi cần bao nhiêu chuồng để nhốt những con bò này
* Ý tưởng:
Đầu tiên dự đoán xem dùng tối đa bao nhiêu chuồng, khi có điều kiện: -106<=a[i]<=106 có nghĩa là tối đa (2.106+1) mã giống bò khác nhau, nghĩa là cần chuẩn bị: 2.106 +1 chuồng bò Giả sử tối thiểu mỗi chuồng nhốt một con bò,
ta dùng mảng C làm chuồng bò và các chuồng bò này ở mỗi cửa chuồng bò bên ngoài cắm các biển ghi mã giống từ -106, ,.-3, -2, -1, 0, 1, 2, 3, 4,…,106 Với mục đích chỉ cho người ta biết rằng chuồng nào nhốt con bò có mã giống bao nhiêu dựa trên bảng này Minh họa thuật toán như sau:
-2 -3 0 2 0 2 1 2 -3 5
* Kết quả: Tất cả các chuồng không có bò ghi 0
-3 2 (Trong chuồng nhốt mã giống là -3 có 2 con)
-2 1 (Trong chuồng nhốt mã giống là -2 có 1 con)
0 2 (Trong chuồng nhốt mã giống là 0 có 2 con)
2 3 (Trong chuồng nhốt mã giống là 2 có 3 con)
1 1 (Trong chuồng nhốt mã giống là 1 có 1 con)
5 1 (Trong chuồng nhốt mã giống là 5 có 1 con)
Vậy ta thấy có tất cả 6 chuồng
* Thuật toán:
- Đầu tiên ta duyệt tất cả các con bò từ con bò số 1 cho đến con bò thứ n
- Chúng ta xét con bò a[i], con bò a[i] này có mã giống là a[i] nên nó phải
đưa vào chuồng có biển là a[i] Lúc này chuồng C có mã giống là a[i] được đưa vào chuồng có biển a[i] Vậy số con bò được nhốt vào chuồng này được tăng thêm 1 đơn vị
for (int i=1;i<=n;i++) C[a[i]]++;
C
-106
-3 5
4 3
2 1
0 -1
-2
-3
-3 -106
Trang 8Trên chính là thao tác nhốt bò, lùa bò vào chuồng.
- Duyệt một vòng lặp để lấy ra các con bò, chúng ta chỉ cần đếm xem trong
chuồng này có bao nhiêu giá trị trong mảng C >0 thì đó chính là chuồng
bò cần phải lấy Vậy mảng C chúng ta đi từ biển là -106 đến biển là +106
for (int i=-1000000;i<=1000000;i++)
if (C[i]>0) d++ //d là số chuồng bò
- Tiếp theo đưa ra mỗi chuồng bò có bao nhiêu con bò thi ta in ra d
cout<<d
for (int i=-1000000;i<=1000000;i++)
if (C[i]>0) cout<<i<< “ “<< C[i]<< ‘\n’;
* Vấn đề:
Tuy nhiên nếu ta Code như trên nếu ta không để ý dễ mắc lỗi tràn mảng, chúng ta đã biết khi khai báo một mảng ở trong C++ như sau:
Ví dụ: int C[106-+1]: Mảng C chạy từ 0 đến 106, nghĩa là mảng không có chỉ số
âm, tức là C[-2],C[-3],… không tồn tại nên C[-3]++ sẽ lỗi nếu chúng ta code như trên
* Giải quyết:
Ta hình dung mỗi con bò có mã giống -106<=a[i]<=106 thì chúng ta sẽ tìm cách tăng giá trị của a[i] này vào để cho mã giống sẽ không bị âm nữa ta sẽ cộng vào mỗi vế một giá trị để cho nó không âm, là cộng vào giá trị +106 Khi đó: 0<=a[i]+106<=2.106 sẽ không còn mã giống bị âm nữa Điều đó nghĩa là chúng ta phải khai báo lại mảng C là: C[2*106+1] nghĩa là C[2*N+1] Ta thu được code tối ưu của bài toán như sau:
* Code C++:
Trang 9Kết quả đầu ra của bài toán như sau:
2.3.3 Bài toán đếm các ký tự số Tên file: luabo2.cpp
Nhập xâu s Thống kê số các chữ số ‘0’, số chữ số ‘1’,…, số chữ số ‘9’ trong xâu đó
- Input: Một sâu s
- Output: Một dòng gồm 10 số nguyên, trong đó, số thứ i là k thể hiện số
i-1 xuất hiện k lần trong xâu
Ví dụ:
abc8km0hs0kskm1hatb9mabc5jk9sdb6 2 1 0 0 0 1 1 0 1 2
* Ý tưởng:
- Nếu i=1 tức là số thứ nhất thể hiện số 0 xuất hiện bao nhiêu lần, ở ví dụ trên kết quả đầu ra số đầu tiên là 2 nghĩa là số 0 xuất hiện 2 lần Tương tự, số
1 xuất hiện một lần, số 2, 3, 4 không xuất hiện lần nào kết quả là 0…, đến số cuối cùng là số 9 xuất hiện 2 lần
- Đầu tiên ta phải đánh giá xem chuồng bò phải chuẩn bị bao nhiêu cái chuồng Do đếm tất cả là 10 số nên ta phải chuẩn bị 10 cái chuồng từ chuồng thứ 0 đến chuồng thứ 9
0 1 2 3 4 5 6 7 8 9
- Chúng ta duyệt vòng lặp và kiểm tra nếu nó là chữ số thỏa mãn:
for (int i=0;i<S.size();i++)
if (‘0’<=S[i]&& S[i]<=’9’)
C[S[i]]++
- Ta lùa vào chuồng, nhưng ta lưu ý đây là kiểu kí tự ‘0’, ‘1’,’2C’, ‘3’,….,
‘9’, thì sẽ khác số 0,1, ….9 Nên khi ta viết vậy là đang lùa ký tự vào chứ không phải là số Cái ta đang cần là lùa số vào chứ không phải lùa ký tự Vậy để lùa được số ta nhớ phần học về xâu, trong bảng mã ASCII được xét như sau:
- Ký tự ‘0’ đứng ở vị trí ‘48’; Ký tự ‘1’ đứng ở vị trí ‘49’; Ký tự ‘2’ đứng
ở vị trí ‘50’; Ký tự ‘3’ đứng ở vị trí ‘51’; Ký tự ‘4’ đứng ở vị trí ‘52’; Ký tự ‘5’ đứng ở vị trí ‘53’; Ký tự ‘6’ đứng ở vị trí ‘54’; Ký tự ‘7’ đứng ở vị trí ‘55’; Ký
C
Trang 10tự ‘8’ đứng ở vị trí ‘56’; Ký tự ‘9’ đứng ở vị trí ‘57’ nên nếu viết: S[i]= ‘0’ thì C[S[i]]=C[48] Ký tự đổi ra số là số trong bảng mã ASCII Vậy cách làm là ta trừ đi 48, tức là: C[S[i]-48]++ hoặc viết: C[S[i]- ‘0’]++ thì mới đúng
* Code C++:
Kết quả đầu ra của bài toán như sau:
2.3.4 Bài toán: “Bình chọn qua điện thoại” Tên file: luabo3.cpp
Trong vòng chung kết cuộc thi “Vietnam Next Top Model” trên vtv3 các thí sinh được đánh số báo danh là một số nguyên dương có giá trị không vượt quá 1000 Khán giả xem truyền hình có thể bình chọn cho thí sinh mình yêu thích bằng cách nhắn tin qua điện thoại di động Ban tổ chức nhận được tin nhắn hợp lệ của N khán giả (các khán giả được đánh số từ 1 đến N), khán giả thứ i bình chọn cho thí sinh mang số báo danh ai
Hãy liệt kê số báo danh của những thí sinh được nhiều khán giả bình chọn nhất theo thứ tự tăng dần
Dữ liệu vào:
- Dòng đầu tiên ghi số nguyên dương N là số lượng khán giả có tin nhắn
bình chọn hợp lệ (N<=105)
- N dòng tiếp theo, dòng thứ i ghi số nguyên dương ai là số báo danh của thí sinh mà khán giả thứ i bình chọn
Kết quả: Danh sách thí sinh được nhiều khán giả bình chọn nhất theo thứ
tự số báo danh tăng dần