1. Trang chủ
  2. » Công Nghệ Thông Tin

Tự code, tự chấm, tự sướng bí kíp thi offline

6 135 0

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

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 6
Dung lượng 24,02 KB

Nội dung

Đây là một thứ sẽ rất giúp ích cho các bạn HS chuyên tin đặc biệt là các bạn chuẩn bị thI HSG quốc gia các kĩ năng trong đây sẽ giúp các bạn rất là nhiều và nó là 1 điều ko thể thiếu với những ai sắp có kì thi HSG quóc gia sắp tới hay các cuộc thi tin như APIO,COCI,.. và cũng như trong các cuộc thi trên mạng của Online Judge như Codeforces,Atcoder,..

Tự code, tự chấm, tự sướng ­  Bí kíp thi offline  Tác giả: Vũ chipchip Phúc Hồng Bạn cảm thấy lo sợ trong những kì thi chấm offline? Bạn bình thường làm bài rất tốt  nhưng khi chấm offline lại bị điểm kém vì sai những lỗi vớ vẩn? Bạn code sai một bài rất khó và debug mãi khơng được vì khơng có test sai? Tất cả những vấn đề đó sẽ được  giải quyết đơn giản với một chương trình chấm bài tự động, giúp bạn tự kiểm tra bài  mình và phát hiện test sai. Bài viết này sẽ giới thiệu với bạn những bước cơ bản nhất  để viết trình chấm ­ một kĩ thuật mà bạn nên thành thạo trước khi thi HSG Quốc gia Table of Contents     o o o o  o o o  o o o  Trình chấm là gì? Tại sao nên viết trình chấm? Khi nào nên viết trình chấm? Thành phần của một bộ trình chấm Lời giải 1: Lời giải 2: Trình sinh test: Trình so test: Ví dụ: Bài VMELLIP Lời giải 1: Lời giải 2: Trình sinh test + Trình so test: Làm sao để viết trình chấm một cách hiệu quả? Template dành cho C++: Template dành cho Pascal: Template dùng Shell script Luyện tập viết trình chấm Trình chấm là gì? Trình chấm là một bộ chương trình giúp bạn tự động sinh ra các test input ngẫu nhiên  và tự động chạy hai chương trình lời giải khác nhau với các input đó để so sánh output.  Về cơ bản, trình chấm gồm 4 chương trình là: lời giải 1, lời giải 2, trình sinh test, và trình so test. Thường thì lời giải 1 là cách chuẩn bạn sẽ sử dụng, còn lời giải 2 là một cách có hiệu quả kém hơn nhưng vẫn chính xác Tại sao nên viết trình chấm? Viết trình chấm là một trong những cách kiểm tra bài của mình đáng tin cậy nhất. Với  những kì thi chấm offline, ví dụ như VOI, việc sai sót nhỏ rất khó tránh khỏi khi ta khơng  thể biết kết quả trong khi thi. Vậy thì, nếu như bài của bạn khơng được chấm với bộ test của ban tổ chức, bạn hãy tự chấm nó với bộ test ngẫu nhiên mà mình sinh. Nếu bài của  bạn đúng với các test ngẫu nhiên, bạn có thể tạm n tâm là bài sẽ được điểm cao và  khơng bị những sai sót "chí mạng" dẫn đến bài bị 0 điểm Trình chấm u cầu một trình "chuẩn" và một trình "trâu", và so sánh hai chương trình  này với nhau. Nếu trình chấm của bạn phát hiện được một test mà kết quả hai chương  trình khơng khớp nhau, trình chuẩn hoặc trình trâu của bạn sẽ sai, và bạn hãy sử dụng  test đó để debug. Còn nếu tất cả các test đều đúng, bạn có thể tạm n tâm, vì mặc dù  có thể cả hai lời giải cùng sai, nhưng cùng sai giống hệt nhau thì rất khó Đối với những kì thi chấm online, hoặc đơn giản là bạn làm bài online trên mạng, trình  chấm cũng rất hữu ích trong việc tìm test sai. Chẳng hạn khi bạn code một bài cấu trúc  dữ liệu khó, nộp bài thấy bị 0 điểm, thay vì việc ngồi debug bằng mắt hãy thử code một  bộ trình chấm để giúp tìm test sai. Với test sai tìm được bạn sẽ dễ dàng debug hơn rất  nhiều Nhiều người ngại viết trình chấm vì cho rằng làm vậy mất thời gian. Tuy nhiên, khi đã  thành thạo thì viết một bộ trình chấm cho một bài chỉ mất khoảng 10 phút, nếu như bài  đó có thể làm trâu và sinh test ngẫu nhiên một cách dễ dàng. Lợi thế về mặt tâm lí khi  đã biết chắc bài làm của mình đúng sẽ giúp bạn làm bài hiệu quả hơn, thực tế sẽ tiết  kiệm được thời gian so với khi khơng kiểm tra bài. Tương tự, viết trình chấm để debug  những bài code khó đơi khi hiệu quả hơn nhiều so với việc debug bằng mắt, tiết kiệm  được rất nhiều thời gian Khi nào nên viết trình chấm? Lời khun của tác giả là: Hãy viết trình chấm bất cứ lúc nào mà bài có thể làm trâu và  sinh test ngẫu nhiên dễ dàng. Có một số bài mà cách trâu còn khó hơn cách chuẩn thì  có thể tạm bỏ qua, tuy nhiên nếu có thời gian vẫn nên viết trình chấm sau đấy để đảm  bảo chắc chắn Thành phần của một bộ trình  chấm Lưu ý: Bài viết này hướng dẫn cho Pascal/C++ trên hệ điều hành Windows. Với các  ngơn ngữ khác hoặc chạy trên hệ điều hành khác, một số lệnh sẽ thay đổi, tuy nhiên ý  tưởng vẫn tương tự Một bộ trình chấm gồm có 4 thành phần: Lời giải 1, lời giải 2, trình sinh test, trình so  test Lời giải 1: Thường là code chuẩn của bạn. Dù viết trình chấm hay khơng thì phần này bắt buộc  phải có nên cũng khơng cần phải nói nhiều. Trong bài viết này, ta sẽ giả sử input của  trình lời giải 1 là  *.inp , output là  *.out Lời giải 2: Thường là code trâu, hoặc là một cách giải khác, miễn là ra đúng đáp số. Hãy chọn  cách dễ code nhất, dễ đúng nhất có thể, vì thời gian chạy thực ra khơng quan trọng lắm  khi bạn chỉ cần sinh test nhỏ để kiểm tra. Trong bài viết này, ta sẽ giả sử input của trình  lời giải 2 là  *.inp , output là  *.ans Trình sinh test: Chương trình này có nhiệm vụ sinh input ngẫu nhiên vào file  *.inp  Để cho hàm ngẫu  nhiên được thay đổi khi chương trình khởi động, sử dụng lệnh  randomize  trong Pascal  và  srand(time(NULL))  trong C++ Lưu ý: Lệnh  srand(time(NULL))  trong C++ tính random theo giây, tức là sau 1 giây nó mới thay đổi random seed. Vì vậy nhiều khả năng các test random sinh ra liên tục sẽ bị  giống nhau. Để khắc phục điều này, ta có thể lồng trình sinh test vào trình so test chứ  khơng tách ra cho chạy riêng nữa. Với Pascal thì khơng phải lo về điều này,  vì  randomize  thay đổi random seed theo mili giây Trình so test: Chương trình này có nhiệm vụ duyệt N lần, với N là số test cần so, mỗi lần thì chạy trình sinh test trước, xong đến lần lượt lời giải 1 và lời giải 2. Sau khi chạy xong, ta có được  file  *.out  và  *.ans  tương ứng là kết quả của hai chương trình lời giải, và việc còn lại là so sánh 2 file này với nhau. Nếu kết quả trùng nhau (hoặc thỏa mãn điều kiện đề bài với  những bài có nhiều đáp số), ta coi như test đó đúng và chuyển đến test sau. Nếu khác  nhau, ta in ra sai và dừng chương trình lại ln, và ta có 3 file  *.inp ,  *.out ,  *.ans  là dữ  liệu của test sai Để chạy file, ta sử dụng  exec('*.exe', '')  trong Pascal và  system("*.exe")  trong C++ Ví dụ: Bài VMELLIP Đây là một bài cấu trúc dữ liệu rất khó, thuộc đề thi VNOI Marathon 2015. Bài viết xin  được lấy code của tanphatls987 được 90 điểm làm ví dụ Lời giải 1: Link code Đây là code của tanphatls987, được thêm 2 dòng  freopen  vào để mở file. Code gốc  khơng có 2 dòng này vì nộp trên SPOJ sử dụng Standard Input / Output Lời giải 2: Link code Đây là code trâu với độ phức tạp O(N * M), làm y như những gì đề bài bảo Trình sinh test + Trình so test: Link code Vì đây là code C++ nên tác giả kết hợp trình sinh test với trình so test để cho hàm  random chạy khơng bị trùng. Code sinh test từ dòng 11 đến dòng 37. Ở đây, ta duyệt  100 lần ứng với 100 test, mỗi lần duyệt ta sinh ngẫu nhiên ra file input  vmellip.inp  Sau  đó, ta lần lượt chạy hai chương trình ở  trên:  system("vmellip.exe")  và  system("vmellip_trau.exe")  (lời giải 2 đặt tên là  vmellip_trau ).  Sau đó ta sử dụng lệnh  system("fc vmellip.out vmellip.ans") , có nhiệm vụ so hai file  text  vmellip.out  và  vmellip.ans  với nhau. Nếu hai file hồn tồn khớp nhau, lệnh  system  sẽ trả về exit code là 0, còn khơng sẽ trả về exit code là 1 Chạy thử chương trình này, ta có thể sinh được một test sai như sau: 15 66 3118 1111 611 1119 2118 98 Trong đó, lời giải 1 ra output là: Lời giải 2 ra output là: Giới hạn test (dòng 3) được đặt nhỏ, mục đích là để sinh ra test sai nhỏ dễ debug hơn.  Sau khi code đã đúng, có thể tăng giới hạn lên để kiểm tra mạnh hơn Làm sao để viết trình chấm một  cách hiệu quả? Qua ví dụ trên, bạn có thể cảm thấy khá ngại khi code trình so test khá dài, code có thể  mất thời gian. Tuy nhiên, ta hồn tồn có thể viết code so test thành một template để  ứng dụng cho tất cả các bài! Với một template so test có sẵn, việc còn lại của ta chỉ là  code phần sinh test và trình trâu, nếu như đã làm quen với trình chấm thì chỉ mất  khoảng 10 phút để viết Tác giả xin được chia sẻ với các bạn các template trình chấm do chính mình sử dụng Template dành cho C++: #include using namespace std; // Tên chương trình const string NAME = "template"; // Số test kiểm tra const int NTEST = 100; // Viết lại hàm random để sử dụng cho thuận tiện Hàm random sinh ngẫu nhiên số phạm vi long long, số sinh >= l

Ngày đăng: 05/02/2020, 21:34

TỪ KHÓA LIÊN QUAN

w