1. Trang chủ
  2. » Luận Văn - Báo Cáo

skkn cấp tỉnh tạo test ngẫu nhiên cho một số bài toán ôn thi học sinh giỏi bằng ngôn ngữ lập trình c

22 1 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Tạo Test Ngẫu Nhiên Cho Một Số Bài Toán Ôn Thi Học Sinh Giỏi Bằng Ngôn Ngữ Lập Trình C++
Tác giả Trương Ngọc Huy
Trường học Trường THPT Hoằng Hóa 4
Chuyên ngành Tin học
Thể loại Sáng kiến kinh nghiệm
Năm xuất bản 2024
Thành phố Thanh Hóa
Định dạng
Số trang 22
Dung lượng 218 KB

Nội dung

SỞ GIÁO DỤC VÀ ĐÀO TẠO THANH HÓATRƯỜNG THPT HOẰNG HÓA 4 ------SÁNG KIẾN KINH NGHIỆM ĐỀ TÀI “TẠO TEST NGẪU NHIÊN CHO MỘT SỐ BÀI TOÁN ÔN THI HỌC SINH GIỎI BẰNG NGÔN NGỮ LẬP TRÌNH C++”

Trang 1

SỞ GIÁO DỤC VÀ ĐÀO TẠO THANH HÓA

TRƯỜNG THPT HOẰNG HÓA 4

- -SÁNG KIẾN KINH NGHIỆM

ĐỀ TÀI

“TẠO TEST NGẪU NHIÊN CHO MỘT SỐ BÀI TOÁN

ÔN THI HỌC SINH GIỎI BẰNG NGÔN NGỮ

LẬP TRÌNH C++”

Người thực hiện: Trương Ngọc Huy

SKKN thuộc môn: Tin học

THANH HOÁ NĂM 2024

Trang 2

MỤC LỤC

Trang

1 MỞ ĐẦU 1

1.1 Lí do chọn đề tài: 1

1.2 Mục đích nghiên cứu: 1

1.3 Đối tượng nghiên cứu: 1

1.4 Phương pháp nghiên cứu: 1

1.5 Những điểm mới của sáng kiến kinh nghiệm: 2

2 NỘI DUNG SÁNG KIẾN KINH NGHIỆM 2

2.1 Cơ sở lý luận của sáng kiến kinh nghiệm: 2

2.2 Thực trạng vấn đề trước khi áp dụng sáng kiến kinh nghiệm: 3

2.3 Các giải pháp đã sử dụng để giải quyết vấn đề: 3

2.3.1 Tạo một số, kí tự ngẫu nhiên sử dụng hàm srand và rand: 3

a Tạo một số nguyên ngẫu nhiên có giá trị thuộc đoạn [0, x]: 3

b Tạo một số nguyên ngẫu nhiên có giá trị thuộc đoạn [-x, x]: 4

c Tạo số nguyên ngẫu nhiên từ x đếm y(x<y): 4

d Tạo một kí tự ngẫu nhiên: 4

e Tạo một số thực ngẫu nhiên: 5

2.3.2 Tạo một số, xâu kí tự ngẫu nhiên sử dụng cách thức khác: 5

a Tạo số nguyên ngẫu nhiên sử dụng lớp mt19937 hoặc mt19937_64: 5

b Tạo số nguyên ngẫu nhiên sử dụng lớp default_random_engine và uniform_int_distribution: 6

c Tạo số thực ngẫu nhiên: 6

d Tạo xâu kí tự ngẫu nhiên: 6

2.3.3 Tạo mãng N số ngẫu nhiên, xâu kí tự có độ dài ngẫu nhiên: 7

a Tạo mảng a gồm N số ngẫu nhiên không âm: 7

b Tạo mảng a gồm N số ngẫu nhiên: 8

c Tạo mảng a gồm N số nguyên ngẫu nhiên từ x đến y: 8

d Tạo mảng a gồm N số thực ngẫu nhiên: 8

e Tạo xâu kí tự có độ dài ngẫu nhiên: 9

f Tạo mảng a gồm N xâu kí tự có độ dài ngẫu nhiên: 10

2.3.4 Một số bài toán hay dùng trong ôn thi học sinh giỏi: 11

Bài toán 1: Tạo mảng ngẫu nhiên tăng 11

Bài toán 2: Tạo mảng cấp số cộng 11

Bài toán 3: Tạo ngẫu nhiên mảng có tỉ lệ 1:k 12

Bài toán 4: Tạo ngẫu nhiên đều 13

Bài toán 5: Tạo xâu đối xứng ngẫu nhiên 14

