Tải bản đầy đủ (.doc) (13 trang)

skkn cấp tỉnh tạo test chấm ngẫu nhiên bằng cách dùng hàm rand trong c

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (165.07 KB, 13 trang )

<span class="text_page_counter">Trang 1</span><div class="page_container" data-page="1">

<b>MỤC LỤC</b>

<b>I. PHẦN MỞ ĐẦU...1</b>

1.Lý do chọn đề tài...1

2.Mục đích của đề tài...1

3.Nhiệm vụ và phương pháp nghiên cứu...1

4.Điểm mới trong kết quả nghiên cứu...1

<b>II. NỘI DUNG...2</b>

1. Sinh số nguyên ngẫu nhiên trong đoạn từ [0, 32767]...2

2. Sinh số nguyên ngẫu nhiên trong đoạn từ [0, 10

<small>6</small>

]...2

3. Sinh số nguyên ngẫu nhiên trong đoạn từ [0, 10

<small>9</small>

]...2

4. Sinh số nguyên ngẫu nhiên trong đoạn từ [1, 10

<small>9</small>

]...3

5. Sinh số nguyên ngẫu nhiên trong đoạn từ [X, Y]...3

6. Sinh số nguyên ngẫu nhiên trong đoạn từ [0, 2.10

<small>9</small>

]...3

7. Sinh số nguyên ngẫu nhiên trong đoạn từ [0, 10

<small>18</small>

]...3

8. Sinh số nguyên ngẫu nhiên có giá trị tuyệt đối ≤ 2.10

<small>9</small>

...4

9. Sinh số nguyên ngẫu nhiên có giá trị tuyệt đối ≤ 10

<small>18</small>

...4

10. Sinh n số nguyên có giá trị tuyệt đối ≤ 2.10

<small>9</small>

theo cấu trúc...4

11. Sinh n số tự nhiên tăng dần (tăng không ngặt) và các số nằm trong đoạn từ [0, 2.10

<small>9</small>

]... 5

12. Sinh n số tự nhiên tăng dần (tăng ngặt) và các số nằm trong đoạn từ [0, 2.10

<small>9</small>

]...5

13. Sinh n số tự nhiên khác nhau đôi một và các số nằm trong đoạn từ [0, 2.10

<small>9</small>

]...5

14. Tạo xâu kí tự chỉ gồm các chữ cái in thường từ ‘a’ đến ‘z’...7

15. Tạo xâu kí tự chỉ gồm các chữ cái in thường từ ‘A’ đến ‘Z’...7

16. Tạo xâu kí tự chỉ gồm các chữ cái in thường và các chữ cái in hoa...7

17. Tạo xâu kí tự chỉ gồm các chữ cái in thường, các chữ cái in hoa và các chữ số...8

18. Tạo xâu kí tự chỉ gồm các chữ cái in thường, các chữ cái in hoa, các chữ số và có dấu cách trống...8

19. Tạo ra n xâu kí tự chỉ gồm các chữ cái in thường, các chữ cái in hoa và các chữ số. Mỗi xâu nằm trên 1 hàng và độ dài mỗi xâu không quá x kí tự...10

<b>III. PHẦN KẾT LUẬN...12</b>

<b>Tài liệu tham khảo...12</b>

</div><span class="text_page_counter">Trang 2</span><div class="page_container" data-page="2">

<b>I. PHẦN MỞ ĐẦU</b>

<b>1. Lý do chọn đề tài</b>

Trong quá trình tham gia giảng dạy và bồi dưỡng học sinh giỏi mơn Tinhọc thì việc tạo test để chấm bài cho học sinh là một công việc hết sức quantrọng. Khi chấm các bài tốn lập trình thi đấu trong Tin học thì chúng ta dùngtest để chấm. Để có được test chấm thì chúng ta phải tạo ra các test bằng tayhoặc bằng code tạo ra file input của bài toán, từ file input của bài tốn ta chạytrương trình code chuẩn hoặc code trâu để sinh ra file output đúng. Một bộ testchuẩn là bộ test phải vét được tất cả các trường hợp của bài tốn.

Từ các lí do trên, tơi xin trình bày sáng kiến kinh nghiệm “TẠO TESTCHẤM NGẪU NHIÊN BẰNG CÁCH DÙNG HÀM rand() TRONG C++”, đểgiúp giáo viên tạo ra được các file input đúng theo bài toán yêu cầu.

<b>2. Mục đích của đề tài</b>

