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

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

13 0 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 Chấm Ngẫu Nhiên Bằng Cách Dùng Hàm Rand Trong C++
Tác giả Tác Giả Chưa Được Xác Định
Trường học Chưa Được Xác Định
Chuyên ngành Tin học
Thể loại Sáng Kiến Kinh Nghiệm
Năm xuất bản Chưa Được Xác Định
Thành phố Chưa Được Xác Định
Định dạng
Số trang 13
Dung lượng 124,5 KB

Nội dung

Lý do chọn đề tài Trong quá trình tham gia giảng dạy và bồi dưỡng học sinh giỏi môn Tin họ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 quan trọng.. Khi chấm các

Trang 1

MỤC LỤC

I PHẦN MỞ ĐẦU 1

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

II NỘI DUNG 2

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, 106] 2

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

4 Sinh số nguyên ngẫu nhiên trong đoạn từ [1, 109] 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.109] 3

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

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

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

10 Sinh n số nguyên có giá trị tuyệt đối ≤ 2.109 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.109] 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.109] 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.109] 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

III PHẦN KẾT LUẬN 12

Tài liệu tham khảo 12

Trang 2

I PHẦN MỞ ĐẦU

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

Trong quá trình tham gia giảng dạy và bồi dưỡng học sinh giỏi môn Tin họ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 quan trọng Khi chấm các bài toán lập trình thi đấu trong Tin học thì chúng ta dùng test để chấm Để có được test chấm thì chúng ta phải tạ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ừ file input của bài toán ta chạy trương trình code chuẩn hoặc code trâu để sinh ra file output đúng Một bộ test chuẩn là bộ test phải vét được tất cả các trường hợp của bài toán

Từ các lí do trên, tôi xin trình bày sáng kiến kinh nghiệm “TẠO TEST CHẤ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.

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

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ấm bài một cách nhanh chóng và hiệu quả.

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

Viết sáng kiến kinh nghiệm thường xuyên liên tục cũng là nhiệm vụ chính trị 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.

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

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

Trang 3

II NỘI DUNG

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ước khi sử dụng rand() Trong các file input được trình bày ở dưới, tôi sẽ sinh ra file SONGUYEN.INP hoặc file XAU.INP:

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

#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;

}

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

Trong C++ không có hàm sinh ra số đến 106, 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 > 106 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.109 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;

}

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

#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);

Trang 4

cout << a;

return 0;

}

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

#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;

}

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

Trong đó X ≤ Y và X, Y có giá trị trong phạm vi từ 0 đến 109 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úng

ta 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;

}

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

Trong code dưới, ta dùng 1LL (nghĩa là số 1 ở kiểu long long) để nhân vớ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;

}

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

#include <bits/stdc++.h>

const long long N = 1e18;

using namespace std;

Trang 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;

}

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

Ta sẽ sinh một số nguyên ngẫu nhiên từ 0 đến 2.109 trừ đi một số nguyên ngẫu nhiên trong đoạn từ 0 đến 2.109.

#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;

}

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

Ta sẽ sinh một số ngẫu nhiên từ 0 đến 1018 trừ đi một số ngẫu nhiên trong đoạn từ 0 đến 1018.

#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;

}

10 Sinh n số nguyên có giá trị tuyệt đối ≤ 2.109 theo cấu trúc

Dòng đầu tiên là số nguyên dương n, dòng thứ hai là n số nguyên thỏa mã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));

Trang 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;

}

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.109]

#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;

}

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.109]

#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;

}

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.109]

Để 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 thoát Như vậy n nhỏ thì chạy trong thờ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

Trang 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ăng dầ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;

}

Trang 8

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

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;

}

Hoặc:

#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;

}

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

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 yê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;

}

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

#include <bits/stdc++.h>

using namespace std;

Trang 9

int n, nn;

char s[300]; // khai báo thừa

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

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;

}

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ố

#include <bits/stdc++.h>

using namespace std;

int n, nn;

char s[300]; // khai báo thừa

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

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;

}

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

#include <bits/stdc++.h>

using namespace std;

int n, nn;

char s[300]; // khai báo thừa

int main(){

Trang 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 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;

nn++;

s[nn]= ' ';

for(int i =1; i<= nn-1; i++)

cout << s[rand()%nn+1];

cout << s[rand()%(nn-1)+1]; // in ký tự cuối không có dấu cách trống return 0;

}

Trong thực tế, nếu cần xâu đó có nhiều dấu cách trống xuất hiện thì ta có thể cho thêm nhiều dấu cách trống vào mảng s, để sinh rand() ngẫu nhiên hoặc trong lúc in ta sẽ in thêm dấu cách trống như code sau:

#include <bits/stdc++.h>

using namespace std;

int n, nn;

char s[300]; // khai báo thừa

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

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;

cout << s[rand()%nn+1]; // đảm bảo không có dấu cách ở đầu

for(int i =1; i<= nn - 1; i++){

int t = rand()%5; // % số càng nhỏ thì dấu cách càng xuất hiện nhiều

if (t==0) cout << " ";

else cout << s[rand()%nn+1];

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