2.4 Hiệu quả của sáng kiến kinh nghiệm: 15

Trang 3

3 KẾT LUẬN VÀ KIẾN NGHỊ 16

3.1 Kết luận: 16

3.2 Kiến nghị: 17

TÀI LIỆU THAM KHẢO 18

DANH MỤC 19

Trang 4

1 MỞ ĐẦU 1.1 Lí do chọn đề tài:

Trong mọi thời đại, giáo dục luôn đóng vai trò vô cùng quan trọng Đó là

nền tảng, là động lực cho sự phát triển của một quốc gia Để đào tạo thế hệ trẻ

trở thành người chủ thực sự của đất nước trong tương lai, có khả năng làm chủđược nền khoa học kỹ thuật hiện đại, thì việc đổi mới nội dung và phươngpháp dạy học là vấn đề hết sức cấp thiết Một trong những biện pháp giúp đổimới phương pháp dạy học hiện nay là ứng dụng công nghệ thông tin trong dạyhọc và trong đời sống xã hội Với sự giúp đỡ của máy vi tính và các phần mềmdạy học, giáo viên sẽ tổ chức tốt quá trình dạy học trên lớp theo hướng phát huytính tích cực, chủ động, sáng tạo trong hoạt động nhận thức của học sinh

Trong quá trình tham gia giảng dạy và bồi dưỡng học sinh giỏi môn Tinhọc ở trường, tôi thấy việc tạo test để chấm bài cho học sinh là một công việchết sức quan trọng Vì khi tham gia các kì thi liên quan đến lập trình trong Tinhọc thì chúng ta cần có test để chấm Để có được test chấm thì chúng ta phảitạo ra các test bằng tay hoặc bằng code tạo ra file input của bài toán, từ fileinput của bài toán ta chạy trương trình code chuẩn hoặc code trâu để sinh rafile output đúng Một bộ test chuẩn là bộ test phải vét được tất cả các trườnghợp của bài toán

Chính vì vậy tôi nhận thấy để đánh giá chính xác được thuật toán của 1bài toán trong Tin học có tối ưu hay không thì việc tạo test là rất quan trọng Đó

chính là lý do, tôi đã chọn đề tài " Tạo test ngẫu nhiên cho một số bài toán ôn thi học sinh giỏi bằng ngôn ngữ lập trình C++" để nghiên cứu.

1.2 Mục đích nghiên cứu:

Tạo ra một số chương trình tạo test để chấm các bài toán cơ bản và nângcao trong quá trình ôn thi học sinh giỏi Giúp học sinh tìm ra các thuật toán tối

ưu hơn và giúp giáo viên chấm bài một cách nhanh chóng và hiệu quả

1.3 Đối tượng nghiên cứu:

- Các khái niệm về hàm và các phương thức khác có liên quan đến tạo testngẫu nhiên;

- Học sinh khối 10 và một số học sinh ôn thi học sinh giỏi của trườngTHPT Hoằng Hóa 4

1.4 Phương pháp nghiên cứu:

- Tìm hiểu các hàm và các phương thức khác có liên quan đến tạo testngẫu nhiên;

- Sáng kiến kinh nghiệm của tôi đang trình bày dựa theo các phương phápnhư: Thuyết trình, quan sát, phân tích thuật toán, … phù hợp với bài học và mônhọc thuộc lĩnh vực Tin học

Trang 5

1.5 Những điểm mới của sáng kiến kinh nghiệm:

- Hiện nay có nhiều giáo viên giảng dạy môn Tin học hoặc những em họcsinh muốn học về lập trình nhưng chưa biết cách tạo test để chấm bài chochương trình của mình hay của học sinh Vì vậy khi biết tạo file input ngẫunhiên thì công việc tạo test chấm bài được thực hiện một cách nhanh chóng vàhiệu quả hơn

- Đề tài này tôi đã vận dụng thêm một số phương thức khác để tạo test

ngoài hàm rand() và vận dụng vào một số bài toán cụ thể để tạo test nhằm tối

ưu thuật toán

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:

Từ nghị quyết số 29/NQ-TW tại Hội nghị Trung ương 8 khóa XI về đổimới căn bản, toàn diện giáo dục và chỉ thị 40/CT của Ban bí thư Trung ươngĐảng, sở GD&ĐT đã tập trung chỉ đạo đổi mới các hoạt động kiểm tra, đánh giáthúc đẩy đổi mới phương pháp dạy học nhằm tạo sự chuyển biến cơ bản về tổchức hoạt động dạy học, góp phần nâng cao chất lượng giáo dục trong các nhàtrường