Tạo test chấm bài là công việc hết sức quan trong trọng. Giúp giáo viên chấmbài một cách nhanh chóng và hiệu quả.

<b>3. Nhiệm vụ và phương pháp nghiên cứu</b>

Viết sáng kiến kinh nghiệm thường xuyên liên tục cũng là nhiệm vụ chínhtrị của mỗi giáo viên, nhưng cần phải lựa chọn phương pháp nghiên cứu đúngđắn và phù hợp với nhà trường trung học phổ thơng. Sáng kiến kinh nghiệmđang trình bày của tơi dựa theo các luận cứ khoa học hướng đối tượng, cụ thể:thuyết trình, quan sát, điều tra cơ bản, phân tích kết quả thực nghiệm sưphạm,v.v… phù hợp với bài học và môn học thuộc lĩnh vực Tin học.

<b>4. Điểm mới trong kết quả nghiên cứu</b>

Hiện nay, nhiều giáo viên ở cấp THCS và THPT đang còn chưa biết cáchtạo test để chấm bài cho học sinh. Sau khi biết tạo file input ngẫu nhiên thì cơngviệ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.

</div><span class="text_page_counter">Trang 3</span><div class="page_container" data-page="3">

<b>II. NỘI DUNG</b>

Trong C++ ta có hàm rand() sẽ cho ra giá trị ngẫu nhiên từ 0 đến 32767. Đểsau mỗi lần chạy cần kết quả khác nhau thì ta cho hàm srand(time(0)); viết trướckhi sử dụng rand(). Trong các file input được trình bày ở dưới, tôi sẽ sinh ra fileSONGUYEN.INP hoặc file XAU.INP:

<b>1. Sinh số nguyên ngẫu nhiên trong đoạn từ [0, 32767]</b>

#include <bits/stdc++.h>using namespace std;int a;

int main(){

freopen("SONGUYEN.INP","w", stdout); srand(time(0));

a= rand(); //Cho giá trị ngẫu nhiên từ 0 đến 32767 cout << a;

return 0;}

<b>2. Sinh số nguyên ngẫu nhiên trong đoạn từ [0, 10</b>

<b><small>6</small></b>

<b>]</b>

Trong C++ khơng có hàm sinh ra số đến 10

<small>6</small>

, vì vậy ta dùng mẹo như sau:rand() chỉ sinh ra được số lớn nhất là 32767. Nếu ta lấy 32767 * 32767 > 10

<small>6</small>

.Rồi dùng tính chất % N sẽ cho ra giá trị trong đoạn từ [0, N-1], muốn có giá trịtừ [0, N] thì ta lấy kết quả đó % (N+1). Ta có rand()*rand() có giá trị max <2.10

<small>9</small>

nên rand()*rand() ta khơng cần phải ép sang kiểu long long vì tích của nókhơng bị tràn số.

#include <bits/stdc++.h>const int N = 1e6+1;using namespace std;int a;

int main(){

freopen("SONGUYEN.INP","w", stdout); srand(time(0));

a= rand()*rand()% (N+1); cout << a;

return 0;}

<b>3. Sinh số nguyên ngẫu nhiên trong đoạn từ [0, 10</b>

<b><small>9</small></b>

<b>]</b>

#include <bits/stdc++.h>const int N = 1e9+1;using namespace std;int a;

int main(){

freopen("SONGUYEN.INP","w", stdout); srand(time(0));

a= rand()*rand()% (N+1);

</div><span class="text_page_counter">Trang 4</span><div class="page_container" data-page="4">

cout << a; return 0;}

<b>4. Sinh số nguyên ngẫu nhiên trong đoạn từ [1, 10</b>

<b><small>9</small></b>

<b>]</b>

#include <bits/stdc++.h>const int N = 1e9;using namespace std;int a;

int main(){

freopen("SONGUYEN.INP","w", stdout); srand(time(0));

a= rand()*rand()% N +1; cout << a;

return 0;}

<b>5. Sinh số nguyên ngẫu nhiên trong đoạn từ [X, Y]</b>

Trong đó X ≤ Y và X, Y có giá trị trong phạm vi từ 0 đến 10

<small>9</small>

. Trong ví dụsau, tôi lấy giá trị X = 10 và Y = 20 (còn nếu cần thay đổi giá trị khác thì chúngta thay giá trị của X và Y là được).

#include <bits/stdc++.h>using namespace std;int a;

