Windows下用批次程式進行對拍

來源:互聯網
上載者:User

在做演算法類競賽的題目的時候,容易想到一個樸素的能保證完全正確的演算法,但是會逾時。而高效的演算法又不能保證完全寫對。這時候可以自己寫一個樸素的演算法、一個資料產生程式和一個檔案比較程式進行驗證高效演算法的正確性。

在Windows下,fc命令提供了比較檔案的功能,雖然批處理不如Linux下的bash等強大,但也足以寫個自動比較的程式了。

下面以求逆序對為例。題目類似於POJ3067,排序後求逆序對。資料量N=300000。容易想到類似於冒泡排序的枚舉逆序對,先寫出來。命名為standard.pas

const
MAXN = 500000;
type
car = record x,v:longint end;

var
a: array[0..MAXN] of car;
n : longint;
i, j : longint;
sum : longint;

procedure swap(var a, b:car);
var
temp:car;
begin
temp := a;
a := b;
b := temp;
end;

begin
readln(n);
for i:=1 to n do
readln(a[i].x , a[i].v);
for i:=1 to n-1 do
for j:=i+1 to n do
if a[i].x > a[j].x then
swap(a[i], a[j]);
for i:=1 to n-1 do
for j:=i+1 to n do
if a[i].v > a[j].v then
inc(sum);
writeln(sum);
end.

用歸併排序等進階的演算法實現NLogN的程式,才能保證過掉這題。命名為題目要求的overtaking.pas。程式是用了歸併排序排好序,再把這個歸併排序複製一下改一下變成求逆序對的統計過程。

const
MAXN = 500000;
type
car = record x,v:longint end;

var
temp, a: array[0..MAXN] of car;
n : longint;
i : longint;
sum : int64;

procedure swap(var a, b:car);
var
temp:car;
begin
temp := a;
a := b;
b := temp;
end;

procedure qsort(l, r:longint);
var
i, j, m:longint;
begin
i:=l;j:=r;m:=a[(l+r)div 2].x;
repeat
while (a[i].x < m) do inc(i);
while (a[j].x > m) do dec(j);
if i <= j then
begin
swap(a[i],a[j]);
inc(i);
dec(j);
end;
until i > j;
if l < j then
qsort(l, j);
if i < r then
qsort(i, r);
end;

procedure merge(left, mid, right :longint);
var
i, j, p, k:longint;
begin
k := left;
i := left;
j := mid + 1;
while (i <= mid) and (j <= right) do
begin
if a[i].x <= a[j].x then
begin
temp[k] := a[i];
inc(i);
inc(k);
end
else begin
temp[k] := a[j];
inc(j);
inc(k);
end;
end;
for p := i to mid do
begin
temp[k] := a[p];
inc(k);
end;
for p := j to right do
begin
temp[k] := a[p];
inc(k);
end;
for i:= left to right do
a[i] := temp[i];
end;

procedure merge_sort(left, right:longint);
var
mid : longint;
begin
if left >= right then
exit;
mid := (left + right) shr 1;
merge_sort(left, mid);
merge_sort(mid+1, right);
merge(left, mid ,right);
end;



procedure merge2(left, mid, right :longint);
var
i, j, p, k:longint;
begin
k := left;
i := left;
j := mid + 1;
while (i <= mid) and (j <= right) do
begin
if a[i].v <= a[j].v then
begin
temp[k] := a[i];
inc(i);
inc(k);
end
else begin
inc(sum, mid - i + 1);
temp[k] := a[j];
inc(j);
inc(k);
end;
end;
for p := i to mid do
begin
temp[k] := a[p];
inc(k);
end;
for p := j to right do
begin
temp[k] := a[p];
inc(k);
end;
for i:= left to right do
a[i] := temp[i];
end;

procedure merge_sort2(left, right:longint);
var
mid : longint;
begin
if left >= right then
exit;
mid := (left + right) shr 1;
merge_sort2(left, mid);
merge_sort2(mid+1, right);
merge2(left, mid ,right);
end;


procedure select_sort;
var
i, j:longint;
begin
for i:=1 to n-1 do
for j:=i+1 to n do
if a[i].x > a[j].x then
swap(a[i], a[j]);
end;

begin

readln(n);
for i:=1 to n do
begin
readln(a[i].x, a[i].v);
end;
merge_sort(1, n);
merge_sort2(1, n);
writeln(sum);


end.

然後寫一個資料產生器。此題造資料很簡單,產生隨機數就行了。

const
INF = 199303170;
MAXN = 3000;

var
i, n:longint;
begin
randomize;
n := random(MAXN);
writeln(n);
for i:=1 to n do
writeln(random(INF),'',random(INF));
end.

然後寫一個批處理對拍,自動將這三個程式的輸入輸出從螢幕、鍵盤重新導向到檔案,然後比較standard.exe與overtaking產生的資料。

:loop
make.exe > data.txt
standard.exe < data.txt > std.txt
overtaking.exe < data.txt > ans.txt
fc std.txt ans.txt
if errorlevel 1 goto end
goto loop
:end

命令列介面會不斷提示找不到檔案差異,然後就可以放心提交了,當然前提是你樸素的演算法寫對了。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.