Môn tin học có nhiều đặc thù khác nhau, khác nhau ở từng cấp học, khốilớp Từ người bắt đầu sử dụng máy tính, đến người đã sử dụng thành thạo máytính Tuy nhiên cấp học cao hơn thì chương trình học cũng cao hơn Một sự khácbiệt nửa của môn Tin học là Lý thuyết – Bài tập – Thực hành hay nói cách khác

là Nói – Làm – Có kết quả, nói chung phải đạt cả ba Chẳng hạn dạy học lậptrình người dạy dạy lý thuyết hay, giải bài tập hay và thực hành cho kết quảminh chứng, nhưng nếu khi thực hành trên máy không cho kết quả như mongmuốn thì chữ hay đó chắc chắn không trọn vẹn

Mặt khác tuy môn Tin học mới đưa vào chương trình phổ thông bắt từnăm 2006, nhưng hiện nay có rất nhiều học sinh biết những kiến thức cơ bản vềthông tin và các công nghệ cao là những kiến thức rất cần thiết đối với mỗingười nhất là thế hệ trẻ hiện nay Vì vậy các em đã đam mê hơn với môn Tinhọc và muốn học lập trình để theo ngành công nghệ thông tin Nhưng do điềukiện kinh tế của gia đình không mua được máy tính cho học sinh cũng như cơ sởvật chất của nhà trường còn thiếu nên cơ sở vật chất để giảng dạy môn học nàycũng không dễ mua sắm Từ những bất cập đó mà trình độ hiểu biết về lập trìnhnói riêng và tin học nói chung trong nhà trường còn hạn chế

Một trong những hạn chế ở đây là học sinh sau khi lập trình giải quyếtđược 1 bài toán trong tin học nhưng không biết có đúng theo yêu cầu của bàitoán không và làm sao biết để tối ưu được thuật toán của bài toán đã cho? Điềunày đã hối thúc tôi tìm tòi và nghiên cứu để tìm ra giải pháp nhằm mục đích dạytốt hơn trong quá trình ôn thi học sinh giỏi nói riêng và học lập trình nói chungtrong nhà trường

Trang 6

2.2 Thực trạng vấn đề trước khi áp dụng sáng kiến kinh nghiệm:

Ngày nay phần lớn học sinh biết sử dụng máy tính và có máy tính cá nhânmỗi ngày một tăng, trình độ hiểu biết và sử dụng máy tính cũng tăng rõ rệt.Nhiều em đã định hướng được ngành nghề cho tương lai nên đã đam mê hơn vớimôn Tin học, nhất là lập trình giải quyết các bài toán trong Tin học Đồng thờinhiều em cũng muốn được vào đội tuyển thi học sinh giỏi cấp Tỉnh của trường

Tuy nhiên cơ sở vật chất của nhà trường không đáp ứng được các tiết thựchành và tài liệu học tập của môn Tin học trong nhà trường còn khá ít Thời gianhọc tập trên trường cũng hạn chế nên phần lớn các em học và làm bài tập ở nhànhưng không biết chương trình của mình đã đúng với yêu cầu của đề bài chưa

Chính vì vậy để biết một chương trình đã đúng chưa và làm sao để tránhsai sót và tối ưu được thuật toán thì cần phải có nhiều bộ test khác nhau và vétđược hết các trường hợp của bài toán cho Đó chính là thực trạng của của vấn đềtrước khi áp dụng sáng kiến kinh nghiệm này

2.3 Các giải pháp đã sử dụng để giải quyết vấn đề:

Trong ngôn ngữ lập trình C++ hàm rand() tạo một số nguyên ngẫu nhiên trong đoạn [0, RAND_MAX], trong đó RAND_MAX là một hằng số có sẵn có

giá trị phụ thuộc vào chương trình dịch Giá trị lớn nhất của số nguyên tạo ra bởi

rand() là RAND_MAX, thường là 32767 Dựa vào hàm rand này tôi đưa ra một

số chương trình tạo test cho một số bài tập đơn giản và nâng cao trong các bàitập bồi dưỡng học sinh giỏi Trước khi gọi hàm rand ta cần gọi hàm srand để

khởi tạo bộ số ngẫu nhiên Tuy nhiên C++ còn cung cấp nhiều cách thức để tạo

dữ liệu ngẫu nhiên khác như sử dụng lớp mt19937, mt19937_64,

default_random_engine, uniform_real_distribution, uniform_int_distribution

sẽ được tôi lồng ghép vào một số nội dung,