int main(){

freopen("SONGUYEN.INP","w", stdout); srand(time(0));

int X = 10; int Y = 20;

a= X + rand()*rand()%(Y - X + 1); cout << a;

return 0;}

<b>6. Sinh số nguyên ngẫu nhiên trong đoạn từ [0, 2.10</b>

<b><small>9</small></b>

<b>]</b>

Trong code dưới, ta dùng 1LL (nghĩa là số 1 ở kiểu long long) để nhânvới rand() (vì rand() là kiểu int) nên tích đó sẽ ép được về kiểu long long.

#include <bits/stdc++.h>const int N = 2e9;using namespace std;int a;

int main(){

freopen("SONGUYEN.INP","w", stdout); srand(time(0));

a= 1LL*rand()*rand()*rand()%(N+1); cout << a;

return 0;}

<b>7. Sinh số nguyên ngẫu nhiên trong đoạn từ [0, 10</b>

<b><small>18</small></b>

<b>]</b>

#include <bits/stdc++.h>const long long N = 1e18;using namespace std;

</div><span class="text_page_counter">Trang 5</span><div class="page_container" data-page="5">

long long a;int main(){

freopen("SONGUYEN.INP","w", stdout); srand(time(0));

a= 1LL*rand()*rand()*rand()*rand()%(N+1); cout << a;

return 0;}

<b>8. Sinh số nguyên ngẫu nhiên có giá trị tuyệt đối ≤ 2.10</b>

<b><small>9</small></b>

Ta sẽ sinh một số nguyên ngẫu nhiên từ 0 đến 2.10

<small>9</small>

trừ đi một số nguyênngẫu nhiên trong đoạn từ 0 đến 2.10

<small>9</small>

.

#include <bits/stdc++.h>const int N = 2e9;using namespace std;int a;

int main(){

freopen("SONGUYEN.INP","w", stdout); srand(time(0));

a= 1LL*rand()*rand()*rand()%(N+1) - 1LL*rand()*rand()*rand()%(N+1); cout << a;

return 0;}

<b>9. Sinh số nguyên ngẫu nhiên có giá trị tuyệt đối ≤ 10</b>

<b><small>18</small></b>

Ta sẽ sinh một số ngẫu nhiên từ 0 đến 10

<small>18</small>

trừ đi một số ngẫu nhiên trong đoạn từ 0 đến 10

<small>18</small>

.

#include <bits/stdc++.h>const long long N = 1e18;using namespace std;

long long a;int main(){

freopen("SONGUYEN.INP","w", stdout); srand(time(0));

a= 1LL*rand()*rand()*rand()*rand()%(N+1) - 1LL*rand()*rand()*rand()*rand()%(N+1);

cout << a; return 0;}

<b>10. Sinh n số nguyên có giá trị tuyệt đối ≤ 2.10</b>

<b><small>9</small></b>

<b> theo cấu trúc</b>

Dòng đầu tiên là số nguyên dương n, dòng thứ hai là n số nguyên thỏamãn điều kiện trên và các số cách nhau bởi một dấu cách trống.

#include <bits/stdc++.h>const int N = 2e9;using namespace std;int a;

int n;int main(){

freopen("SONGUYEN.INP","w", stdout); srand(time(0));

</div><span class="text_page_counter">Trang 6</span><div class="page_container" data-page="6">

n = 100;// thay đổi giá trị của n để sinh ra các test khác nhau cout << n << "\n";

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

a = 1LL*rand()*rand()*rand()%(N+1)-1LL*rand()*rand()*rand()%(N+1); cout << a << " ";

}

return 0;}

<b>11. Sinh n số tự nhiên tăng dần (tăng không ngặt) và các số nằm trong đoạntừ [0, 2.10</b>

<b><small>9</small></b>

<b>]</b>

#include <bits/stdc++.h>const int N = 100;using namespace std;int a;

int n;int main(){

freopen("SONGUYEN.INP","w", stdout); srand(time(0));

n = 100;// thay đổi giá trị của n để sinh ra các test khác nhau cout << n << "\n";

a = 0; // thay đổi giá trị bắt đầu nếu cần. for(int i = 1; i<= n; i++){

cout << a << " ";

a = a + rand()%N; // thay đổi giá trị N nếu cần }

return 0;}

<b>12. Sinh n số tự nhiên tăng dần (tăng ngặt) và các số nằm trong đoạn từ [0,2.10</b>

<b><small>9</small></b>

<b>]</b>

