実装リンク集 https://qiita.com/drken/items/6edb1c0542d4c3b7179c
問題一覧 https://abs.contest.atcoder.jp/assignments
入力
@a=split(/ /,<>);
や@a=split(' ',<>);
は使いません。というわけでこの節だけ入門を逸脱します。ご容赦ください。てかこれを書きたくてPerlを担当したようなもの^^;
- トークン1個
$n=<>;
- トークン2個
<>=~$";
$`$'
- トークン3個
<>=~/ (.+) /;
$`$1
$'
- トークン3個(数値)
<>=~/ .+ /;
$`$&
$'
- トークン4個(数値)
<>=~/ .+ (.+) /;
$`$&
$1
$'
- トークン2・3個ないし4個以上
@a=glob<>;
そういえばですが、AtCoderの入力例で<STDIN>
と書かれていますが、<ARGV>
としても差し支えありません。そして、<>
は<ARGV>
と同じ意味なのです。
解答
例題 PracticeA
最初なので真面目にやります。use strictを付け、変数はmyで宣言します。
文字列の結合は.
です。
あまり知られていませんが、節の最後の文は;
を付けなくて良いです。
#!/usr/bin/perl
use strict;
my $a=<>;
my($b,$c)=glob<>;
print $a+$b+$c.$".<>
第1問 ABC086A Product
Perlでは文字列を引用符で囲わなくても通る場合があります。
あと、今回に限り改行文字($/
)を律儀に出力しました(例題は入力した文字列をchompせずに出力しているので問題ありません)。AGC001以降の問題では実は出力は改行空白区切りのいずれでもよく終端改行も不要なので、以降は改行は出力しません。
#!/usr/bin/perl
<>=~$";print$`*$'%2?Odd:Even,$/
第2問 ABC081A Placing Marbles
boolを直接intとして扱うことができます。
また、未初期化の変数はundefですが、数値のコンテキストでは0として扱われます。
$s=<>;
for(;$i<3;$i++){$r+=substr($s,$i,1) eq '1'}
print$r
第3問 ABC081B Shift only
arrの各要素に対し2で割ることが出来た回数の最小値です。
INF値として1<<29
が使われていますが、2倍してオーバーフローしない中で簡潔に書ける数として競技プログラミングではよく使われます。
#!/usr/bin/perl
$r=<><<29;
for(glob<>){
$r0=0;
for(;$_%2<1;$_=int($_/2)){$r0++}
if($r>$r0){$r=$r0}
}
print$r
第4問 ABC087B Coins
500円玉と100円玉の枚数を全探索します。
#!/usr/bin/perl
($a,$b,$c,$x)=<>;
for($i=0;$i<=int($x/500);$i++){
for($j=0;$j<=int(($x-500*$i)/100);$j++){
$k=$x-500*$i-100*$j;
$r+=$k%50==0&&$c>=int($k/50)&&$a>=$i&&$b>=$j
}
}
print$r
第5問 ABC083B Some Sums
変数sは各i(j)を10で割れるだけ割って、その間に出た余りの和です。
#!/usr/bin/perl
<>=~/ .+ /;
for($i=1;$i<=$`;$i++){
$s=0;
$j=$i;
for(;$j;$j=int($j/10)){$s+=$j%10}
if($&<=$s&&$s<=$'){$r+=$i}
}
print$r
第6問 ABC088B Card Game for Two
降順にソートしたら、符号を変えながら足しこんでいきます。
#!/usr/bin/perl
$n=<>;
@a=sort {$b<=>$a} glob<>;
$t=1;
for($i=0;$i<$n;$i++){
$r+=$t*$a[$i];
$t=-$t
}
print$r
第7問 ABC085B Kagami Mochi
$n=@aとすると、nに配列aの長さが代入されます。これを代入を経ずに得たい場合にscalarを使います。
#!/usr/bin/perl
$n=<>;
$h{$_}=1 for<>;
print scalar keys %h;
第8問 ABC085C Otoshidama
1000円札と5000円札の枚数を全探索します。
#!/usr/bin/perl
<>=~$";
for($i=0;$i<=$`;$i++){
for($j=0;$j<=$`-$i;$j++){
$k=$`-$i-$j;
if($i*1000+$j*5000+$k*10000==$'){
printf("%d %d %d",$k,$j,$i);
exit
}
}
}
print"-1 -1 -1"
第9問 ABC049C Daydream
文字列を逆にして比較していきます。
どうもscalarはscalarに変換するのではなく、その中身をscalar contextで評価せよっていう意味らしい?このコードのscalarは必須です。ないとlist contextになってしまうようです(正しくない)。
#!/usr/bin/perl
@T=map {scalar reverse $_} ("dream","dreamer","erase","eraser");
$s=<>;
chomp($s);
$s=reverse($s);
$l=length($s);
for($c=0;$c<$l;){
$k=-1;
for($i=0;$i<4;$i++){
if(substr($s,$c,length($T[$i])) eq $T[$i]){
$k=length($T[$i]);
last;
}
}
if($k<0){
print'NO';
exit
}
$c+=$k;
}
print'YES'
第10問 ABC086C Traveling
dx+dyがdt以下かつdtとの偶奇が一致。
2行目以降の入力は2通り示します。どちらを使っても通ります。
#!/usr/bin/perl
for($n=<>;$n--;){
#@a=glob<>;$dt=$a[0]-$t;$dx=$a[1]-$x;$dy=$a[2]-$y;
<>=~/ (.+) /;$dt=$`-$t;$dx=$1-$x;$dy=$'-$y;
if($dx+$dy>$dt || ($dt-$dx-$dy)%2){
print'No';
exit
}
$t=$`;
$x=$1;
$y=$';
}
print'Yes'