2.3.1 Tạo một số, kí tự ngẫu nhiên sử dụng hàm srand và rand:

a Tạo một số nguyên ngẫu nhiên có giá trị thuộc đoạn [0, x]:

freopen("SND.INP","w", stdout); //Ghi giá trị vào file SND.INP

Trang 7

b Tạo một số nguyên ngẫu nhiên có giá trị thuộc đoạn [-x, x]:

freopen("SNDXX.INP","w", stdout); //Ghi giá trị vào file SNDXX.INP

c Tạo số nguyên ngẫu nhiên từ x đếm y(x<y):

Ta có rand()%(y-x+1) tạo số nguyên ngẫu nhiên từ 0 đếm y-x do đóx+rand()%(y-x+1) tạo các số từ x đến x+y-x=y Từ nhận xét đó ta có đoạnchương trình sau:

freopen("SNDXY.INP","w", stdout); //Ghi giá trị vào file SNDXY.INP

d Tạo một kí tự ngẫu nhiên:

Ta có các kí tự trong bảng mã ASCII có mã thập phân tử 0 đến 255 do đó

ta sử dụng cách ép kiểu nguyên về kí tự Cách ép kiểu nguyên về kí tự như sau

freopen("KITU.INP","w", stdout); //Ghi giá trị vào file KITU.INP

Trang 8

freopen("SOTHUC.INP","w", stdout); //Ghi giá trị vào file SOTHUC.INP

float x = 1, y = 100;

float n = x + z*(y-x); //Tạo số thực trong đoạn [x, y](1, 100)

ôn luyện học sinh giỏi một cách dễ dàng từ đó có thể đánh giá các giải thuật củahọc sinh một cách chính xác

2.3.2 Tạo một số, xâu kí tự ngẫu nhiên sử dụng cách thức khác:

a Tạo số nguyên ngẫu nhiên sử dụng lớp mt19937 hoặc mt19937_64:

Lớp mt19937 sử dụng để tạo ra số nguyên 32-bit, lớp mt19937_64 sửdụng để tạo ra số nguyên 64-bit Sau đây là chương trình minh họa cách sửdụng 2 lớp này

Trang 9

c Tạo số thực ngẫu nhiên:

Hàm rand và lớp mt19937 chỉ tạo ra số nguyên, để tạo ra số thực bạnphải sử dụng phép nhân số nguyên tạo ra với 1.0 và sau đó chia các số tạo racho nhau Một cách khác để tạo ra số thực ngẫu nhiên là sử dụng lớp

default_random_engine, uniform_real_distribution tương tự như với sốnguyên Sau đây là chương trình minh họa tạo số thực ngẫu nhiên có giá trịtrong đoạn [1, 1000]

d Tạo xâu kí tự ngẫu nhiên:

Để tạo xâu kí tự ngẫu nhiên, ta thực hiện theo các bước như sau:

- Định nghĩa một xâu/mảng kí tự làm bảng kí tự từ điển;

- Sử dụng cấu trúc lặp gọi hàm tạo số ngẫu nhiên nhiều lần, lấy giá trị số

Trang 10

ngẫu nhiên đó chia lấy phần dư cho một số(thường là tổng số kí tự của bảng kí

tự từ điển) cho để làm chỉ số truy cập lấy kí tự ngẫu nhiên từ bảng kí tự từ điển

Sau đây là chương trình minh họa tạo ra xâu kí tự ngẫu nhiên có độ dàitối đa 100 kí tự là chữ latin viết thường và chỉ có 4 kí tự là: ‘a’, ‘b’, ‘c’, ‘d’:

string dict = "abcd"; //Từ điển

string rnds = ""; //Xâu ngẫu nhiên tạo ra

int len = mt() % 100; //Độ dài xâu

for (int i = 1; i <= len; i++){

2.3.3 Tạo mãng N số ngẫu nhiên, xâu kí tự có độ dài ngẫu nhiên:

Tạo ngẫu nhiên N số, kí tự ngẫu nhiên sử dụng kiểu dữ liệu mảng để lưu

a Tạo mảng a gồm N số ngẫu nhiên không âm:

freopen("ARRD.INP","w", stdout); //Ghi giá trị vào file ARRD.INP

int x = 100, y = 1000;

int n = rand()%(x+1);//Tạo số lượng phần tử thuộc đoạn 0 x(0 100)

cout<<n<<endl;

for(int i = 1; i <= n; i++){

a[i] = rand ()%(y+1); //Tạo số nguyên dương thuộc đoạn 0 y(0 1000) cout <<a[i]<<" ";

}

return 0;

}