#include <bits/stdc++.h>const int N = 100;using namespace std;int a;

int n;int main(){

freopen("SONGUYEN.INP","w", stdout); srand(time(0));

n = 100; // thay đổi giá trị của n để sinh ra các test khác nhau cout << n << "\n";

a = 0; // thay đổi giá trị bắt đầu nếu cần. for(int i = 1; i<= n; i++){

cout << a << " ";

a = a + rand()%N + 1; // thay đổi giá trị N nếu cần }

return 0;}

<b>13. Sinh n số tự nhiên khác nhau đôi một và các số nằm trong đoạn từ [0,2.10</b>

<b><small>9</small></b>

<b>]</b>

Để sinh ra số thứ n nó khác với n-1 số trước đó, thì ta sẽ lặp trong khi nósinh ra được số thứ n mà nó khác thì mới thốt. Như vậy n nhỏ thì chạy trongthời gian cho phép. Cịn nếu n mà lớn thì thời gian chạy rất lâu. Vì vậy để sinh

</div><span class="text_page_counter">Trang 7</span><div class="page_container" data-page="7">

ra n số nguyên đôi một khác nhau ta có mẹo như sau: Ta sinh ra một mảng tăngdần, rùi thực hiện nhiều lần phép đổi chỗ 2 vị trí trong mảng đó là được.

#include <bits/stdc++.h>const int N = 100;const int NN = 1e6;using namespace std;int a;

int n;

int b[NN+3];int main(){

freopen("SONGUYEN.INP","w", stdout); srand(time(0));

n = 100;// thay đổi giá trị của n để sinh ra các test khác nhau cout << n << "\n";

// sinh mảng b là mảng các số tăng

a = rand()%N; // thay đổi giá trị bắt đầu nếu cần. b[1] = a;

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

a = a + rand()%N + 1; // thay đổi giá trị N nếu cần b[i] = a;

}

// đổi chỗ ngẫu nhiên 2 phần tử của mảng b

int t = 1000; // thay đổi giá tri t là số lần đổi chỗ for(int i = 1; i <= t; i++)

swap(b[rand()*rand()%n+1], b[rand()*rand()%n+1]); for (int i =1; i <= n; i++)

cout << b[i] << " "; return 0;

Hoặc code tương tự khác:

#include <bits/stdc++.h>const int N = 100;const int NN = 1e6;using namespace std;int a;

int n;

int b[NN+3];int main(){

freopen("SONGUYEN.INP","w", stdout); srand(time(0));

n = 100;// thay đổi giá trị của n để sinh ra các test khác nhau cout << n << "\n";

// sinh mảng b là mảng các số tăng

a = 2e9 - rand()%N; // thay đổi giá trị bắt đầu nếu cần. b[1] = a;

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

a = a - (rand()%N + 1); // thay đổi giá trị N nếu cần b[i] = a;

}

// đổi chỗ ngẫu nhiên 2 phần tử của mảng b

int t = 1000; // thay đổi giá tri t là số lần đổi chỗ for(int i = 1; i <= t; i++)

swap(b[rand()*rand()%n+1], b[rand()*rand()%n+1]); for (int i =1; i <= n; i++)

cout << b[i] << " "; return 0;

}

</div><span class="text_page_counter">Trang 8</span><div class="page_container" data-page="8">

<b>14. Tạo xâu kí tự chỉ gồm các chữ cái in thường từ ‘a’ đến ‘z’</b>

Ta đã biết ký tự ‘a’ trong bảng mã ASCII là 97, ‘b’ là 98, … ‘z’ là 122.Nên ta sẽ sinh ngẫu nhiên các số trong đoạn [97, 122] rồi ép chúng về kiểu char.

#include <bits/stdc++.h>using namespace std;int n;

char ch;int main(){

freopen("XAU.INP","w", stdout); srand(time(0));

n = 100;// thay đổi giá trị của n để sinh ra các test khác nhau

cout << n << "\n"; // Nếu đề bài không yêu cầu in n thì ta bỏ dịng này for (int i = 1; i <= n; i ++){

ch = 97+ rand()%26; cout << ch;

}

return 0;}

#include <bits/stdc++.h>using namespace std;int n;

