这个嘛是本人专门为了NOI上面对拍程序写的对拍程序,已经经历了NOI2015的考验;更重要的是——纯Pascal的哦(HansBug:实际上是我不会写.sh脚本TT,谁叫用惯了windows的我只会写bat呢)。。。(本人实测复杂度约为 \( {10}^{5} \) 的程序在windows下每秒钟约能够拍20次左右,linux下能够最高达到600次每秒哦,上次我开动程序后当我反应过来以后次数已是四位数了么么哒,固然了若是你程序自己就复杂度太高的话那么仍是没有办法,毕竟受到程序运行速度的制约)。。。linux
须要的可执行文件(注:linux下面可执行文件无.exe后缀,在程序中去掉便可,这三个可执行文件均须要文件输入输出,其中std程序输出文件为stdXXX.out,数据生成器输出到XXX.in,固然了欢迎擅长使用输入输出管道的童鞋进行优化喽):windows
1.XXX.exe/XXX——你的程序 ide
2.stdXXX.exe/stdXXX——你的标程(其实也能够是暴力程序,总之保证这个必定不WA就好了) 函数
3.fuckXXX.exe/fuckXXX——你的数据生成器(其实这个逗比的前缀前几天才被JYY狠狠地吐槽了一下,不过我已经用这种对拍格式一年多了,因而这个程序仍是先按照我本身的习惯来设计的啦,欢迎你们按照本身的习惯来进行修改^_^)性能
而后在Linux下直接编译号后开终端直接用就好啦^_^优化
此程序本人将其命名为Jd。。。。但愿即便此程序被传开以后,Jd这个专有名词依然能够保留下去啦this
代码以下:(Jd.exe(Win)/Jd(Linux))spa
1 Program Jd; 2 uses dos,sysutils; 3 const mm=24*60*60; 4 var 5 i,j,k,l,m,n:longint; 6 tit,s1:ansistring; 7 t1,t2:extended;tt,jj:boolean; 8 function fc(ss1,ss2:ansistring):boolean; //标准比对模块,千万注意不管是正常退出仍是中断的都必须关闭文件,不然会致使很快报错 9 var s1,s2:ansistring;f1,f2:text; 10 begin 11 assign(f1,ss1);reset(f1); 12 assign(f2,ss2);reset(f2); 13 while not(eof(f1)) and not(eof(f2)) do //有效行的比对 14 begin 15 readln(f1,s1);readln(f2,s2); 16 s1:=trimright(s1); 17 s2:=trimright(s2); 18 if s1<>s2 then 19 begin 20 close(f1);close(f2); 21 exit(false); 22 end; 23 end; 24 while not(eof(f1)) do //多余行的比对 25 begin 26 readln(f1,s1); 27 if trimright(s1)<>'' then 28 begin 29 close(f1);close(f2); 30 exit(false); 31 end; 32 end; 33 while not(eof(f2)) do //多余行的比对 34 begin 35 readln(f2,s2); 36 if trimright(s2)<>'' then 37 begin 38 close(f1);close(f2); 39 exit(false); 40 end; 41 end; 42 close(f1);close(f2);exit(true); 43 end; 44 function judge:boolean; //总评测模块,能够按照本身的意愿增删功能,也能够彻底改为纯测速器,那样子就不须要std了,而后直接返回True便可 45 begin 46 writeln('Running source...'); 47 t1:=now;exec(tit+'.exe','');t2:=(now-t1)*mm; //now函数获取的时间单位为Day 48 writeln(t2:0:3,'s'); 49 50 51 writeln('Running std...'); //若是改为测速模式的话能够删除此段 52 t1:=now;exec('std'+tit+'.exe','');t2:=(now-t1)*mm; 53 writeln(t2:0:3,'s'); 54 55 exit(fc('std'+tit+'.out',tit+'.out')); 56 end; 57 begin 58 write('Program Name :');readln(tit); 59 write('How many (0 means unlimited):');readln(l); 60 i:=0; 61 repeat 62 inc(i); 63 writeln('Test No.',i); 64 exec('fuck'+tit+'.exe',''); //启动数据生成器 65 66 repeat 67 tt:=judge; 68 if tt then 69 writeln('Accept') 70 else 71 begin //这边是当出现WA时自动暂停询问是否再测一次,固然了你能够按照你的意愿修改功能 72 writeln('Wrong Answer'); 73 write('Continue this point?'); 74 readln(j);if j<>1 then break; 75 end; 76 until tt; 77 writeln('---------------------------------------------------'); 78 writeln; 79 until i=l; 80 end.
对了有人问我为啥要手写那么长的Fc模块,缘由以下:设计
1.直接缘由——我不擅长使用FC.exe(Linux下的diff)的输入输出管道并且调用起来麻烦;code
2.然而更重要的一点是——这个Fc模块能够按照你的需求很是自由的修改(本程序中的是忽略行末空格和多余回车的,也就是经常使用的模式),好比说容许0.01%的实数精度偏差,那样子只要简单修改下fc模块代码便可正常使用,并且在程序其余的地方也能够按照你本身的须要自由的增删功能,好比自动计算当前拍下来全部的点里面的正确率、平均耗时。。。
或者能够这么说——这个东西是Pascal写的(固然了欢迎你们作出来C/C++版的高级语言对拍器),这个是你做为一个OI党再熟悉不过的语言了,因此能够这么说,在这个里面只要你想要的功能均可以有,只要你能编出来(HansBug:更况且计算平均值这种东西我想对于已经须要大量对拍的Oier来讲恐怕都不是问题吧^_^)
最后,欢迎各位优化(HansBug:其实按照JYY的说法,最好是在不很影响性能的状况下压缩代码长度,固然了Linux下每秒钟500+次的高速度仍是但愿保持的啦,然而在win下因为win自己建立子进程的速度就慢的很因此并非颇有办法TT,还有弱弱的说一句但愿能保留我这个Jd的名字啦么么哒^_^)