TẠP CHÍ ?
Số 1 & 2
01-02.2016
SINH VIÊN TRUNG TÂM BETH-CENTER
SÁNG TẠO, ĐỔI MỚI VỚI PHÒNG THÍ NGHIỆM
STEAM Lập trình Alice
với đối tượng, cảnh nền qua các phương thức và sự kiện đơn giản (Phần 1)
4 cá
ch hướ ng
dẫn
h n ì r t p ậ l c t r ẻ e m họ
Thö Ngoû Kính gửi quý độc giả! Với mong muốn luôn đổi mới và mang đến cho quý độc giả những thông tin bổ ích, cốt lõi về phương pháp giáo dục STEM. Bắt đầu từ tháng này, Tạp chí STEM lần đầu tiên được ra mắt và là tạp chí duy nhất tại Việt Nam về chương trình giáo dục STEM – chương trình sẽ cung cấp các kỹ năng cần thiết về phương pháp học tập của thế kỷ 21 cho học sinh. Tạp chí STEM là sự kế thừa của Tạp chí Tin & Nhà trường với đầy đủ các chuyên mục quen thuộc như: Chuyện làng STEM, Robotics kỳ thú, Lập trình thật đơn giản, các chuyên mục Sáng tạo Nghệ thuật số, Thế giới mở… Đây sẽ tiếp tục là một ấn phẩm giáo dục với những thông tin bổ ích, lý thú về khoa học, công nghệ, kỹ thuật hiện đại, cập nhật những thông tin về giáo dục STEM trong nước và trên thế giới đến với bạn đọc. Tạp chí STEM sẽ được phát hành dưới dạng phiên bản online. Quý độc giả quan tâm có thể đọc trực tuyến tạp chí trên trang web http://www.hocvienstem.com. Với sự thay đổi này, độc giả sẽ có những trải nghiệm mới, có sự tương tác và tiện lợi hơn trong việc tiếp cận tạp chí. Hy vọng, tạp chí STEM sẽ ngày càng phát triển và được sự đón nhận nhiệt tình từ quý độc giả trên cả nước! Trân trọng Ban biên tập
TẠP CHÍ STEM / SỐ 01 NĂM 2016
1
MỤC LỤC
CHUYỆN LÀNG STEM
4
Sinh viên Trung tâm Beth-Center sáng tạo, đổi mới với phòng thí nghiệm STEAM Hải Nhung
7
4 cách hướng dẫn học lập trình cho trẻ Hà Phương
10 Alice ở xứ sở lập trình Công Quyền
ROBOTICS KỲ THÚ
13 Giới thiệu hệ thống cảm biến (Sensor Sub System) Robot Vex Hải Phong
SÁNG TẠO NGHỆ THUẬT SỐ
15 Chỉnh sửa ảnh đón Xuân với công cụ trực tuyến PicMonkey Duy Anh
2
TẠP CHÍ STEM / SỐ 01 NĂM 2016
LẬP TRÌNH THẬT LÀ ĐƠN GIẢN
17 Lập trình cảm biến với Lego Mindstorms EV3 (Phần 5) Tiến Tùng 21 Cùng ôn lại lập trình Scratch trên những tấm thẻ màu Thảo Nguyên 24 Lập trình Alice với đối tượng, cảnh nền qua các phương thức và sự kiện đơn giản (Phần 1) Công Quyền 27 Trò chơi vòng quay may mắn với các thuật toán đơn giản Thu Hương 30 Kỳ thi lập trình Sinh viên quốc tế ACM/ICPC 2015 Hà Nội (Phần 2) Mai Huy Hoàng
THẾ GIỚI MỞ
36 Luyện toán cùng Tux of Math Command Nguyên Ân
? 38
HỌ ĐÃ LÀM ĐIỀU ĐÓ NHƯ THẾ NÀO
Tại sao Archimedes nổi tiếng đến vậy? Nhà sách Long Minh
33 Giải đáp tháng 12 - 2015 Nguyễn Quốc Hưng 35 Đề ra số Xuân 2016 Nguyễn Quốc Hưng
HỌC QUA HÀNH
42 Câu chuyện 1001 đêm khoa học Nhật Vinh (dịch)
VẠN VẬT KẾT NỐI
46 Tạo một nhiệt kế Đọc Nhanh Thu Trang (dịch)
TẠP CHÍ STEM / SỐ 01 NĂM 2016
3
CHUYỆN LÀNG STEM
SINH VIÊN TRUNG TÂM BETH-CENTER SÁNG TẠO,
ĐỔI MỚI VỚI
PHÒNG THÍ NGHIỆM STEAM Hải Nhung (dịch) Nguồn: heraldstandard.com
T
ạp chí STEM xin giới thiệu vài nét về một mô hình Trung tâm sáng tạo STEAM - Trung tâm Bethlehem-Center tại Mỹ. Mời quý độc giả cùng tìm hiểu.
và Toán học) với công nghệ giảng dạy và nghệ thuật truyền thông tiên tiến. Khoản tài trợ trị giá 115.000 đô la Mỹ được sử dụng để tạo lập một môi trường học tập sáng tạo cho học sinh của học khu, đồng thời phối hợp với cơ quan giáo dục địa phương - IU1 tạo môi trường phát triển chuyên môn.
Tại trường trung học Bethlehem-Center, học sinh không còn học tập theo phương pháp “dạy chay-học chay” kiểu thuyết giảng. Với sự hỗ trợ của công nghệ Linda Marcolini, quản lý học khu Bethlehem-Center hiện đại, các học sinh hiện nay được yêu cầu phải cho biết rất cảm ơn các nỗ lực của Tổ chức Claude Worthington Benedum trong việc hỗ trợ xây dựng sáng tạo và đổi mới. chương trình giảng dạy tiên tiến cho học khu và Gene Fox, giáo viên công nghệ tại Beth-Center cho mong muốn được giới thiệu giảng dạy cho học sinh biết tình trạng “dạy chay - học chay” không còn phổ các kỹ năng công nghệ cần thiết để đáp ứng công biến trong các trường học hiện nay. Chúng ta cần việc của các em sau này. khuyến khích học sinh có thái độ tích cực hơn trong học tập và yêu cầu các em rèn luyện phương pháp Ý tưởng tạo ra không gian học tập mới mẻ này được tự học. Chúng tôi đang cố gắng dạy cho các em các hình thành sau khi các cán bộ của học khu được mời kỹ năng của thế kỷ 21, đây là các kỹ năng mà các tham quan các phòng học đa phương tiện tại các trường thuộc học khu này. Các cán bộ của Học khu nhà tuyển dụng cần tìm kiếm ở các ứng viên.” Bethlehem-Center đã gặp gỡ các thành viên thuộc tổ Học khu Bethlehem-Center được Tổ chức Claude chức Claude Worthington Benedum và mong muốn Worthington Benedum tài trợ xây dựng một phòng được hợp tác từ Tổ chức này. Aaron Cornell, hiệu STEAM (Khoa học, Công nghệ, Kỹ thuật, Nghệ thuật, trưởng Trường trung học Bethlehem-Center đã liên 4
TẠP CHÍ STEM / SỐ 01 NĂM 2016
hệ với IU1, đơn vị này đã cung cấp iPad và hỗ trợ Internet cho trường. Trong một chương trình thí điểm, Ray VanSickle và Vincent Genovese, 2 giáo viên của trường đã sử dụng iPad để phục vụ việc giảng dạy trong các tiết học lịch sử Mỹ và tiếng Tây Ban Nha.
Hiệu trưởng Cornell cũng đồng quan điểm, Ông cho biết “Chương trình thí điểm đã cho chúng ta thấy một phương pháp giảng dạy và học tập mới có sử dụng công nghệ. Các học sinh không chỉ đơn giản là xem một trình chiếu Power Point, mà các em còn được sử dụng các ứng dụng và tạo ra sản phẩm kỹ Học sinh được cung cấp thiết bị kỹ thuật số, thay thuật số của riêng mình.” cho việc sử dụng giấy bút và có thể nộp và chấm bài bằng máy. Thành công của chương trình thí điểm đã Khoản tài trợ cung cấp kinh phí để học khu chuyển tạo tiền đề cho hoạt động phát triển chuyên môn của đổi thư viện thành một trung tâm đa phương tiện. toàn bộ học khu. Trong một tuyên bố, Donald Martin, Học sinh vẫn có thể học tập và đọc sách tại trung Giám đốc Trung tâm phát triển chuyên môn IU1 cho tâm, và ngoài ra, các em được tiếp cận với vô số biết: “Sự hợp tác giữa IU1, Học khu Bethlehem-Center các sản phẩm công nghệ hiện đại, bao gồm máy và Tổ chức Claude Worthington Benedum chứng tính, máy tính bảng... để hỗ trợ học tập cho học sinh. minh rằng một mối quan hệ hợp tác chặt chẽ cùng Jacob Pendland, một học sinh năm cuối chia sẻ với một số suy nghĩ khác biệt thực sự có thể thay đổi “Công nghệ này là nhanh hơn rất nhiều so với những cách nhìn nhận về hoạt động học tập của học sinh gì chúng em vẫn sử dụng trước đây. Các sản phẩm thông qua việc sử dụng công nghệ.” công nghệ cũng rất dễ sử dụng.”
TẠP CHÍ STEM / SỐ 01 NĂM 2016
5
CHUYỆN LÀNG STEM Học sinh còn có thể sử dụng một màn hình màu xanh lá cây để tạo các video, sau đó chia sẻ với các bạn cùng lớp thông qua các TV thông minh. Hiệu trưởng Cornell chia sẻ “Tôi nghĩ rằng trung tâm đa phương tiện mang lại cơ hội cho các em học sinh sử dụng các công nghệ mới, đồng thời cho phép các em có cơ hội để sáng tạo và học hỏi các kỹ năng mà các em sẽ áp dụng vào thực tế. Chúng tôi dành rất nhiều thời gian để uốn nắn các em nhỏ do các em đang trong giai đoạn quyết định, tuy nhiên cũng cho phép các em có cơ hội sáng tạo”.
giữa các học sinh, cung cấp thêm các thiết bị như: máy in 3D, máy khắc laser... Gene Fox hiện đang sử dụng máy in và máy khắc này trong các tiết dạy công nghệ của mình; Tuy nhiên, anh còn có những mục tiêu dài hạn khác với việc sử dụng 2 loại máy này. Fox chia sẻ: “Kế hoạch của tôi là sẽ chuyển giao máy in hoặc máy khắc cho bất cứ giáo viên nào cần sử dụng cho việc thiết kế hoặc xây dựng khi họ được đào tạo sâu hơn.” Trung tâm phục vụ cho học sinh từ mẫu giáo đến lớp 8, và tất cả các giáo viên. Các học khu khác của IU 1 sẽ được mời đến tham quan và sử dụng Trung tâm đa phương tiện mới còn được trang bị không gian phát triển chuyên môn của học khu, góp bàn ghế và nội thất mới hoàn toàn cho phép học phần khuyến khích các trường trong khu vực cải tiến sinh có thể dễ dàng di chuyển và tăng sự tương tác chương trình giảng dạy dựa trên công nghệ.
6
TẠP CHÍ STEM / SỐ 01 NĂM 2016
4
CÁCH
hướng dẫn trẻ em học lập trình
Hà Phương (dịch) Nguồn: pixelkin.org
T
rên số báo trước, các bạn đã biết việc viết mã lập trình có thể rất quan trọng đối với trẻ em!? Chúng ta sẽ tiếp tục tìm hiểu những cách hướng dẫn trẻ em học lập trình qua bài viết sau đây. Các bạn có thể giúp trẻ em tiếp cận viết mã lập trình thông qua các ứng dụng đơn giản trên máy tính bảng, nguồn tài liệu trực tuyến, các trại hè giao lưu và học lập trình cùng các trò chơi video kết hợp với các khái niệm lập trình.... Ứng dụng trên máy tính bảng Một trong số những cách tốt nhất để hướng dẫn trẻ em lập trình là thông qua các ứng dụng học lập trình trên thiết bị có hệ điều hành iOS hoặc Android. Những ứng dụng này cho phép trẻ em dưới 5 tuổi bắt đầu mày mò với các khái niệm lập trình cơ bản trên giao diện màn hình cảm ứng của máy tính bảng sẽ rất quen thuộc đối với trẻ em.
Trò chơi Hopscotch là một ứng dụng tương tự khác nhưng mở rộng hơn dựa trên ;ý tưởng này và dành cho trẻ em lớn hơn, công cụ này tạo ra những trò chơi nhỏ dành cho các em và tải chúng lên để chia sẻ với mọi người. Cả Hopscotch và Daisy the Dinosaur đều không đi sâu vào việc viết mã code cụ thể Trò chơi Daisy the Dinosaur là một ví dụ như vậy. nhưng đem lại cho trẻ em những thao tác cơ bản Đây là một ứng dụng nhỏ gọn dành cho trẻ em, hữu ích về thiết kế và lập trình. hướng dẫn làm thế nào để có thể thao tác lập trình bằng việc cung cấp một loạt các số để di chuyển Các ứng dụng khác như Tynker và Cargo-Bot thử chú khủng long Daisy. thách hơn một chút, hướng tới những học sinh lớn hơn để nắm được những vấn đề cơ bản. Ứng dụng
TẠP CHÍ STEM / SỐ 01 NĂM 2016
7
CHUYỆN LÀNG STEM này có nhiều thử thách cụ thể hơn và cài đặt lệnh cho người sử dụng. Giao diện màn hình cảm ứng khiến cho trẻ em dễ tiếp cận với các ứng dụng này. Nguồn tài liệu trực tuyến Một khi đã có cơ hội để tiếp cận những điều cơ bản, trẻ em có thể chuyển sang sử dụng Internet để tìm kiếm các nguồn tài liệu về lập trình. Những video trên YouTube hướng dẫn người học từng bước cơ bản trong quá trình học lập trình. Ngôn ngữ dựa trên trình duyệt cho phép tạo ra nhiều trò chơi miễn phí và hình ảnh động. Ngoài ra, các khóa học trực tuyến cung cấp nhiều hơn và sâu hơn những phân tích về kiến thức cơ bản. Scratch (https://scratch.mit.edu/) là một ngôn ngữ đặc biệt dùng cho học sinh Tiểu học và THCS, được tạo ra bởi nhóm nghiên cứu tại MIT Media Labs, Scratch là một ngôn ngữ lập trình dễ sử dụng để tạo ra những trò chơi video nhỏ gọn, những đoạn phim hoạt hình có thể chơi được và đây là ngôn ngữ lập trình miễn phí dành cho trẻ em. Các em có thể tìm hiểu một số video hướng dẫn lập trình Scratch để dễ dàng tìm hiểu về ngôn ngữ này và nhớ cùng đọc chuyên mục Lập trình thật đơn giản để học lập trình Trại hè lập trình Scratch qua những bài viết hướng dẫn trên Tạp chí STEM nhé. Cắm trại mùa hè và các cuộc hội thảo là một cách tuyệt vời để trẻ em quan tâm đến lập trình. Trẻ em Khan Academy (https://www.khanacademy.org/) sẽ được làm việc theo nhóm nhỏ bao gồm cả học được biết đến rất rộng rãi cho các lớp lập trình. Với sinh và giáo viên. Chúng có thể sẽ gặp những đứa nguồn tài liệu video, Khan Academy cung cấp toàn trẻ khác có cùng mối quan tâm và sử dụng kỹ năng bộ chương trình giảng dạy hoàn toàn miễn phí. được học để làm việc cùng với nhau. Trong khi đó, Codeacademy (https://www. codecademy.com/) là một kho tài liệu lớn với các bài học tương tác mang lại cho các em học sinh ở tất cả các lứa tuổi kỹ năng mà họ cần để lập trình bằng các ngôn ngữ cơ bản, thậm chí có thể tạo ra hoặc thiết kế trang web riêng của mình. Treehouse (https://teamtreehouse.com) cũng cung cấp các khóa học bằng video trực tuyến. Trang web Code Racer (http://teamtreehouse.com/library/ code-racer) thân thiện với trẻ em, cho phép các em nắm bắt tương đối về mã code trong những thử thách với những người chơi khác.
8
TẠP CHÍ STEM / SỐ 01 NĂM 2016
Có rất nhiều trại hè thu hút trẻ em ở các nhóm và độ tuổi khác nhau. Coderdojo (https://coderdojo. com/) và iDTech (https://www.idtech.com/) mở ra cho trẻ em tất cả các cấp độ kỹ năng và tính đồng nhất. Có nhiều chương trình và trại chuyên môn như Girls Make Games (http://girlsmakegames.how/), Girls Who Code (http://girlswhocode.com/), và Black Girls Code (http://www.blackgirlscode.com/) muốn truyền cảm hứng cho các bé gái và phụ nữ quan tâm đến những lĩnh vực liên quan đến STEM. Bờ Tây nước Mỹ trở thành nơi diễn ra những trại hè kiểu như thế này.
Nội dung do người dùng tạo dựng
trên Xbox One và Windows là trung tâm của ý tưởng này, cho phép người chơi tạo ra trò chơi của riêng Bạn không nhất thiết phải học những điều cơ bản mình bằng cách sử dụng các hành vi và các nhân về lập trình và thiết kế từ những nơi dạy lập trình. vật được tạo ra cho chính trò chơi đó. Và LittleBigPlanet Nhiều trò chơi video hiện có khả năng tạo ra những (http://pixelkin.org/2013/10/23/littlebigplanet-explained/) gì được gọi là nội dung do người dùng tạo dựng. Các là một trò chơi dễ thương và hấp dẫn cung cấp các trò chơi này thường có tùy chọn cho phép người chơi công cụ cần thiết cho người sử dụng để xây dựng tạo ra mức độ trò chơi của riêng họ, và cuộc đấu trí các cấp độ của riêng họ theo cách họ muốn. sử dụng tài sản và các công cụ được thực hiện bởi các nhà phát triển. Rất nhiều các trò chơi có tính năng tùy chọn để chia sẻ các dự án cá nhân trực tuyến, có nghĩa là người Những trò chơi này sẽ không dạy trẻ em cách viết chơi sẽ đưa tác phẩm của mình cho người khác chơi mã code nhưng chúng sẽ giúp các em hiểu được và có được cảm hứng từ các tác phẩm của người những khái niệm cơ bản về lập trình. khác. Và việc tạo ra những thứ trong các trò chơi có thể sẽ mang đến sự hứng thú, kích thích óc sáng tạo của trẻ em và đem lại cho chúng chìa khóa để mở Trong Mario Maker (http://supermariomaker. các thế giới ảo của riêng mình. nintendo.com) trên Wii U, mức độ thiết kế của người chơi sử dụng gạch, đường ống, và kẻ thù được tìm thấy trong nhiều Mario Universes khác nhau. Spark Project (http://pixelkin.org/games/project-spark/)
TẠP CHÍ STEM / SỐ 01 NĂM 2016
9
CHUYỆN LÀNG STEM
Ở XỨ SỞ LẬP TRÌNH
T
Công Quyền
hế giới Alice xin chào các bạn nhỏ! Các bạn thân mến, trong suốt thời gian qua, Thế giới Alice đã đồng hành cùng các bạn để khám phá rất nhiều điều mới mẻ đến từ phần mềm lập trình Alice 3.x. Đã bao giờ bạn tự hỏi rằng tại sao phần mềm này lại được đặt tên là Alice? Alice là tên của nhân vật nào? Nguồn gốc của phần mềm này ở đâu và ai là tác giả của phần mềm hết sức thú vị và bổ ích này? Trong số ra lần này, chúng ta cùng nhau giải đáp các thắc mắc trên các bạn nhé! Bạn nhỏ nào yêu thích các câu chuyện cổ tích nước ngoài, chắc hẳn cái tên Alice không hề xa lạ. Alice chính là tên của một cô bé trong cuốn tiểu thuyết dành cho thiếu nhi “Alice ở xứ sở thần tiên” của tác giả Lewis Carroll. Câu chuyện kể về cô bé Alice chui qua một hang thỏ rồi lạc vào thế giới thần tiên có những sinh vật kỳ lạ. Và tác giả của phần mềm Alice - Randy Pausch đã lấy tên cô bé Alice đặt tên cho phần mềm lập trình của mình với mục đích ban đầu là tạo điều kiện cho nữ sinh THCS tiếp cận và yêu thích khoa học máy tính (KHMT). Trong một phát biểu của Randy Pausch có nêu: “Hiện nay phụ nữ chưa có vai trò đúng mức trong Khoa học Máy tính (KHMT). Việc gia tăng số nữ sinh viên theo ngành KHMT vừa giúp cải tiến công nghệ nhờ sự đa dạng hóa quan điểm thiết kế, vừa giúp tăng cường nguồn nhân lực cho nhu cầu tương lai. Nhiều nghiên cứu cho thấy rằng nữ sinh từ cấp trung học cơ sở (THCS – middle school) thường không quan tâm đến những ngành nghề liên quan đến toán học và khoa học, trong đó có KHMT. Ở cuối lớp Tám, số nam sinh quyết định chọn nghề nghiệp tương lai thuộc các lĩnh vực khoa học kỹ thuật nhiều gấp đôi số nữ sinh. Thấu hiểu những khó khăn của người mới học lập trình và đặc biệt là đối với nữ sinh, sau khi khảo sát, phân loại kỹ lưỡng những phương pháp dạy lập trình, từ năm 1998, Randy Pausch cùng nhóm nghiên cứu của ông tại CMU quyết định xây dựng phần mềm để dạy lập trình theo hướng mới, dùng cho học sinh trung học phổ thông và sinh viên năm đầu của các ngành kỹ thuật. Phần mềm được đặt tên là Alice do cảm hứng từ truyện “Alice ở xứ thần tiên” của nhà toán học Lewis Carroll.
10
TẠP CHÍ STEM / SỐ 01 NĂM 2016
Alice là phần mềm nguồn mở. Lúc đầu, nhóm Pausch xây dựng Alice bằng ngôn ngữ Python. Do sự tài trợ của công ty Sun Microsystems, các phiên bản tiếp theo của Alice được viết bằng ngôn ngữ Java. Giống như cô bé Alice, Phần mềm Alice của Carroll luôn gặp những vấn đề toán học trong cuộc phiêu lưu vào thế giới kỳ lạ. Nhóm Pausch muốn tạo điều kiện để người dùng phần mềm Alice tiếp cận một cách tự nhiên với những khái niệm lập trình căn bản (biến, điều kiện, vòng lặp, đệ quy, thủ tục, đối tượng, tình huống) trong cuộc “phiêu lưu” của chính mình: xây dựng phần mềm trò chơi với những nhân vật trong thế giới ảo ba chiều, tương tự những nhân vật của phim hoạt hình Pixar. Sau khi đặt nhân vật vào “sàn diễn” và thiết lập các thuộc tính thích hợp cho nhân vật, người dùng Alice quy định hành vi của nhân vật thông qua việc sắp xếp những thẻ lệnh (command tile) theo thứ tự cần thiết. Những thẻ lệnh trong Alice giúp người dùng điều khiển chuyển động của nhân vật hoặc làm cho từng bộ phận của nhân vật (đầu, tay, chân) cử động. Khi người dùng quy định hành vi của nhân vật gắn với từng tình huống nhất định, nhân vật bắt đầu có “tính cách”.
Pascal. Do không cần viết câu lệnh, người dùng Alice không bao giờ vấp phải “lỗi cú pháp” (syntax error). Những sai lầm vào lúc chạy chương trình (run-time error) luôn thể hiện rõ ràng qua... hành vi “kỳ quặc” của nhân vật, giúp người dùng chỉnh sửa dễ dàng. Từ tháng 10/2006, CMU hợp tác với công ty Electronic Arts để xây dựng Alice 3.0 với các nhân vật từ trò chơi “The Sims 2” nổi tiếng. Alice 3.0 được phát hành chính thức vào mùa hè 2009 và đưa vào sử dụng trong học kỳ mùa thu năm 2009 tại CMU.
Thực hiện kịch bản trong Alice Với Alice, người học lập trình không cần ghi nhớ cú pháp của ngôn ngữ lập trình nào cả, dù là ngôn ngữ giản lược như BASIC hay “ngôn ngữ tự nhiên” như
Như vậy, Randy Pausch là tác giả của phần mềm lập trình Alice. Nhưng, để đưa Alice được chú ý nhiều hơn bởi các nữ sinh phải kể đến công sức của Caitlin Kelleher (Người Mỹ). Cô đã cải tiến công cụ lập trình Alice thành phần mềm “kể chuyện bằng hoạt hình” mà cô gọi là Storytelling Alice, đặc biệt dành cho các bạn gái. Kelleher cho rằng nam giới và nữ giới có khuynh hướng đặt vấn đề và giải quyết vấn đề khác nhau, do
TẠP CHÍ STEM / SỐ 01 NĂM 2016
11
CHUYỆN LÀNG STEM
Alice có sẵn trên 700 nhân vật vậy sự hiện diện của nữ giới trong KHMT và trong khoa học kỹ thuật nói chung sẽ giúp công nghệ đáp ứng tốt hơn những nhu cầu xã hội. Theo Kelleher, việc dạy lập trình ở cấp THCS giúp phát triển tư duy lô-gích và kỹ năng giải quyết vấn đề của học sinh. Cô tin rằng nữ giới sẽ tham gia nhiều hơn vào KHMT nếu Alice tạo được hứng thú cho nữ sinh ở lứa tuổi THCS – lứa tuổi dậy thì, lứa tuổi khởi đầu những nhận thức về vai trò của bản thân, lứa tuổi dễ rơi vào “khủng hoảng”, đánh mất sự tự tin. Nữ sinh không quan tâm nhiều đến trò chơi điện tử như nam sinh. Kelleher đi đến kết luận: Alice cần giúp nữ sinh kể chuyện, “diễn xuất” những vai khác nhau thông qua những “phim hoạt hình” do chính các em viết kịch bản và dàn dựng. Nhờ vậy, kỹ năng lập trình và niềm tin vào kỹ năng đó trong mỗi “cô bé người lớn” sẽ hình thành một cách tự nhiên. Và giờ đây, khi dùng Alice hoặc Storytelling Alice, bạn đừng quên nghĩ đến người tạo ra nó - Randy Pausch, và đặc biệt, có một phụ nữ uyên bác, dịu dàng và nhẫn nại đã đưa Alice gần hơn với các bạn nữ: Caitlin Kelleher. 12
TẠP CHÍ STEM / SỐ 01 NĂM 2016
Cảm ơn các bạn! Xin chào và hẹn gặp lại!
ROBOTICS KỲ THÚ
GIỚI THIỆU HỆ THỐNG CẢM BIẾN (SENSOR SUB SYSTEM) ROBOT VEX
Hải Phong
T
rên
các
số
báo
trước,
chúng ta đã được giới thiệu
Cảm biến siêu âm (Ultrasonic): ♦ Có thể cảm biến khoảng cách từ 1.5 in tới 115 in. ♦ Tránh va chạm. ♦ Tạo ra nhiều chức năng tự động.
một cách tổng quan các
hệ thống con của Robot Vex nói chung, Bài viết này, chuyên mục
Robotics kỳ thú sẽ đi sâu giới thiệu các thành phần của hệ thống cảm biến Robot Vex. Mời các bạn độc giả tiếp tục làm quen với mô hình Robot mới này nhé.
Giới thiệu chung về hệ cảm biến
H1. Cảm biến siêu âm Cảm biến ánh sáng ♦ Phân tích ánh sáng cung cấp cho Robot. ♦ Tự động tìm vùng sáng, tối. ♦ Tạo ra nhiều chức năng tự động cho Robot.
Hệ thống cảm biến giúp Robot có khả năng phát hiện các thay đổi khác nhau của môi trường. Các cảm biến đóng vai trò như tai, mắt của Robot, nhờ vậy Robot có thể hoạt động độc lập, không cần sự điều khiển của con người. Robot sẽ cảm nhận các thay đổi của môi trường xung quanh và đưa ra các hành vi phù hợp với các tác động của môi trường. Vậy các thành phần của hệ thống cảm biến là gì, chúng ta tiếp tục tìm hiểu ở phần sau đây. Các bộ phận của hệ cảm biến Bộ cảm biến bao gồm các thành phần sau:
H2. Cảm biến ánh sáng
TẠP CHÍ STEM / SỐ 01 NĂM 2016
13
ROBOTICS KỲ THÚ Loa Cảm biến đo đường (Line tracker) ♦ Cho phép Robot phân biệt đường đi màu đen trên ♦ Phát ra âm thanh từ Robot Vex nền trắng. ♦ Đi theo đường đánh dấu trước. ♦ Sử dụng kết hợp với cảm biến ánh sáng.
H3. Cảm biến đo đường Bộ đo góc quay (Potentiometer) ♦ Đo vị trí góc. ♦ Có thể chỉnh sửa theo góc 250 độ.
H4. Bộ đo góc quay
H5. Loa Mô hình Robot “VEX Walker”
H6. Robot Vex Walker
Lấy ý tưởng từ các tiểu thuyết khoa học qua các thời kỳ khác nhau, thiết kế robot có khả năng đi bộ là một nhiệm vụ khó khăn. Tuy vậy, các kỹ sư Robot Vex đã thiết kế thành công Robot Walker có khả năng đi bộ cân bằng trên 2 chân. Không chỉ có vậy, với hệ thống cảm biến thông minh, Robot này còn có thể quay các góc khác nhau trong khi đi bộ. Rất thú vị phải không các bạn! Hãy cùng tìm hiểu những phần kiến thức khác về chú Robot Vex đặc biệt này trên số báo tiếp theo các bạn nhé. 14
TẠP CHÍ STEM / SỐ 01 NĂM 2016
i ớ v n uâ PicMonkey SÁNG TẠO NGHỆ THUẬT SỐ
Chỉnh sửa ảnh
X óđ n
C
ác dụng cụ chỉnh sửa ảnh online đang ngày càng phát triển và trở nên phổ biến hơn bởi các tính năng vô cùng hữu dụng cũng như giao diện thân thiện với người dùng, bên cạnh “phù thủy ảnh” Adobe Photoshop và nhiều phần mềm xử lý ảnh chuyên nghiệp còn có những công cụ chỉnh sửa ảnh rất thú vị khác nữa. Tạp chí STEM số đặc biệt nhân dịp tết Bính Thân 2016 sẽ giới thiệu đến các bạn một trang web ứng dụng chỉnh sửa với đầy đủ các tính năng như vậy, đó là trang web Picmonkey. com. Nào, các bạn cùng thử tìm hiểu công cụ này để tự mình chỉnh sửa những bức ảnh đẹp cho mùa Xuân năm nay nhé.
công cụ trực tuyến
Duy Anh
chỉnh sửa (từ máy tính - Computer, từ Facebook, từ OneDrive, Dropbox hay ảnh có sẵn). Tại đây, chúng ta có 4 khung hình lớn phục vụ cho việc chỉnh sửa ảnh:
- Khung đỏ: các tính năng chỉnh sửa được chia làm 8 nhóm chính (lần lượt từ trên xuống dưới): Chỉnh sửa cơ bản (Basic Edit), Hiệu ứng (Effects), Trang điểm (Touch Up), Chèn chữ (Text), Chèn hình (Overlay), Chèn khung ảnh (Frames), Texture, Hình nền (Themes). Với mỗi tính năng trên khung đỏ, chúng ta lại có thêm nhiều lựa chọn chi tiết hơn bên trong khung đen. Ví dụ như trong Chỉnh sửa cơ bản Truy cập vào trang web picmonkey.com, bạn sẽ bắt chúng ta có thêm tính năng cắt ảnh (Crop), Xoay gặp một giao diện khá hiện đại và đẹp mắt. Bởi sự ảnh (Rotate), Chỉnh màu (Colors)... đa dạng và phong phú trong các tính năng chỉnh sửa ảnh, bài viết sẽ không thử nghiệm hết tất cả - Khung tím bên trên giao diện chứa những công cụ các công cụ mà thay vào đó để độc giả tự mình trải hỗ trợ khác như: Mở tệp ảnh, Lưu ảnh, Chia sẻ ảnh… nghiệm và cảm nhận. - Và cuối cùng, khung hình lớn nhất là nơi hiển thị Hãy bắt tay vào công cuộc khám phá các tính bức ảnh cũng như những thay đổi mà chúng ta lựa năng vô cùng hấp dẫn của PicMonkey bằng cách chọn. bấm vào Mục Edit và lựa chọn hình ảnh bạn muốn TẠP CHÍ STEM / SỐ 01 NĂM 2016
15
SÁNG TẠO NGHỆ THUẬT SỐ
Mặc dù sở hữu rất nhiều tính năng nhưng nhờ cách sắp xếp khoa học và hợp lý, người dùng có thể dễ dàng nắm bắt cách sử dụng.
Trong tính năng Effects chứa rất nhiều những hiệu ảnh màu sắc đặc biệt mà bạn nên trải nghiệm từng chức năng của nó.
Picmonkey.com cho phép người dùng xén ảnh (Crop), Tương tự với tính năng Touch Up, bạn sẽ có cả một xoay ảnh (Rotate). bàn trang điểm với hàng tá các dụng cụ khác nhau để sử dụng. PicMonkey cũng cho phép chèn chữ với rất nhiều loại font cũng như màu sắc khác nhau từ nút lệnh Text và chèn đủ loại hình thù với Overlays. Ứng dụng cũng cho phép bạn tạo khuôn hình khiến bức ảnh của bạn trở nên ấn tượng hơn (Frames) và thêm nhiều lựa chọn về hiệu ứng ảnh tại Textures.
Xoay ảnh với Rotate. Bạn có thể điều chỉnh độ sáng, bóng râm, độ tương phản tại Exposure và tùy chỉnh độ sắc nét độ trong của ảnh (Sharpen). Bạn cũng có thể chỉnh sửa lại kích thước của ảnh (Resize).
Hiệu ứng ảnh tại Textures. Hy vọng bài viết đã giúp các bạn nắm được các tính năng cơ bản của PicMonkey để có thể tự tạo cho mình những bức ảnh với tông màu đẹp mắt.
Chỉnh sửa lại kích thước của ảnh. 16
TẠP CHÍ STEM / SỐ 01 NĂM 2016
Chúc các bạn một năm mới an khang, thịnh vượng và không quên đón đọc Tạp chí STEM trên các số báo sắp tới trong năm 2016 nhé.
LẬP TRÌNH THẬT LÀ ĐƠN GIẢN
Lập trình cảm biến với
Lego Mindstorms EV3 (Phần 5) Tiến Tùng
Tạp chí STEM xin gửi lời chào ấm áp tới các bạn nhỏ. Chúc các bạn một năm mới thật nhiều niềm vui, học tập thật tốt và nhớ đón đọc những bài viết thật hay về lập trình Robot các bạn nhé.
C
ác bạn nhỏ thân mến, trong số báo trước, Tạp chí đã hướng dẫn các bạn cách thức cập nhật Firmware cho EV3 Brick để hoạt động được tốt hơn, mượt mà hơn phải không nào. Tuy nhiên, trong quá trình sử dụng không phải lúc nào hệ thống robot cũng chuyển động ổn định. Bài viết sẽ cùng các bạn nhỏ xử lý những lỗi thường gặp trên bộ não EV3 nhé.
Một số loại linh kiện cơ bản Như thường lệ, trước khi vào phần lập trình, Tạp chí xin được giới thiệu đến các bạn nhỏ thêm một số loại linh kiện thường dùng trong bộ LEGO MINDSTORM EV3 EDUCATION. ♦ O - Frame 5X7: chiếc khung nhỏ này có khá nhiều lỗ tròn ở các hướng khác nhau, giúp cho chúng ta dễ dàng kết nối, sáng tạo ra được nhiều mô hình khác nhau.
♦ H - Frame 5X11: Tương tự như O – Frame nhưng với kích thước lớn hơn và có nhiều lỗ tròn kết nối hơn.
TẠP CHÍ STEM / SỐ 01 NĂM 2016
17
LẬP TRÌNH THẬT LÀ ĐƠN GIẢN ♦ Ống nhòm trắng: có hình dáng như 1 chiếc ống Hãy làm theo các hướng dẫn sau đây sẽ giúp cho nhòm, linh kiện này giúp kết nối các linh kiện khác EV3 Brick của các bạn trở lại bình thường, hoặc ít với nhau một cách đơn giản hơn rất nhiều. nhất là tránh được điều tệ nhất, giúp cho EV3 Brick không bị hỏng. Trước khi vào phần sửa lỗi chúng ta cùng nhìn lại giao diện của EV3 Brick nhé. EV3 Brick bị kẹt ở màn hình Updating khi cập nhật Firmware. Đây là một lỗi khá phổ biến mà nguyên nhân có thể kể đến như sau: ♦ EV3 Brick bị ngắt kết nối khi đang tiến hành Update. ♦ Phần mềm LEGO EV3 Education xảy ra lỗi khi đang tiến hành update.
♦ Ống nhòm đen: tương tự như ống nhòm trắng nhưng với kích cỡ nhỏ hơn. Để xử lý tình huống này, các bạn hãy thực hiện theo các bước sau: ♦ Giữ tổ hợp phím Back – Center – Right để EV3 Brick khởi động lại. ♦ Sau khi EV3 Brick khởi động lại, hãy thả phím Back. ♦ Sau khi màn hình xuất hiện “Updating” hãy thả 2 phím Center và Right rồi kết nối EV3 Brick với máy tính thông qua dây cáp USB. ♦ Tiến hành cập nhật firmware như bình thường.
Cách xử lý lỗi thường gặp với EV3 Brick
EV3 bị kẹt ở màn hình Starting khi khởi động bộ não.
Để xử lý tình huống này, các bạn hãy thực hiện theo Khi gặp tình huống lỗi trên EV3 Brick, các bạn nhỏ các bước sau: hãy giữ bình tĩnh và đừng lo lắng. ♦ Tháo pin và lắp lại pin vào EV3 Brick. ♦ Giữ chặt tổ hợp phím Center – Right cho tới khi màn hình hiển thị “Updating”. ♦ Kết nối EV3 Brick với máy tính thông qua dây cáp USB. ♦ Tiến hành cập nhật firmware như bình thường. EV3 Brick đột ngột dừng hoạt động nhưng không thể tắt đi được. Để xử lý tình huống này, các bạn hãy chắc chắn rằng EV3 Brick vẫn đang bật rồi thực hiện theo các bước sau: ♦ Giữ chặt tổ hợp phím Back – Center – Left. ♦ Khi màn hình EV3 Brick tắt, hãy thả phím Back. ♦ Khi màn hình hiển thị “Starting”, hãy thả 2 phím Center - Left.
18
TẠP CHÍ STEM / SỐ 01 NĂM 2016
Lập trình cảm biến màu sắc.
Và chúng ta có giao diện như sau: Như các bạn thấy, chúng ta sẽ có 2 nhánh với 2 màu mặc định là nhánh Ở các số báo trước, chúng ta lần lượt được lập trình trên với màu đen, nhánh dưới với không màu. với các loại cảm biến chạm, siêu âm, ánh sáng phải không nào. Lần này, tạp chí STEM xin được gửi đến các bạn về cảm biến màu sắc nha.
Để lựa chọn màu sắc khác các bạn hãy nhấp chuột Các bạn có thấy cảm biến màu sắc có quen không? vào ký hiệu màu để thay đổi nhé. Thực sự là rất quen đó nha, vì đó không ai khác, chính là anh chàng cảm biến ánh sáng mà các bạn đã được giới thiệu đó. Khác với robot NXT khi cảm biến ánh sáng và cảm biến màu sắc là tách biệt hoàn toàn. Ở phiên bản EV3 này, LEGO đã kết hợp giữa hai loại cảm biến thú vị đó, vừa tiết kiệm chi phí, vừa “đa zi năng” phải không các bạn nhỏ. Để bắt đầu lập trình cảm biến màu sắc, xin mời các bạn nhỏ hãy bật chương trình LEGO EV3 Education lên nhé, sau đó hãy lấy khối Switch ra và chuyển nó từ cảm biến chạm sang cảm biến màu sắc.
Như các bạn thấy, chúng ta có lần lượt là 7 màu: không màu, màu đen, màu xanh lam, màu xanh lục, màu vàng chanh, màu đỏ, màu trắng và màu nâu. Để các bạn dễ hình dung, tạp chí sẽ lựa chọn hai mầu lần lượt là: Đen & Đỏ nhé.
TẠP CHÍ STEM / SỐ 01 NĂM 2016
19
LẬP TRÌNH THẬT LÀ ĐƠN GIẢN
Như các bạn thấy, khi nào gặp màu đen thì sẽ có âm thanh “Black”, khi nào gặp màu đỏ sẽ có âm thanh “Red”. Thật đơn giản phải không các bạn! Vậy thử thách nhỏ giành cho các bạn nhỏ kỳ này nha. Hãy cho robot của chúng ta di chuyển trên bản đồ, khi gặp màu đỏ hãy rẽ trái, màu xanh lục thì dừng lại, màu xanh lam thì đi thẳng. Hãy nhớ, đến màu nào thì phải phát ra âm thanh báo hiệu nha các bạn.
20
TẠP CHÍ STEM / SỐ 01 NĂM 2016
Cùng ôn lại lập trình
Scratch
trên những tấm thẻ màu
Thảo Nguyên
N
hững tấm thẻ với những hình ảnh đẹp mắt cùng với các khối lệnh hướng dẫn rõ ràng, dễ hiểu sẽ giúp học sinh học lập trình Scratch một cách nhanh chóng. Nào, chúng ta cùng ôn lại những kiến thức cơ bản và thường xuyên sử dụng trong lập trình khối lệnh Scratch từ những tấm thẻ học này nhé.
Thay đổi màu sắc
Nhảy theo âm thanh của tiếng trống
Thẻ lệnh mô phỏng chức năng thay đổi màu sắc cho nhân vật bằng cách nhấn nút lệnh Space trên bàn phím. Thẻ lệnh hướng dẫn bạn chèn một nhân vật trong thư viện hoặc tự vẽ một nhân vật mới theo sáng tạo của bạn bằng công cụ Paint. Sau đó, bạn dùng khối thẻ lệnh Change ( ) effect by ( ) để thay đổi màu cho nhân vật.
Tấm thẻ hướng dẫn bạn tạo một chương trình đơn giản, tạo chuyển động (nhảy múa) của nhân vật theo âm thanh của tiếng trống hoặc theo tiếng nhạc bạn có thể chèn vào chương trình.
TẠP CHÍ STEM / SỐ 01 NĂM 2016
21
LẬP TRÌNH THẬT LÀ ĐƠN GIẢN Di chuyển nhân vật theo các phím mũi tên
Chuyển động mềm mại trơn tru
Bạn có thể tạo một chương trình hoặc một trò chơi nhỏ mô phỏng chuyển động của một nhân vật theo các phím mũi tên lên xuống, sang trái – sang phải. Bạn có thể mở rộng thêm chức năng xoay tròn nhân vật hoặc sang trái, sang phải bằng lệnh Set rotation style ().
Lệnh Glide ( ) secs to x ( ) y ( ) được lựa chọn trong các trường hợp mô phỏng chuyển động của các nhân vật. Vì với lệnh này, các nhân vật sẽ chuyển động mượt mà hơn, đẹp hơn và hơn hết là chỉ cần 1 lệnh này đã có thể mô phỏng toàn bộ chuyển động của nhân vật từ một điểm đến điểm khác theo mọi hướng và mọi phương tại bất kỳ vị trí x, y nào trên màn hình sân khấu.
Các nhân vật trò chuyện Với chức năng này, bạn có thể tạo một câu chuyện với nhiều nhân vật trò chuyện với nhau. Bạn còn nhớ câu chuyện cổ tích “Trí khôn của ta đây” trên số báo tháng 3.2015 không nhỉ. Rất nhiều cuộc trò chuyện diễn ra giữa các nhân vật là Con cọp, con Trâu và Bác nông dân. Cách thực hiện rất đơn giản với lệnh Say ( ) hoặc Say ( ) for ( ) secs.
22
TẠP CHÍ STEM / SỐ 01 NĂM 2016
Chuyển động theo chuột máy tính Với tấm thẻ học này, bạn có thể thao tác chuyển động của nhân vật với con trỏ chuột và dễ dàng tạo được những trò chơi thú vị trên lập trình Scratch với khối lệnh point towards (mouse-pointer).
Tạo hình ảnh động Với những hướng dẫn này, các bạn sẽ dễ dàng tạo được hình ảnh động chỉ với vài bước đơn giản, sử dụng khối lệnh switch costume to ( ) để thay đổi hình dạng nhân vật. Để bắt đầu, bạn có thể vào thư viện để lựa chọn các nhân vật và những thao tác tạo bản sao hay nhân bản (duplicate) cho nhân vật. Sau đó, bạn chỉnh sửa nhân vật đó khác đi để tạo nhiều hình dáng khác nhau cho nhân vật.
Với những tấm thẻ màu ngộ nghĩnh này, các bạn học sinh sẽ dễ dàng học và ghi nhớ những phần kiến thức cơ bản nhất trên lập trình Scratch. Qua đó, thẻ học này sẽ giúp các em học sinh nâng cao tư duy và vận dụng vào các bài
Tạo phim hoạt hình
tập lập trình của mình. Bạn
Nếu hướng dẫn trên giúp bạn tạo hình ảnh động, thì với tấm thẻ hướng dẫn sau đây, bạn có thể kết hợp những thẻ lệnh trong Scratch như chuyển đổi hình dạng Next Costume, thẻ lệnh Move để tạo những chuyển động ngộ nghĩnh cho các nhân vật của bạn khi thực hiện một đoạn phim hoạt hình. Tương tự, bạn cũng có thể lựa chọn các chức năng xoay tròn nhân vật hoặc sang trái, sang phải bằng lệnh Set rotation style () để giúp nhân vật chuyển động phong phú hơn.
cũng có thể thử tạo những tấm thẻ này và nhiều tấm thẻ với các nội dung khác về hướng dẫn học lập trình Scratch để cùng ôn lại những kiến thức về ngôn ngữ lập trình này nhé.
SỐ 196 THÁNG 02 NĂMTẠP 2016 CHÍ/ TIN STEM HỌC / SỐ & NHÀ 01 NĂM TRƯỜNG 2016
23
LẬP TRÌNH THẬT LÀ ĐƠN GIẢN
Lập trình Alice
Với đối tượng, cảnh nền qua các phương thức và sự kiện đơn giản (Phần 1) Công Quyền
T
rên số báo này, chúng ta sẽ làm quen với một chùm bài viết với nhiều thao tác tổng hợp như thêm đối tượng, xây dựng cảnh nền, lập trình thao tác nhân vật với các phương thức mới. Bạn cũng có thể lập trình Alice với các sự kiện đơn giản và điều khiển Camera. Chúng ta bắt đầu với phần 1 của bài viết sau đây. 1. Chọn nền:
Bước đầu tiên quen thuộc trong việc tạo thế giới Alice là chọn background. Khi bạn mở Alice, hộp thoại sẽ tự động xuất hiện. Bạn nhấn vào thẻ “Templates”, chọn phông nền nước bằng cách nhấn vào “water” và sau đó nhấn vào nút “open”.
24
TẠP CHÍ STEM / SỐ 01 NĂM 2016
2. Chọn đối tượng: Bây giờ, hãy thêm objects vào thế giới. Chúng ta sẽ thêm vào chú cá vàng và cô tiên. Bên phải của khung hiển thị, nhấn vào nút “Add Objects”. Khi bạn nhấn vào “add objects”, một thư viện các đối tượng sẽ xuất hiện phía dưới phông nền Water.
Thêm đối tượng – Cá vàng: Chọn thư mục Định vị đối tượng – Up & Down: Hình mũi tên lên và animals và kéo chuột cho đến khi bạn tìm xuống sẽ di chuyển đối tượng của bạn lên và xuống. thấy Goldfish. Nhấn vào Goldfish và nhấn vào Hãy di chuyển cô tiên lơ lửng trên mặt nước. “Add instance to world”. Chú cá vàng xuất hiện trên màn hình hiển thị, ban đầu chú cá sẽ rất nhỏ nhưng các bạn chưa bận tâm về điều đó lúc này. Trước hết, chúng ta cần thêm vào cô tiên. Nhấn vào “Local Gallery” để quay trở về thư viện sẵn có trên máy tính. Định vị đối tượng – Spin: Nút này được dùng để xoay đối tượng (spin). Thử xoay chú cá vàng song song với màn hình. Thêm đối tượng – Cô tiên: Bây giờ, kéo chuột đến thư mục “Fantasy”. Sau đó, chọn thư mục “Faeries”. Thêm cô tiên vào thế giới của bạn bằng cách nhấn vào cô tiên và sau đó nhấn “Add Instance to World”.
Thêm đối tượng – Object Tree: Khi bạn thêm đối tượng vào thế giới, chúng sẽ xuất hiện trong danh sách bên tay trái màn hình của bạn. Danh sách này được gọi là Object Tree. Lúc này bạn đã có hai đối tượng trong thế giới của bạn, chú cá vàng và cô tiên.
Nút Undo: Bất kể lúc nào bạn làm sai trong Alice, bạn cũng có thể nhấn vào nút Undo và Alice sẽ trả về thao tác gần nhất. Hãy sử dụng nó khi cần!
Định vị đối tượng – Tilt: Nút tiếp theo sẽ xoay nhân vật của bạn về phía sau hoặc phía trước. Hãy sử dụng nó để làm cho cô tiên nghiêng nhẹ về phía trước.
3. Định vị đối tượng: Bây giờ, bạn hãy nhìn bên phải màn hình. Tất cả các nút có hình mặt người ở trên sẽ giúp bạn định vị được đối tượng.
Định vị đối tượng – Tumble: Nút định vị này sẽ giúp bạn di chuyển nhân vật đến tất cả các nơi. Sử dụng nó để di chuyển cô tiên sao cho cô ta hướng mặt về Nhấn vào white arrow, hãy thử nhấn vào cô tiên và phía chú cá. Lưu ý: Nếu bạn không thích vị trí của cô di chuyển cô ấy. Hãy di chuyển cô tiên sao cho cô ấy ta, nhấn “Undo” và thử di chuyển lại. đứng bên phải chú cá vàng như trong hình.
TẠP CHÍ STEM / SỐ 01 NĂM 2016
25
LẬP TRÌNH THẬT LÀ ĐƠN GIẢN Định vị đối tượng - Resize: Nút Resize sẽ giúp bạn có thể thay đổi kích thước nhân vật. Hãy sử dụng để làm cho chú cá lớn hơn cô tiên. Bay giờ hãy di chuyển chú cá hơi nhô lên trên mặt nước. Bạn có thể chỉnh sửa vị trí và kích thước theo ý muốn của bạn. Như vậy, chú cá và cô tiên đã được chỉnh sửa vị trí. Các bạn hãy luyện tập thêm với các nhân vật khác mà các bạn muốn. Trong số ra lần sau, chúng ta sẽ cùng nhau chỉnh sửa vị trí của camera. Định vị đối tượng – Copy: Còn một nút nữa nhưng Xin chào và hẹn gặp lại! chúng ta không sử dụng, nút này sẽ copy đối tượng của bạn, tuy nhiên về sau nó sẽ gây ra một số vấn đề. Vì thế chúng ta không nên sử dụng nó mà nên thêm đối tượng từ thư viện nếu bạn muốn.
Sau khi các bạn định vị được đối tượng, nhấn vào nút “done” để thoát khỏi thư viên đối tượng. Lúc này, màn hình của bạn sẽ giống như hình sau:
26
TẠP CHÍ STEM / SỐ 01 NĂM 2016
LẬP TRÌNH THẬT LÀ ĐƠN GIẢN
Trò chơi vòng quay may mắn với các thuật toán đơn giản Thu Hương
T
hông thường, chúng ta thấy trò chơi này xuất hiện khá nhiều từ trò chơi Chiếc nón kỳ diệu, Bánh xe số trong chương trình Hãy chọn giá đúng hay bất kỳ chương trình bán hàng khuyến mại với vòng quay may mắn. Thuật toán này cực kỳ đơn giản, nhưng chúng ta không thể phủ nhận những ứng dụng thực tế của nó trong nhiều lĩnh vực của đời sống của chúng ta.
Đây là kỹ thuật phổ biến hay sử dụng trong các phương pháp tìm kiếm dựa vào xác suất, đặc biệt trong phép toán Chọn lọc (Selection) của thuật toán di truyền (Genetic Algorithm). Thực chất của kỹ thuật này là giải quyết bài toán cụ thể sau:
Giả sử V={v1,v2, …, vn} là tập các láng giềng của u, p1, p2, …, pn là xác suất lựa chọn đỉnh tiếp theo từ u đến các tương ứng v1,v2, …, vn.
tức là chắc chắn chọn 1 trong các đỉnh trên để đi tiếp. Để đảm bảo ưu thế của những đỉnh có xác suất lớn, nhưng vẫn đảm bảo cơ hội của các đỉnh có xác suất thấp hơn, người ta sinh ra một số ngẫu nhiên k (0, sum] rồi chọn i nhỏ nhất sao cho:
Ghi chú
........................................ ..............
.................... ..................................
........................................ ..............
.................... ..................................
........................................ ..............
.................... ..................................
........................................ ..............
.................... ..................................
........................................ ..............
.................... ..................................
........................................ ..............
.................... ..................................
........................................ ..............
.................... ..................................
Cách làm này mô phỏng hoạt động của một vòng quay may mắn (vòng được chia làm nhiều phần không bằng nhau), rõ ràng khi quay ta không biết kim của bánh quay sẽ chỉ vào phần nào nhưng ta cũng có thể nhận thấy ngay là phần lớn hơn sẽ nhiều khả năng kim rơi vào đó hơn. Như vậy, chúng ta sẽ thực hiện việc quét các đỉnh rất đơn giản như sau: Đặt điểm mẫu từ một đỉnh xuất phát, lần lượt quét (tới thăm các đỉnh tiếp theo theo quy tắc: thăm xong đánh dấu chúng lại) cho đến thăm tới đỉnh cuối cùng và quay về đỉnh ban đầu, kết thúc một hành trình. Quá trình này được lặp đi lặp lại, hành trình tốt hơn (có chiều dài ngắn hơn) sẽ được cập nhật cho đến một khoảng thời gian đủ tốt (thông thường tính toán theo số vòng lặp, với các trường hợp nhỏ (số đỉnh ≤ 200) số vòng lặp bằng 500 là đủ tìm ra kết quả tối ưu, còn với các trường hợp lớn hơn ta phải thử với số lần lặp lớn hơn nhiều, tùy thuộc vào từng bộ dữ liệu cụ thể.
........................................ ..............
.................... ..................................
........................................ ..............
.................... ..................................
........................................ ..............
.................... ..................................
........................................ ..............
.................... ..................................
........................................ ..............
.................... ..................................
........................................ ..............
.................... ..................................
....................................... ...............
................... ..................................
........................................ ..............
.................... ..................................
........................................ ..............
TẠP CHÍ STEM / SỐ 01 NĂM 2016
27
LẬP TRÌNH THẬT LÀ ĐƠN GIẢN Trong cả quá trình thăm quét các điểm luôn khác nhau giữa các điểm với nhau vì còn phụ thuộc vào độ dài, ngắn, thậm chí là chướng ngại vật trên đường tới các điểm… Tuy nhiên, chúng ta có thể hiểu đơn giản thuật toán như sau:
- W[1..N]: mảng số nguyên một chiều lưu hành trình trên từng cạnh. - Mark[1..N]: mảng boolean một chiều đánh dấu đỉnh đã thăm. - UV[1..N-1]: mảng số nguyên 1 chiều lưu các đỉnh chưa thăm.
Sau mỗi vòng lặp, đường đi của một hành trình trên mỗi cạnh được cập nhật lại theo công thức sau:
Các thủ tục đặc tả:
trong đó ρ thuộc (0,1) gọi là tham số thường được chọn là 0,8 trong cài đặt và chạy chương trình. Ngoài sự thay đổi trên đường quét của mỗi cạnh bất kỳ (i, j) còn được xác định một giá trị tương đương Δi,j nhất định tùy thuộc vào từng chu trình quét, cụ thể được tính như sau:
trong đó Q là một hằng số, Lk là độ dài hành trình thứ k. Sau mỗi vòng lặp (hay sau mỗi lần quét hết một hành trình), sự tương đồng trong quá trình quét trên các cạnh sẽ thay đổi (hoặc giảm hoặc tăng dần) ảnh hưởng đến thời gian quét từng cạnh. Nhờ vậy thuật toán có khả năng tìm được lời giải tốt trong những trường hợp dữ liệu cực lớn. Hướng dẫn cài đặt bằng ngôn ngữ PASCAL Cấu trúc dữ liệu: - D[1..N, 1..N]: mảng số thực hai chiều lưu độ dài các cạnh. - T[1..N, 1..N]: mảng số thực hai chiều lưu sự tương đồng trên các cạnh. - Delta[1..N, 1..N]: mảng số thực hai chiều tất cả các thay đổi trên quá trình quét cạnh. 28
TẠP CHÍ STEM / SỐ 01 NĂM 2016
.................... .......................................
. ........................................ .................
....................... ....................................
.... ........................................ ..............
.......................... ..................................
...... ......................................................
Procedure Init; Begin For i:= 1 to n-1 do For j:=i+1 to n do Begin T[i,j]:= c; {c là một hằng số thường lấy bằng 0.5} Delta[i,j]:= 0; T[j,i]:= T[i,j]; Delta[j,i]:= Delta[i,j]; End; N_Loop:= 0; {đếm số vòng lặp hiện tại} L_Best:= MaxReal; {biến số thực đủ lớn} End;
........................................ ....................
Procedure Lucky_Wheel (Var k: Integer); Begin sum:= 0; dem:= 0; Fillchar(UV, Sizeof(UV), 0); For i:= 1 to n do If (Not Mark[i]) then Begin sum:= sum+p[i]; {sum là biến tổng các xác suất} Inc(dem); UV[dem]:= i; End; k:= random(sum); t:= 0; i=1; While (t>0) do Begin t=t+p[UV[i]]; End; k:= UV[i]; End;
........................................ ....................
.................... ........................................
........................................ ....................
.................... ........................................
........................................ ....................
.................... ........................................
........................................ ....................
.................... ........................................
........................................ ....................
.................... ........................................
.................... ........................................ .............................................................
............................................ ................
........................ ....................................
.... ........................................ .............. .............................................................
.... ........................................ ..............
.......................... .................................
....... ........................................ ...........
............................. ..............................
.......... ........................................ ........
Procedure Pheromone_Update; Begin For i:=1 to N-1 do For j:=i+1 to N do Begin T[i,j]:= rho*T[i,j] + Delta[i,j]; {rho thường được chọn bằng 0.8}
................................ ............................
............ ........................................ .......
................................. ...........................
............. ........................................... ... ........................................ ....................
LẬP TRÌNH THẬT LÀ ĐƠN GIẢN
T[j,i]:= T[i,j]; End;
End; Procedure Cycle; Begin Init; Repeat Inc(N_Loop); For i:= 1 to M do Begin W[1]:= 1; Fillchar(Mark, Sizeof (Mark), False); Mark[1] := True; L:= 0; For j:= 2 to N do Begin Lucky_Wheel(W[j]); L:= L + D[W[j-1], W[j]]; Mark[W[j]]:= True; End; End; L:= L+D[W[N], W[1]]; If (L>0) then Begin L_Best:= L;
Luu_duong_di:= W; {Luu_duong_di là mảng lưu kết quả} End; For i:=1 to N-1 do For j:=i+1 to N do Begin Delta[i,j]:= Delta[i,j] + Q/L; Delta[i,j] := Delta[j,i]; End; End; Pheromone_Update; Until (N_Loop < N_C); {N_C là tổng số vòng lặp sẽ chạy, phụ thuộc từng bộ dữ liệu} End;
Thuật toán này hoàn toàn có thể ứng dụng để giải bài toán du lịch một cách đơn giản hơn bao giờ hết. Đây cũng là một bài toán kinh điển được dùng trong thực tế khá nhiều. Bởi vậy, tin học thực sự không hề xa lạ với cuộc sống của chúng ta mà ngược lại chúng luôn hiện hữu, gần gũi và rất trực quan sinh động.
.................... ...............................
. ........................................ .........
....................... ............................
.... ........................................ ......
.......................... ..........................
...... ..............................................
........................................ ............
.................... ................................
........................................ ............
.................... ................................
........................................ ............
.................... ................................
........................................ ............
.................... ................................
........................................ ............
.................... ................................
........................................ ............
.................... ................................
......................................................
............................................ ........
........................ ............................
.... ........................................ ......
......................................................
.... ........................................ ......
.......................... .........................
....... ........................................ ...
............................. ...................... .......... ........................................
................................ ....................
............ ........................................
................................. ...................
............. .......................................
........................................ .............
TẠP CHÍ STEM / SỐ 01 NĂM 2016
29
LẬP TRÌNH THẬT LÀ ĐƠN GIẢN
HƯỚNG DẪN - NHẬN XÉT - LỜI GIẢI
Kỳ thi lập trình Sinh viên Quốc tế ACM/ICPC 2015 Hà Nội (Phần 2)
Đề bài: Cho N xâu con S, mỗi xâu có độ dài là 20 và một xâu lớn g có độ dài L tối đa 105. Ta nói rằng xâu con S ghép được với xâu lớn g ở vị trí i (i + 19 ≤ L) nếu có tối đa vị trí j (1 ≤ j ≤ 20) mà sj ≠ gi+j-1. Mức độ duy nhất của xâu con S là số vị trí mà xâu S ghép được với xâu lớn g. Tính mức độ duy nhất của N xâu con (1 ≤ N ≤ 104). Thuật toán: Ý tưởng ban đầu để tiếp cận bài toán là đề bài yêu cầu gì ta làm nấy. Với mỗi xâu con S và một vị trí i trong xâu g, ta kiểm tra xem có thể khớp được hay không trong O(20) bằng cách đếm số vị trí khác nhau. Nếu số vị trí khác nhau nhỏ hơn 1 thì tăng kết quả. Độ phức tạp thuật toán là O(20*N*L). Giả sử, ta thay đổi điều kiện bài toán thành: xâu con S khớp được với vị trí i của g nếu giống tất cả các ký tự. Khi đó, ta có thể dùng thuật toán hash để kiểm tra 2 xâu có giống nhau hay không trong O(1). Độ phức tạp lúc này giảm còn O(N*L). Ta có thể cải tiến thuật toán trên bằng cách sinh tất cả các mã hash của xâu con độ dài 20 trong g rồi sort lại. Lúc này để đếm xem có bao nhiêu vị trí của g khớp với S ta chỉ việc chặt nhị phân mã hash của S trong mảng chứa các mã hash của g. Vậy nên với một xâu con ta mất độ phức tạp O(logL), do đó độ phức tạp giảm còn O(N*logL).
. ........................................ .................
....................... ....................................
.... ........................................ ..............
.......................... ..................................
Mai Huy Hoàng Bài F: Genome
.................... .......................................
Quay lại bài toán ban đầu, dễ dàng nhận thấy kết quả bài toán là: Số xâu con trong g giống S hoàn toàn + Số xâu con trong g khác duy nhất một vị trí với S. Trong trường hợp thứ 2, ta hoàn toàn có thể cố định vị trí khác đó, có 20 vị trí có thể khác nhau (do độ dài xâu con là 20), và có 3 trường hợp khác ký tự (do xâu chỉ chứa 4 ký tự A, C, G, T). Vậy nên số xâu ta cần phải xét là (1+3*20)=61 xâu. Độ phức tạp tổng thể là O(61*N*logL). Trong code dưới đây mình chỉ hash với 1 khóa 109+7, tuy nhiên có thể sinh ra test để hash với khóa này sai. Bạn đọc nên hash thêm 1 khóa nữa để đảm bảo accept.
...... ......................................................
........................................ ....................
.................... ........................................
........................................ ....................
.................... ........................................
........................................ ....................
.................... ........................................
........................................ ....................
.................... ........................................
........................................ ....................
.................... ........................................
........................................ ....................
Code:
.................... ........................................ .............................................................
#include <bits/stdc++.h> using namespace std; const int L = int(1e5) + 10; const int N = int(1e4) + 10; const int p = int(1e9) + 7; // const char a[4] = {‘A’, ‘C’, ‘G’, ‘T’}; int n, l; string s[N], g; long long h[L], pw[L]; vector<long long> hashTable; int ord(char ch) { // Đổi kí tự ra hệ cơ số 4 if (ch == ‘A’) return 0; if (ch == ‘C’) return 1; if (ch == ‘G’) return 2; return 3; }
............................................ ................
........................ ....................................
.... ........................................ .............. .............................................................
.... ........................................ ..............
.......................... .................................
....... ........................................ ...........
............................. ..............................
.......... ........................................ ........
................................ ............................
............ ........................................ .......
................................. ...........................
long long getHash(int i, int j) { // Trả về mã hash của xâu con g[i..j]
............. ........................................... ... ........................................ ....................
30
TẠP CHÍ STEM / SỐ 01 NĂM 2016
LẬP TRÌNH THẬT LÀ ĐƠN GIẢN
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.................... .......................................
return (h[j] - ((h[i-1] * pw[20]) % p) + p) % p; } void initHash() { pw[0] = 1; // Khởi tạo mảng 4^i mod p for(int i = 1; i < l; i++) { h[i] = (h[i-1] * 4 + ord(g[i])) % p; // h[i] là mã hash của g[1..i] pw[i] = (pw[i-1] * 4) % p; } for(int i = 1; i < l-19; i++) hashTable. push_back(getHash(i, i + 19)); // Xây dựng mảng hashTable chứa mã hash sort(hashTable.begin(), hashTable. end()); // sort mảng hashTable } int countHash(string s) { // Đếm số vị trí trong xâu g mà khớp hoàn toàn với xâu s long long hashNumber = 0; for(int i = 1; i <= 20; i++) hashNumber = (hashNumber * 4 + ord(s[i])) % p; // Tính mã hash của s return upper_bound(hashTable.begin(), hashTable.end(), hashNumber) - lower_ bound(hashTable.begin(), hashTable.end(), hashNumber); // Hàm chặt nhị phân trả về số giá trị = hashNumber } int main() { ios_base::sync_with_stdio(false); cin >> n; for(int i = 1; i <= n; i++) cin >> s[i], s[i] = ‘ ‘ + s[i]; // Do string trong C++ đánh số từ 0 nên chèn thêm 1 kí tự ‘ ‘ vào đầu để xâu đánh số từ 1 cin >> g; g = ‘ ‘ + g; l = g.size(); initHash(); // Thủ tục sinh ra các mã hash của xâu con độ dài 20 trong g for(int i = 1; i <= n; i++) { int ans = countHash(s[i]); // Trường hợp s_i không khác kí tự nào
for(int j = 1; j <= 20; j++) { // Thử từng vị trí khác nhau char backUp = s[i][j]; // Lưu lại kí tự ban đầu for(int c = 0; c < 4; c++) if (backUp != a[c]) { // Thử 3 kí tự còn lại s[i][j] = a[c]; // Thay thế ans += countHash(s[i]); // Tăng kết quả } s[i][j] = backUp; // Trả về kí tự ban đầu } cout << ans << “\n”; } }
. ........................................ .................
....................... ....................................
.... ........................................ ..............
.......................... ..................................
...... ......................................................
........................................ ....................
.................... ........................................
........................................ ....................
.................... ........................................
........................................ ....................
.................... ........................................
........................................ ....................
Bài H: Salary Adjustment
.................... ........................................
Cho dãy s có n+2 phần tử, trong đó s0 bé hơn các số và sn+1 lớn hơn các số trong dãy 1..n. Mỗi vị trí i có pi bước nhảy tăng và qi bước nhảy giảm. Bước nhảy tăng ở vị trí i sẽ nhảy sang vị trí k gần nhất bên phải i sao cho si<sk. Nếu i = n+1 thì bước nhảy không có tác dụng.
........................................ ....................
.................... ........................................
........................................ ....................
.................... ........................................ .............................................................
Bước nhảy giảm ở vị trí i sẽ nhảy sang vị trí r gần nhất bên trái i sao cho sr<si. Nếu i=0 thì bước nhảy không có tác dụng.
............................................ ................
Với mỗi vị trí i, tính xem có thể đến được vị trí có giá trị lớn nhất là bao nhiêu sau pi bước tăng và qi bước giảm theo thứ tự bất kỳ.
.... ........................................ ..............
........................ ....................................
.............................................................
.... ........................................ ..............
.......................... .................................
Thuật toán:
....... ........................................ ...........
............................. ..............................
Ý tưởng: Với mỗi vị trí i, ta sẽ thực hiện tất cả các bước nhảy giảm trước, sau đó mới thực hiện bước nhảy tăng. Vị trí cuối cùng sẽ là vị trí có giá trị lớn nhất có thể đạt được. Bạn đọc có thể tự chứng minh ý tưởng này bằng một vài ví dụ đơn giản. Phần sau đây mình sẽ trình bày cách nhảy như thế nào.
.......... ........................................ ........
................................ ............................
............ ........................................ .......
................................. ...........................
............. ........................................... ... ........................................ ....................
TẠP CHÍ STEM / SỐ 01 NĂM 2016
31
LẬP TRÌNH THẬT LÀ ĐƠN GIẢN Với mỗi vị trí i từ 1..n, ta cần biết xem sau khi nhảy qi bước về bên trái thì sẽ ở vị trí j nào, sau đó từ vị trí j cần biết xem nhảy pi bước về bên phải thì dừng ở vị trí k nào thì k chính là kết quả tương ứng với vị trí i. Từ vị trí i ta có thể tìm được vị trí gần nhất bên trái nhỏ hơn i và vị trí gần nhất bên phải lớn hơn i bằng stack, cụ thể là thuật toán Histogram. Gọi Li và Ri là 2 vị trí tương ứng bên trái và bên phải i. Ta có thể suy ra khi thực hiện bước nhảy trái thì sẽ nhảy tới vị trí L[L[L[…L[i]]]]. Độ phức tạp để thực hiện q bước nhảy giảm là O(q), tương tự với bước nhảy tăng. Ta có thể giảm độ phức tạp nhảy còn O(logN) bằng cách dùng RMQ như sau: Gọi f[i][j]=k là vị trí sau khi thực hiện 2j bước nhảy bắt đầu từ i. Có thể tính được mảng f từ 1..n như sau: f[i][0]= L[i], f[i][j]=f[f[i][j-1]][j-1]. Tương tự có thể tính được mảng g[i][j] với các bước nhảy phải. Để thực hiện q bước nhảy sang bên trái, ta có thể tách thành thực hiện log(q) bước nhảy, mỗi bước nhảy có độ dài là 2j như RMQ. Độ phức tạp chung là O(N logN). Đó là một cách làm, ngoài ra còn có cách làm độ phức tạp O(N) như sau: Khi sử dụng stack để tính mảng Li, ta biết được st có top phần tử sau khi đẩy i vào. Có thể suy ra được thực hiện 1 bước nhảy từ i sẽ nhảy đến st[top-1], 2 bước nhảy sẽ là st[top-2]…, qi bước nhảy sẽ là st[top-qi]. Ta sẽ sử dụng một danh sách tương ứng với mỗi vị trí i để chỉ ra có bao nhiêu vị trí khác mà sau khi thực hiện bước nhảy trái sẽ dừng tại i. Sau đó xây dựng stack để tính R, ta đồng thời có thể tính được luôn kết quả. Do để xác định sau khi nhảy pi và qi sẽ dừng ở đâu chỉ mất O(1) nên độ phức tạp là O(N).
32
TẠP CHÍ STEM / SỐ 01 NĂM 2016
Code:
.................... .......................................
. ........................................ .................
#include <bits/stdc++.h> using namespace std; const int N = int(2e5) + 10; int s[N], p[N], q[N], n, nTest; vector<int> Q[N]; int st[N], top, ans[N]; void goLeft()
....................... ....................................
.... ........................................ ..............
.......................... ..................................
...... ......................................................
........................................ ....................
.................... ........................................ { s[0] = 0; s[n+1] = int(1e9) + 1; ........................................ .................... st[0] = 0; top = 0; .................... ........................................ for(int i = 1; i <= n; i++) { while (top && s[st[top]] >= s[i]) top--; ........................................ .................... st[++top] = i; int j = st[max(0, top - q[i])]; .................... ........................................ Q[j].push_back(i); ........................................ .................... } .................... ........................................ } void goRight() { ........................................ .................... st[0] = n+1; top = 0; for(int i = n; i >= 0; i--) { .................... ........................................ while (top && s[st[top]] <= s[i]) top--; ........................................ .................... st[++top] = i; for(int j = 0; j < Q[i].size(); j++) { .................... ........................................ int u = Q[i][j]; ............................................................. ans[u] = st[max(0, top - p[u])]; } ............................................ ................ } ........................ .................................... } int main() .... ........................................ .............. { ............................................................. ios_base::sync_with_stdio(false); ifstream cin(“input.txt”); .... ........................................ .............. //ofstream cout(“output.txt”); .......................... ................................. cin >> nTest; for(int iTest = 1; iTest <= nTest; iTest++) ....... ........................................ ........... { ............................. .............................. cin >> n; for(int i = 1; i <= n; i++) cin >> s[i]; .......... ........................................ ........ for(int i = 1; i <= n; i++) cin >> p[i]; ................................ ............................ for(int i = 1; i <= n; i++) cin >> q[i]; goLeft(); ............ ........................................ ....... goRight(); ................................. ........................... for(int i = 1; i <= n; i++) cout << ans[i] << ‘ ‘; cout << “\n”; ............. ........................................... ... } } ........................................ ....................
LẬP TRÌNH THẬT LÀ ĐƠN GIẢN
Giải đáp
.................... .......................................
. ........................................ .................
....................... ....................................
tháng 12 2015 Đội tuyển ACM (Dành cho học sinh THCS) Thuật toán: Dễ thấy rằng khi ta chia dãy N bài toán thành ba phần (i, j, k) với 1 ≤ i < j < k ≤ N thì các phương án chia các bài cho ba người là hoán vị của (i, j, k) và kết quả là tổng độ khó nhỏ nhất tính trên 6 hoán vị này. Nên chúng ta sẽ phải quy hoạch động trên 6 hoán vị của ba dãy a, b, c tương ứng là 3 dãy độ khó ước tính bởi Stjepan, Ivan và Gustav. Xét trên một hoán vị, gồm 3 dãy a, b, c. Gọi: - F[1][i] là tổng độ khó nhỏ nhất của i bài toán đầu tiên nếu chỉ phân người thứ nhất làm. - F[2][i] là tổng độ khó nhỏ nhất của i bài toán đầu tiên nếu chia i bài toán thành 2 phần và cho người thứ nhất làm phần đầu và người thứ hai làm phần cuối. - F[3][i] là tổng độ khó nhỏ nhất của i bài toán đầu tiên nếu chia i bài toán thành 3 phần và cho người thứ nhất làm phần đầu và người thứ hai làm phần giữa và người thứ ba làm phần cuối. Như vậy, ta có công thức quy hoạch động là: F[1][i] = a[i] + F[1][i-1] với i: 1, 2, .., N F[2][i] = b[i] + F[1][i-1] với i = 2 (do bài 1 phải phân công cho người thứ nhất) F[2][i] = min(b[i] + F[1][i-1], b[i] + F[2][i-1]) với 3 ≤ i ≤ N (do có 2 trường hợp là đến i mới phần bài i cho người thứ 2 hoặc đã phân từ trước đó).
.... ........................................ ..............
Nguyễn Quốc Hưng
Tương tự: F[3][i] = c[i] + F[2][i-1] với i = 3 F[3][i] = min(c[i] + F[2][i-1], c[i] + F[3][i-1]) với 4 ≤ i ≤ N. Kết quả cho hoán vị a, b, c là F[3][N]. Thực hiện với 6 hoán vị, ta sẽ có kết quả của bài toán. Chương trình mẫu dùng ngôn ngữ C++ : #include <cstdio> #include <algorithm> #include <cstring> #include <cassert> #include <iostream> #include <vector> #include <map> #include <set> #include <cmath> #include <cstdlib> #include <array> #include <type_traits> #include <queue> #include <stack> #include <functional> using namespace std; #define LOG(l, x) if (l <= LOGLEVEL) cout << x << endl #define int64 long long #define repeat(x) for (auto repeat_var = 0; repeat_var < x; ++repeat_var) #define for_inc(i, x) for (auto i = 0; i < x; ++i) #define for_dec(i, x) for (auto i = x - 1; i >= 0; --i) #define for_inc_range(i, x, y) for (auto i = x; i <= y; ++i) #define for_dec_range(i, x, y) for (auto i = x; i >= y; --i)
.......................... ..................................
...... ......................................................
........................................ ....................
.................... ........................................
........................................ ....................
.................... ........................................
........................................ ....................
.................... ........................................
........................................ ....................
.................... ........................................
........................................ ....................
.................... ........................................
........................................ ....................
.................... ........................................ .............................................................
............................................ ................
........................ ....................................
.... ........................................ .............. .............................................................
.... ........................................ ..............
.......................... .................................
....... ........................................ ...........
............................. ..............................
.......... ........................................ ........
................................ ............................
............ ........................................ .......
................................. ...........................
............. ........................................... ... ........................................ ....................
TẠP CHÍ STEM / SỐ 01 NĂM 2016
33
LẬP TRÌNH THẬT LÀ ĐƠN GIẢN #define fill0(x) memset(x, 0, sizeof(x)) #define INT_INF ((int)2E9L) #define INT64_INF ((int64)1E18L) #define MOD 1000000007 int MODP(int64 x) { int r = x % MOD; if (r < 0) r += MOD; return r; } int n; int solve(const vector<int> &a, const vector<int> &b, const vector<int> &c) { vector<int> f[4]; for_inc_range(k, 1, 3) { f[k].resize(n + 1); } f[1][0] = 0; for_inc_range(i, 1, n) { f[1][i] = a[i] + f[1][i - 1]; } for_inc_range(i, 2, n) { f[2][i] = b[i] + f[1][i - 1]; if (i > 2) { f[2][i] = min(f[2][i], b[i] + f[2] [i - 1]); } } for_inc_range(i, 3, n) { f[3][i] = c[i] + f[2][i - 1]; if (i > 3) { f[3][i] = min(f[3][i], c[i] + f[3] [i - 1]); } } return f[3][n]; } int main() { ios::sync_with_stdio(false); freopen(“acm.inp”, “r”, stdin); freopen(“acm.out”, “w”, stdout); cin >> n; vector<int> a( n + 1), b( n + 1), c( n + 1); for_inc_range(i, 1, n) cin >> a[i]; for_inc_range(i, 1, n) cin >> b[i]; for_inc_range(i, 1, n) cin >> c[i]; int ret = INT_INF; ret = min(ret, solve(a, b, c)); ret = min(ret, solve(a, c, b));
ret = min(ret, ret = min(ret, ret = min(ret, ret = min(ret, cout << ret << return 0;
solve(b, solve(b, solve(c, solve(c, endl;
a, c, a, b,
c)); a)); b)); a));
}
.................... .......................................
. ........................................ .................
....................... ....................................
.... ........................................ ..............
.......................... ..................................
...... ......................................................
NHỮNG CHIẾC CHÌA KHÓA – KRIZA (Dành cho học sinh THPT)
........................................ ....................
.................... ........................................
Thuật toán:
........................................ ....................
Với 40% số điểm, ta có thể dùng một thuật toán là O(N*K) với mỗi cánh cửa ta chỉ cần duyệt qua tối đa N chìa khóa để thử cho cánh cửa này.
.................... ........................................
........................................ ....................
.................... ........................................
........................................ ....................
Để được tối đa điểm cho bài này, chúng ta cần để ý rằng, các trạng thái của vòng chìa khóa sẽ lặp lại theo chu kỳ là N vì chỉ có N cánh cửa và N chìa. Ví dụ với mẫu thử thứ 2, trạng thái của vòng chìa khóa là:
.................... ........................................
........................................ ....................
.................... ........................................
........................................ ....................
.................... ........................................ .............................................................
Lần thứ nhất, mở và khóa cửa thứ nhất – dãy chìa khóa (từ trái qua phải): 4 2 1 3. Lần thứ hai, mở và khóa cửa thứ hai – dãy chìa khóa (từ trái qua phải): 1 3 4 2. Lần thứ ba, mở và khóa cửa thứ ba – dãy chìa khóa (từ trái qua phải): 2 1 3 4. Lần thứ tư, mở và khóa cửa thứ tư – dãy chìa khóa (từ trái qua phải): 3 4 2 1. Lần thứ năm, mở và khóa cửa thứ năm – dãy chìa khóa (từ trái qua phải): 4 2 1 3. Lần thứ sáu, mở và khóa cửa thứ sáu – dãy chìa khóa (từ trái qua phải): 1 3 4 2. Bạn đọc có thể tải chương trình tại địa chỉ:
https://goo.gl/PhyMoz.
............................................ ................
........................ ....................................
.... ........................................ .............. .............................................................
.... ........................................ ..............
.......................... .................................
....... ........................................ ...........
............................. ..............................
.......... ........................................ ........
................................ ............................
............ ........................................ .......
................................. ...........................
............. ........................................... ... ........................................ ....................
34
TẠP CHÍ STEM / SỐ 01 NĂM 2016
LẬP TRÌNH THẬT LÀ ĐƠN GIẢN
số Xuân 2016 Nguyễn Quốc Hưng
.................... .......................................
. ........................................ .................
....................... ....................................
.... ........................................ ..............
.......................... ..................................
...... ......................................................
........................................ ....................
.................... ........................................
GIÁ TRỊ TRUNG BÌNH CỦA DÃY CON - PROSJEK
TÌM CÂY KHUNG - GRID MST
(Dành cho học sinh THCS)
(Dành cho học sinh THPT)
Bạn được cho một mảng N số nguyên. Yêu cầu được đưa ra là tìm một dãy con liên tiếp có độ dài ít nhất là K và có giá trị trung bình lớn nhất có thể.
Đây là một vấn đề rất đơn giản. Bạn được cho N điểm và một vài điểm có thể trùng nhau. Trọng số là khoảng cách giữa hai điểm được tính bằng khoảng cách Manhattan giữa hai điểm. Yêu cầu tìm cây khung có trọng số nhỏ nhất của N điểm này.
Lưu ý: Giá trị trung bình của một dãy số là thương của tổng của tất cả các số trong dãy chia cho chiều dài của dãy đó. Dữ liệu: Vào từ tệp PROSJEK.INP • Dòng đầu tiên chứa hai số nguyên N (1 ≤ N ≤ 3*105) và K (1 ≤ K ≤ N). • Dòng thứ hai chứa N số nguyên ai (1 ≤ ai ≤ 106). Kết quả: Ghi ra tệp PROSJEK.OUT • Dòng duy nhất của đầu ra là trung bình tối đa có thể. Sai số cho phép ± 0.001. Có 30% tổng số điểm với N không lớn hơn 5000.
........................................ ....................
.................... ........................................
Chú ý: Khoảng cách Manhattan giữa hai điểm có tọa độ (x, y) và (u, v) được tính bởi công thức: D = |x - u| + |y - v|.
........................................ ....................
.................... ........................................
........................................ ....................
.................... ........................................
........................................ ....................
.................... ........................................
........................................ ....................
.................... ........................................
Dữ liệu: Vào từ tệp GRIDMST.INP • Dòng đầu tiên là số nguyên N (1≤N≤100000), số lượng điểm. • N dòng tiếp theo, mỗi dòng là hai số nguyên x, y (0 ≤ x, y ≤ 1000), là tọa độ của mỗi điểm.
.............................................................
............................................ ................
........................ ....................................
.... ........................................ ..............
Kết quả: Ghi ra tệp GRIDMST.OUT • Ghi trên một dòng với một số nguyên là trọng số nhỏ nhất của cây khung tìm được.
.............................................................
.... ........................................ ..............
.......................... .................................
PROSJEK.INP 41 1234 42 2434 63 712136
PROSJEK.OUT 4 3.666666 3.333333
GRIDMST.INP
4 00 01 10 11 5 00 10 0 10 0 11 1 12 2
GRIDMST.OUT
3
....... ........................................ ...........
............................. ..............................
.......... ........................................ ........
................................ ............................
14
............ ........................................ .......
................................. ...........................
............. ........................................... ... ........................................ ....................
TẠP CHÍ STEM / SỐ 01 NĂM 2016
35
THẾ GIỚI MỞ
Luyện toán cùng
Tux of MATH COMMAND
Nguyên Ân
C
ác em nhỏ còn nhớ phần mềm nguồn mở Tuxpaint - một công cụ hướng dẫn các em học vẽ đã được Tạp chí đăng tải trên số báo tháng 11.2014. Đây là công cụ nằm trong dự án Tux4kids với nhiều phần mềm nguồn mở hữu ích cho học sinh. Trên số này, Tạp chí sẽ giới thiệu đến các bạn phần mềm Tux of Math Command - đây cũng là phần mềm nằm trong dự án Tux4kids. Phần mềm được thiết kế cho trẻ em từ 5 đến 10 tuổi giúp các em học sinh ôn luyện các phép toán cộng, trừ, nhân, chia và nhiều phép toán khác.
mềm cung cấp các chức năng như Play Alone (Chơi 1 mình), Network Game (Trò chơi được kết nối qua mạng), Play With Friends (Chơi cùng bạn bè), Fractoroids (Trò chơi học toán trong không gian vũ trụ)... và còn nhiều chức năng giúp các bạn nhỏ ôn luyện toán. Để lựa chọn các chức năng này, các bạn kích chuột lên từng nút lệnh trên giao diện chương trình.
Các bạn có thể tải phần mềm tại địa chỉ: http://sourceforge.net/projects/tuxmath/ và cài đặt để bắt đầu sử dụng phần mềm. Một số tính năng của phần mềm: Phần mềm cung cấp các dạng bài luyện được mô phỏng theo các trò chơi toán học vui nhộn. Học sinh được thực hành và ôn luyện các phép toán như: Cộng, Trừ, Nhân, Chia và các phép toán với số nguyên... qua các trò chơi mô phỏng về hệ thống phá hủy những tảng thiên thạch đang trôi nổi trên không gian vũ trụ , qua đó giúp học sinh ôn luyện các phép toán. Ngoài ra, phần mềm có chức năng mới kết nối nhiều người chơi trên cùng mạng hệ thống. Công cụ nhỏ gọn này còn được dịch sang 40 ngôn ngữ và có thể chạy trên các hệ điều hành như: Windows, Linux/Unix, Mac OS-X. Sau khi cài đặt và chạy chương trình, giao diện màn hình sẽ như hình vẽ. Các bạn có thể lựa chọn nút lệnh để bắt đầu vào ôn luyện và học toán. Phần
36
TẠP CHÍ STEM / SỐ 01 NĂM 2016
Nếu các em học sinh Tự ôn luyện, các em kích chọn lên nút lệnh Play Alone, sau đó các em bạn chọn lên từng mục Math Command Training Academy, Math Command Fleet Missions, Play Arcade Game...
THẾ GIỚI MỞ Sau đó, bạn tiếp tục lựa chọn các chủ điểm phạm vi kiến thức, các phép toán đã được chương trình cung cấp bao gồm các bài tập cộng, trừ, nhân chia trên phạm vi các số... và bài tập về luyện bảng cửu chương để các em ôn luyện.
Một điểm đặc biệt của phần mềm là các thầy cô giáo, phụ huynh có thể tạo một máy chủ với các bài tập trong phạm vi kiến thức ôn luyện. Với chức năng này, thầy cô giáo có thể tạo những bài kiểm tra nhanh trên lớp cho các bạn học sinh. Để thực hiện, Thầy cô chọn mục Network Game và thiết lập hệ thống server bằng cách chọn Run Server, sau đó, nhập tên vào mục Server Name. Cuối cùng, thầy cô và các phụ huynh lựa chọn mục phạm vi kiến thức của chương trình để đưa vào server bài tập ôn luyện cho học sinh.
Học sinh THCS cũng có thể làm quen và ôn luyện với các phép toán cộng, trừ, nhân, chia trong tập hợp số nguyên, trong đó, có các phép toán với các số nguyên dương và nguyên âm....
Sau khi thầy cô giáo tạo được hệ thống Server, các bạn học sinh muốn ôn luyện, lựa chọn mục Join Game, chương trình sẽ tự động đưa các bạn vào Hệ thống Server mà giáo viên vừa tạo. Học sinh nhập tên của mình và kích vào biểu tượng nút lệnh Play trên màn hình và bắt đầu làm bài kiểm tra.
Các bạn cũng có thể lựa chọn các phần Play Arcade Game và Play Custom Game để vừa học và chơi. Đây là hai phần kiến thức toán tổng hợp được mô phỏng thành trò chơi để học sinh ôn luyện lại toàn bộ kiến thức sau khi các bạn đã học trên từng bài học.
Và còn rất nhiều những tính năng hay khác trên phần mềm Tux of Math Command, thầy cô giáo có thể tìm hiểu thêm để hỗ trợ các bạn học sinh ôn luyện toán học. Đây thực sự là một công cụ hữu ích dành cho các bạn học sinh. Hãy cùng tải về, cài đặt và sử dụng để tăng khả năng tư duy tính toán của các em nhé.
TẠP CHÍ STEM / SỐ 01 NĂM 2016
37
?
HỌ ĐÃ LÀM ĐIỀU ĐÓ NHƯ THẾ NÀO
Trích: Tập làm nhà phát minh Công ty cổ phần văn hóa Long Minh
38
TẠP CHÍ STEM / SỐ 01 NĂM 2016
HỌ ĐÃ LÀM ĐIỀU ĐÓ NHƯ THẾ NÀO
TẠP CHÍ STEM / SỐ 01 NĂM 2016
?
39
?
40
HỌ ĐÃ LÀM ĐIỀU ĐÓ NHƯ THẾ NÀO
TẠP CHÍ STEM / SỐ 01 NĂM 2016
HỌC QUA HÀNH
Trích: Tập làm nhà phát minh Công ty cổ phần văn hóa Long Minh
TẠP CHÍ STEM / SỐ 01 NĂM 2016
41
HỌC QUA HÀNH
CÂU CHUYỆN 1001 ĐÊM KHOA HỌC Nhật Vinh (dịch) Trích nguồn: http://Savoir-sans-frontieres.com
42
TẠP CHÍ STEM / SỐ 01 NĂM 2016
HỌC QUA HÀNH
TẠP CHÍ STEM / SỐ 01 NĂM 2016
43
HỌC QUA HÀNH
44
TẠP CHÍ STEM / SỐ 01 NĂM 2016
HỌC QUA HÀNH
TẠP CHÍ STEM / SỐ 01 NĂM 2016
45
VẠN VẬT KẾT NỐI
TẠO MỘT NHIỆT KẾ
ĐỌC NHANH Thu Trang (dịch) Nguồn: John Boxall, Arduino Workshop
C
ác bạn đều đã biết đến chiếc nhiệt kế rồi phải Lưu ý rằng cảm biến nhiệt độ TMP36 nhìn giống như không nhỉ, một thiết bị có công dụng rất hữu ích transistor BC548 được minh họa trong hình 2. được sử dụng để đo nhiệt độ. Trên số báo đầu Xuân này, chuyên mục Vạn Vật kết nối sẽ hướng dẫn các bạn tạo ra chiếc nhiệt kế thông minh này nhé. Nhiệt độ có thể được biểu diễn bởi một tín hiệu tương tự. Chúng ta có thể đo nhiệt độ bằng cách sử dụng cảm biến nhiệt độ đầu ra kiểu điện áp TMP36 của Analog Devices (bạn đọc có thể tìm hiểu tại địa chỉ http://www.analog.com/tmp36/), được miêu tả trong hình 1.
Hình 2: Transistor phổ thông BC548 Cảm biến nhiệt độ TMP36 xuất ra một điện áp tỷ lệ thuận với nhiệt độ, do đó, chúng ta có thể xác định nhiệt độ hiện tại bằng một phép chuyển đổi đơn giản. Ví dụ, ở mức 25 độ C, điện áp đầu ra là 750 mV, và khi nhiệt độ thay đổi 1 độ C sẽ làm cho điện áp thay đổi 10 mV. Cảm biến nhiệt độ TMP36 có thể đo nhiệt độ trong khoảng từ −40 đến 125 độ C.
Hình 1: Cảm biến nhiệt độ TMP36
46
TẠP CHÍ STEM / SỐ 01 NĂM 2016
Hàm analogRead() sẽ trả về giá trị giữa 0 và 1023, tương ứng với điện áp giữa 0 và 5000 mV (5V). Nếu chúng ta nhân kết quả của analogRead() với (5000/1024), chúng ta nhận được mức điện áp đầu ra của cảm biến. Tiếp theo, ta trừ đi 500 (lượng bù của cảm biến TMP36 để cho phép đọc các mức
VẠN VẬT KẾT NỐI nhiệt độ âm) và sau đó chia cho 10 để có kết quả Chương trình Arduino nhiệt độ theo đơn vị độ C. Nếu cần đơn vị đo nhiệt độ Chương trình Arduino sẽ được lập trình như ở trang là độ F, thì ta nhân giá trị độ C với 1,8 rồi cộng với 32. sau: Mục tiêu Trong dự án này, chúng ra sẽ sử dụng cảm biến nhiệt độ TMP36 để tạo ra một nhiệt kế đọc nhanh. Khi nhiệt độ xuống dưới 20 độ C, đèn LED xanh da trời sẽ sáng. Khi nhiệt độ ở mức 20-26 độ C, đèn LED xanh lá cây sẽ sáng và khi nhiệt độ trên 26 độ C thì đèn LED đỏ sẽ sáng.
Đầu tiên, chương trình đọc mức điện áp từ cảm biến nhiệt độ TMP36 và chuyển sang đơn vị đo nhiệt độ là độ C ở . Tiếp theo, sử dụng cấu trúc if-else ở và , đoạn chương trình so sánh nhiệt độ hiện tại với giá trị ngưỡng nóng và lạnh để bật đèn LED phù hợp. Câu lệnh delay(1000) được dùng để tránh việc đèn LED nhấp nháy quá nhanh nếu nhiệt độ thay đổi nhanh giữa hai dải nhiệt độ.
Phần cứng
Mở rộng sáng tạo
Dưới đây là những linh kiện cần thiết để chúng ta có thể thực hiện dự án này:
Nào, chúng ta cùng thử tạo sản phẩm nhiệt kế đơn giản bằng Arduino từ bài hướng dẫn này các bạn nhé. Đặc biệt, các bạn có thể dựa trên dự án này để tạo ra các sản phẩm khác sáng tạo hơn. Ví dụ bạn có thể thêm bộ công tắc PowerSwitch Tail, như mô tả trong hình vẽ dưới.
• Ba điện trở 560 Ω (R1 đến R3) • Một đèn LED đỏ (LED1) • Một đèn LED xanh lá cây (LED2) • Một đèn LED xanh da trời (LED3) • Một cảm biến nhiệt độ TMP36 • Một bảng cắm mạch • Một số dây nối • Mạch Arduino và dây cáp USB
Sơ đồ mạch Mạch điện rất đơn giản. Khi chúng ta nhìn vào mặt in chữ của cảm biến nhiệt độ TMP36, chân bên trái kết nối với mức 5V, chân ở giữa là đầu ra điện áp và chân bên phải kết nối với GND như mô tả trong hình 3.
Hình 4: Công tắc cho điện áp PowerSwitch Tail đến 120V AC Với PowerSwitch Tail, chúng ta có thể điều khiển một cách an toàn một thiết bị chạy từ ổ điện, chẳng hạn như một máy sưởi, đèn hoặc một thiết bị khác bằng đầu ra số từ Arduino. (Để biết thêm thông tin chi tiết, các bạn có thể tham khảo tại địa chỉ http://www.adafruit.com/products/268/) Ví dụ, bạn có thể sử dụng PowerSwitch Tail để tạo nên một máy sưởi hoặc quạt hoạt động theo nhiệt độ, điều khiển một đèn gara để nó sáng trong một khoảng thời gian rồi tắt hoặc đều khiển đèn giáng sinh ngoài trời từ xa.
Hình 3: Sơ đồ mạch của nhiệt kế
Thật hay phải không nào, chúc các bạn thành công với những sản phẩm sáng tạo của mình với lập trình Arduino nhé. TẠP CHÍ STEM / SỐ 01 NĂM 2016
47
VẠN VẬT KẾT NỐI Chương trình Arduino // Project 8 - Creating a Quick-Read Thermometer // define the pins that the LEDs are connected to: #define HOT 6 #define NORMAL 4 #define COLD 2 float float float float float
voltage = 0; celsius = 0; hotTemp = 26; coldTemp = 20; sensor = 0;
void setup() { pinMode(HOT, OUTPUT); pinMode(NORMAL, OUTPUT); pinMode(COLD, OUTPUT); } void loop() { // read the temperature sensor and convert the result to degrees Celsius sensor = analogRead(0); voltage = (sensor*5000)/1024; // convert raw sensor value to millivolts voltage = voltage-500; // remove voltage offset celsius = voltage/10; // convert millivolts to Celsius // act on temperature range if ( celsius < coldTemp ) { digitalWrite(COLD, HIGH); delay(1000); digitalWrite(COLD, LOW); } else if ( celsius > coldTemp && celsius <= hotTemp ) { digitalWrite(NORMAL, HIGH); delay(1000); digitalWrite(NORMAL, LOW); } else { // celsius is > hotTemp digitalWrite(HOT, HIGH); delay(1000); digitalWrite(HOT, LOW); } }
48
TẠP CHÍ STEM / SỐ 01 NĂM 2016