int main(){

freopen("XAU.INP","w", stdout); srand(time(0));

n = 100;// thay đổi giá trị của n để sinh ra các test khác nhau

cout << n << "\n"; // Nếu đề bài không yêu cầu in n thì ta bỏ dịng này for (int i = 1; i <= n; i ++)

cout << char(97+ rand()%26); return 0;

<b>15. Tạo xâu kí tự chỉ gồm các chữ cái in thường từ ‘A’ đến ‘Z’</b>

Ta đã biết ký tự ‘A’ trong bảng mã ASCII là 65, ‘B’ là 66, … ‘Z’ là 90.Nên ta sẽ sinh ngẫu nhiên các số trong đoạn [65, 90] rồi ép chúng về kiểu char.

#include <bits/stdc++.h>using namespace std;int n;

int main(){

freopen("XAU.INP","w", stdout); srand(time(0));

n = 100; // Thay đổi giá trị của n để sinh ra các test khác nhau

cout << n << "\n"; // Nếu đề bài khơng u cầu in n thì ta bỏ dịng này for (int i = 1; i <= n; i ++)

cout << char(65 + rand()%26); return 0;

<b>16. Tạo xâu kí tự chỉ gồm các chữ cái in thường và các chữ cái in hoa</b>

#include <bits/stdc++.h>using namespace std;

</div><span class="text_page_counter">Trang 9</span><div class="page_container" data-page="9">

int n, nn;

char s[300]; // khai báo thừaint main(){

freopen("XAU.INP","w", stdout); srand(time(0));

n = 100;// thay đổi giá trị của n để sinh ra các test khác nhau

cout << n << "\n"; // Nếu đề bài khơng u cầu in n thì ta bỏ dòng này nn = 0;

for (char ch = 'a'; ch <= 'z'; ch++){ nn++;

s[nn] = ch; }

for (char ch = 'A'; ch <= 'Z'; ch++){ nn++;

s[nn] = ch; }

// nn = 52;

for (int i = 1; i <= n; i++ ) cout << s[rand()%nn + 1]; return 0;

<b>17. Tạo xâu kí tự chỉ gồm các chữ cái in thường, các chữ cái in hoa và cácchữ số</b>

#include <bits/stdc++.h>using namespace std;int n, nn;

char s[300]; // khai báo thừaint main(){

freopen("XAU.INP","w", stdout); srand(time(0));

n = 100;// thay đổi giá trị của n để sinh ra các test khác nhau

cout << n << "\n"; // Nếu đề bài không yêu cầu in n thì ta bỏ dịng này nn = 0;

for(char ch = 'a'; ch <= 'z'; ch++){ nn++;

s[nn] = ch; }

for(char ch = 'A'; ch <= 'Z'; ch++){ nn++;

s[nn] = ch; }

for(char ch = '0'; ch <= '9'; ch++){ nn++;

s[nn] = ch; }

// ta tính ra được nn = 62; for (int i = 1; i <= n; i++ ) cout << s[rand()%nn + 1]; return 0;

<b>18. Tạo xâu kí tự chỉ gồm các chữ cái in thường, các chữ cái in hoa, các chữsố và có dấu cách trống</b>

#include <bits/stdc++.h>using namespace std;int n, nn;

char s[300]; // khai báo thừaint main(){

</div><span class="text_page_counter">Trang 10</span><div class="page_container" data-page="10">

freopen("XAU.INP","w", stdout); srand(time(0));

n = 100;// thay đổi giá trị của n để sinh ra các test khác nhau

cout << n << "\n"; // Nếu đề bài khơng u cầu in n thì ta bỏ dịng này nn = 0;

for(char ch = 'a'; ch <= 'z'; ch++){ nn++;

s[nn] = ch; }

for(char ch = 'A'; ch <= 'Z'; ch++){ nn++;

s[nn] = ch; }

for(char ch = '0'; ch <= '9'; ch++){ nn++;

s[nn] = ch; }

// ta tính ra được nn = 62; nn++;

#include <bits/stdc++.h>using namespace std;int n, nn;

char s[300]; // khai báo thừaint main(){

freopen("XAU.INP","w", stdout); srand(time(0));

n = 100;// thay đổi giá trị của n để sinh ra các test khác nhau

cout << n << "\n"; // Nếu đề bài khơng u cầu in n thì ta bỏ dòng này nn = 0;

for(char ch = 'a'; ch <= 'z'; ch++){ nn++;

s[nn] = ch; }

for(char ch = 'A'; ch <= 'Z'; ch++){ nn++;

s[nn] = ch; }

for(char ch = '0'; ch <= '9'; ch++){ nn++;

s[nn] = ch; }

</div>

×