Trang 11

b Tạo mảng a gồm N số ngẫu nhiên:

freopen("ARRAD.INP","w", stdout); //Ghi giá trị vào file ARRAD.INP

int x = 100, y = 1000;

int n = rand()%(x+1); //Tạo số lượng phần tử thuộc đoạn 0 x(0 100)

cout<<n<<endl;

for(int i = 1; i <= n; i++){

a[i] = rand ()%(y+1) - rand ()%(y+1); //Tạo số nguyên dương thuộc đoạn -y y(-1000 1000)

cout <<a[i]<<" ";

}

return 0;

}

c Tạo mảng a gồm N số nguyên ngẫu nhiên từ x đến y:

Dựa vào nhận xét của mục 2.3.1 c ta có thủ tục tạo n số nguyên ngẫunhiên tử x đến y(x<y) như sau:

freopen("ARRXY.INP","w", stdout); //Ghi giá trị vào file ARRXY.INP

int z = 100, x = 10, y = 1000;

int n = rand()%(z+1);//Tạo số lượng phần tử thuộc đoạn 0 z(0 100)

cout<<n<<endl;

for(int i = 1; i <= n; i++){

a[i] = x + rand()%(y-x+1); //Tạo số nguyên dương thuộc đoạn x y(10 1000)

cout <<a[i]<<" ";

}

return 0;

}

d Tạo mảng a gồm N số thực ngẫu nhiên:

Sử dụng đoạn chương trình tạo một số thực ở mục 2.3.1 e ta sẽ có một

Trang 12

mảng ngẫu nhiên gồm n số thực như sau:

freopen("ARRTHUC.INP","w", stdout); //Ghi giá trị vào file ARRTHUC.INP

int m = 100;

int n = rand()%(m+1);//Tạo số lượng phần tử thuộc đoạn 0 m(0 100)

cout<<n<<endl;

float x = 10, y = 10000;

for(int i = 1; i <= n; i++){

float z = rand()/(float) RAND_MAX; //Tạo số thực trong đoạn [0, 1.0]

a[i] = x + z*(y-x); //Tạo số thực trong đoạn [x, y](10, 10000)

cout << fixed<<setprecision(2)<<a[i]<<" ";

}

return 0;

}

e Tạo xâu kí tự có độ dài ngẫu nhiên:

Sau đây tôi sẽ đưa ra một chương trình tạo một xâu ngẫu nhiên gồm chữcái thường, Hoa và số, các trường hợp còn lại làm tương tự

freopen("XAUtHS.INP","w", stdout); //Ghi giá trị vào file XAUtHS.INP

int m = 100;

int n = rand()%(m+1); //Số lượng kí tự trong xâu

int x = 96;

for(int i = 1; i <= 26; i++){

x++; a[i] = (char)x; //Mảng kí tự in thường a z

}

x = 64;

for(int i = 27; i <= 52; i++){

x++; a[i] = (char)x; //Mảng kí tự in HOA A Z

Trang 13

for(int i = 1; i <= n; i++){

cout<<a[rand()%62 + 1]; //Tạo xâu ngẫu nhiên gồm chữ in thường, in HOA và chữ số //cout<<a[rand()%52 + 1]; //Tạo xâu ngẫu nhiên gồm chữ in thường và in HOA }

freopen("ARRXAU.INP","w", stdout); //Ghi giá trị vào file ARRXAU.INP

int x = 96;

for(int i = 1; i <= 26; i++){

x++; a[i] = (char)x; //Mảng kí tự in thường a z

}

x = 64;

for(int i = 27; i <= 52; i++){

x++; a[i] = (char)x; //Mảng kí tự in HOA A Z

int n = rand()%(z+1); //n là số lượng kí tự trong 1 xâu

int m = rand()%(y+1); //m là số lượng phần tử của mảng xâu

cout<<m<<endl;

for(int j=1; j<=m; j++) {

for(int i=1; i<=n;i++)

//cout<<a[rand()%52+1]; //Tạo 1 xâu gồm n phần tử gồm chữ cái thường và Hoa

cout<<a[rand()%62+1]; //Tạo 1 xâu gồm n phần tử gồm chữ cái thường, Hoa và số

//cout<<(char)(x+rand()%(y-x+1); //Tạo ra xâu ngẫu nhiên từ x -> y

//cout<<(char)(97+rand()%(122-97+1)); //Tạo ra xâu gồm n kí tự ngẫu nhiên từ 'a'->'z'

Ngày đăng: 13/06/2024, 20:24

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

w