Help us understand the problem. What is going on with this article?

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.
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away