ACM/OI 出題用


  之前出題,很苦惱出數據和檢查程序,因為很多繁瑣的工作,還很可能小手一抖出問題。

  最近又在出題。。。想起之前的對拍腳本,感覺不能更方便,於是擼了一套出題用的小工具,也學習了一點點的DOS命令

  首先是輸入數據,需要十組,命名規則為01.in,02.in,……,10.in,寫好數據生成器rand.cpp后去掉輸出重定向然后編譯,運行以下腳本

 1 @echo off  
 2 set a=0
 3 :loop  
 4     set /a a=%a%+1
 5     rand.exe>0%a%.in
 6     echo %a%
 7     ping -n 2 127.0.0.1>nul
 8 if %a% == 9 goto NEXT
 9 goto loop  
10 :NEXT
11     set /a a=%a%+1
12     rand.exe>%a%.in
13     echo %a%
14 pause  
in_maker

  @符號表示不把指令顯示出來,echo off表示不輸出提示

  這里學到一個小技巧,dos命令里(貌似)沒有sleep命令,於是通過ping來代替,因為每次ping會等待1s,所以需要sleep多少秒就ping多少次(加一)就行,這里因為數據生成器使用時間初始化隨機種子,所以需要間隔一秒,所以ping兩次

  這里第一次接觸set操作和變量,具體的以后再研究,這里的變量是 %variable% (注意格式,和for的變量區分)。

  這里用到了輸出指向>,當然,接下來的out_maker用到了輸入指向<

---------------------------------------------------------------------------------------------------------------------------

  接下來是輸出,命名規則為01.out,02.out,……,10.out,寫好標程std.cpp后去掉輸入輸出重定向,運行以下腳本

 1 @echo off  
 2 set a=0
 3 :loop  
 4     set /a a=%a%+1
 5     std.exe<0%a%.in>0%a%.out  
 6     echo %a%
 7 if %a% == 9 goto NEXT
 8 goto loop  
 9 :NEXT
10     set /a a=%a%+1
11     std.exe<%a%.in>%a%.out
12     echo %a%
13 pause  
out_maker

--------------------------------------------------------------------------------------------------------------------------------

  如果確定rand.cpp和std.cpp都沒有問題,其實可以寫在一起,在in的最后一行,加上call out_maker.bat即可,以后就可以自動化生成數據

 1 @echo off  
 2 set a=0
 3 :loop  
 4     set /a a=%a%+1
 5     rand.exe>0%a%.in
 6     echo %a%
 7     ping -n 2 127.0.0.1>nul
 8 if %a% == 9 goto NEXT
 9 goto loop  
10 :NEXT
11     set /a a=%a%+1
12     rand.exe>%a%.in
13     echo %a%
14 call out_maker.bat
15 pause  
data_maker

------------------------------------------------------------------------------------------------------------------------------

  然后就是對拍啊,不敢保證自己的標程是對的,要找小伙伴寫代碼來測試數據,拿到他的代碼my.cpp后去掉輸入輸出重定向編譯,然后運行以下腳本

 1 @echo off  
 2 set a=0
 3 :loop  
 4     set /a a=%a%+1
 5     my.exe<0%a%.in>std%a%.out  
 6     fc std%a%.out 0%a%.out 
 7     if errorlevel 1 goto dif  
 8     if errorlevel 0 goto sam
 9 :dif
10     del std%a%.out
11     echo %a%
12     pause
13     if %a% == 9 goto NEXT
14     goto loop
15 :sam
16     del std%a%.out
17     echo %a%
18     if %a% == 9 goto NEXT
19     goto loop
20     
21 :NEXT
22     set /a a=%a%+1
23     my.exe<%a%.in>std%a%.out  
24     fc std%a%.out %a%.out  
25     del std%a%.out
26     echo %a%
27 pause  
checker_goto

  之前的代碼已經可以解決問題了,但是使用goto的話有兩個弊病,一是破壞程序結構,使邏輯混亂,二是為了保持結構,有很多重復代碼出現,為了解決這個問題,使用for語句和if語句

 1 @echo off  
 2 for /l %%a in (1,1,10) do (
 3     if %%a == 10 (
 4         my.exe<%%a.in>std%%a.out  
 5         fc std%%a.out %%a.out
 6         del std%%a.out
 7         echo %%a
 8     ) else (
 9         my.exe<0%%a.in>std%%a.out  
10         fc std%%a.out 0%%a.out 
11         if errorlevel 1 (
12             del std%%a.out
13             echo %%a
14             pause
15         ) else (
16             del std%%a.out
17             echo %%a
18         )
19     )
20 )
21 pause  

  這里需要注意的就是,dos命令是格式敏感的if-else必須寫成這個格式(注意其中的空格),for循環有很多寫法,通過參數區分,這里只使用了/L的,是從1每次加1到10為止。

  for中使用的變量是&&variable(區分於set的變量)
  到這里,功能實現了,代碼也很優美了。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM