Edited at

AtCoder に登録したら解くべき精選過去問 10 問を Pascal で解いてみた

More than 1 year has passed since last update.

実装リンク集 https://qiita.com/drken/items/6edb1c0542d4c3b7179c

問題一覧 https://abs.contest.atcoder.jp/assignments

私の実装
記事

Ruby (私家版)
https://qiita.com/cielavenir/items/c0a45b6b87c411b60b93

Swift
https://qiita.com/cielavenir/items/b90a94dce60a620fa2dc

C
https://qiita.com/cielavenir/items/ee1e47b844d05dcfc66e

VB.Net
https://qiita.com/cielavenir/items/7ddf5e9bac02daf72159

Pascal
https://qiita.com/cielavenir/items/530270ac4affca435442

Perl
https://qiita.com/cielavenir/items/4d16ba1be4ad6847a914

MoonScript/Lua
https://qiita.com/cielavenir/items/6553531e230f39cd6a3d

PascalはおそらくIOが速い?言語で、A/B問題最速コードはPascalであることが多いです。0msも狙えます。


解答

Pascalの文法はVBに近い雰囲気です。


例題 PracticeA

https://practice.contest.atcoder.jp/tasks/practice_1

readで読み込めます。


0.pas

program practiceA;

uses SysUtils;
var
a,b,c: integer;
s: string;
begin
read(a); // readlnにする必要はない
read(b);
readln(c);
readln(s);
writeln(IntToStr(a+b+c)+' '+s);
end.


第1問 ABC086A Product

https://abc086.contest.atcoder.jp/tasks/abc086_a

Pascalにも3項演算子っぽいものはありますが、短絡しません。


1.pas

program ABC086A;

uses StrUtils;
var
a,b: integer;
begin
read(a);
read(b);
writeln(ifThen(a*b mod 2>0,'Odd','Even'));
end.


第2問 ABC081A Placing Marbles

https://abc081.contest.atcoder.jp/tasks/abc081_a

Pascalの文字列は1-indexedです。

あと、forやifは全部複文形式で書いていますが、1文だけの場合はbegin-endで囲む必要はありませんので好みでどうぞ。


2.pas

program ABC081A;

var
s: string;
c,i: integer;
begin
read(s);
c:=0;
for i:=1 to 3 do begin
if s[i]='1' then begin
c:=c+1;
end;
end;
writeln(c);
end.


第3問 ABC081B Shift only

https://abc081.contest.atcoder.jp/tasks/abc081_b

arrの各要素に対し2で割ることが出来た回数の最小値です。

INF値として1<<29が使われていますが、2倍してオーバーフローしない中で簡潔に書ける数として競技プログラミングではよく使われます。

Pascalでは、整数除算はdiv、剰余はmodです。


3.pas

program ABC081B;

var
i,n,x,r,r0: longint;
arr: array of integer;
begin
r:=1<<29;
read(n);
SetLength(arr,n);
for i:=0 to n-1 do begin
read(arr[i]);
end;
for i:=0 to n-1 do begin
r0:=0;
x:=arr[i];
while x mod 2 < 1 do begin
r0:=r0+1;
x:=x div 2;
end;
if r>r0 then begin
r:=r0;
end;
end;
writeln(r);
end.


第4問 ABC087B Coins

https://abc087.contest.atcoder.jp/tasks/abc087_b

500円玉と100円玉の枚数を全探索します。


4.pas

program ABC087B;

var
a,b,c,x,i,j,k,r: integer;
begin
read(a);
read(b);
read(c);
read(x);
r:=0;
for i:=0 to x div 500 do begin
for j:=0 to (x-500*i) div 100 do begin k:=x-500*i-100*j;
if (k mod 50=0) and (c>=k div 50) and (a>=i) and (b>=j) then begin
r:=r+1;
end;
end;
end;
writeln(r);
end.


第5問 ABC083B Some Sums

https://abc083.contest.atcoder.jp/tasks/abc083_b

変数sは各i(j)を10で割れるだけ割って、その間に出た余りの和です。


5.pas

program ABC083B;

var
n,a,b,r,i,j,s: integer;
begin
read(n);
read(a);
read(b);
r:=0;
for i:=1 to n do begin
s:=0;
j:=i;
while j>0 do begin
s:=s+(j mod 10);
j:=j div 10;
end;
if (a<=s) and (s<=b) then begin
r:=r+i;
end;
end;
writeln(r);
end.


第6問 ABC088B Card Game for Two

https://abc088.contest.atcoder.jp/tasks/abc088_b

通常の配列にはソートが実装されていないため、TFPGListを使う必要があります。つらい…

降順でソートしたら、符号を切り替えながら足しこんでいきます。


6.pas

program ABC088B;

{$mode Delphi}
uses SysUtils,fgl;

(*
procedure reverse(var a:TFPGList<longint>;start:longint;size:longint);
var
en,i:longint;
z:longint;
begin
en:=start+size-1;
for i:=0 to trunc(size/2-1) do begin
z:=a[start+i];
a[start+i]:=a[en-i];
a[en-i]:=z;
end;
end;
*)

function intcompare(n1,n2:longint):longint;
begin
result:=n2-n1;
end;

var
n,i,r,t: longint;
arr: TFPGList<longint>;
begin
read(n);
arr:=TFPGList<longint>.Create();
for i:=0 to n-1 do begin
read(r);
arr.Add(r);
end;
arr.Sort(@intcompare);
// reverse(arr,0,arr.Count);
r:=0;
t:=1;
for i:=0 to n-1 do begin
r:=r+t*arr[i];
t:=-t;
end;
writeln(r);
end.



第7問 ABC085B Kagami Mochi

https://abc085.contest.atcoder.jp/tasks/abc085_b


7.pas

program ABC085B;

{$mode Delphi}
uses SysUtils,fgl;
var
n,i,r: longint;
arr: TFPGMap<longint,integer>;
begin
read(n);
arr:=TFPGMap<longint,integer>.Create();
for i:=0 to n-1 do begin
read(r);
// arr.AddOrSetData(r,1); // AtCoderでは使用不可
arr.Remove(r);
arr.Add(r,1);
end;
writeln(arr.Count);
end.


第8問 ABC085C Otoshidama

https://abc085.contest.atcoder.jp/tasks/abc085_c

1000円札と5000円札の枚数を全探索します。

exitはプログラム終了ではなく関数からリターンする意味になります。

https://www.freepascal.org/docs-html/rtl/system/exit.html


8.pas

program ABC085C;

uses SysUtils;
var
n,y,i,j,k: integer;
begin
read(n);
read(y);
for i:=0 to n do begin
for j:=0 to n-i do begin
k:=n-i-j;
if i*1000+j*5000+k*10000=y then begin
writeln(IntToStr(k)+' '+IntToStr(j)+' '+IntToStr(i));
exit;
end;
end;
end;
writeln('-1 -1 -1');
end.


第9問 ABC049C Daydream

https://abc049.contest.atcoder.jp/tasks/arc065_a

Substringはcopyです。文字列長をチェックする必要はありません。


9.pas

program ABC049C;

uses StrUtils;
var
T: array[0..3] of string = ('dream','dreamer','erase','eraser');
s: string;
i,c,l,k: integer;
begin
for i:=0 to 3 do begin
T[i]:=ReverseString(T[i]);
end;
readln(s);
s:=ReverseString(s);
c:=0;
l:=Length(s);
while c<l do begin
k:=-1;
for i:=0 to 3 do begin
if copy(s,c+1,Length(T[i]))=T[i] then begin
k:=Length(T[i]);
end;
end;
if k<0 then begin
writeln('NO');
exit;
end;
c:=c+k;
end;
writeln('YES');
end.



第10問 ABC086C Traveling

https://abc086.contest.atcoder.jp/tasks/arc089_a

dx+dyがdt以下かつdtとの偶奇が一致。


10.pas

program ABC086C;

var
i,n,t,x,y: integer;
t0,x0,y0,dt,dx,dy: integer;
begin
read(n);
t:=0;
x:=0;
y:=0;
for i:=1 to n do begin
read(t0);
read(x0);
read(y0);
dt:=t0-t;
dx:=x0-x;
dy:=y0-y;
if (dx+dy>dt) or ((dt-dx-dy) mod 2>0) then begin
writeln('No');
exit;
end;
t:=t0;
x:=x0;
y:=y0;
end;
writeln('Yes');
end.