【競プロ】C#でJOI問題を解く|折り紙-2008年 日本情報オリンピック春合宿OJ

2021/02/05に公開

AtCoderにてJOI(日本情報オリンピック)の問題をC#で埋めている。

AtCoderで出される問題と異なり、制約が厳しく普通に解いただけでもメモリ制限エラー(MLE)となることが多い。

今回は、「2008年 日本情報オリンピック春合宿OJ」の「折り紙」について記載する。

https://atcoder.jp/contests/joisc2008/tasks/joisc2008_origami

MLEへの対処

値をbyteで保持

https://atcoder.jp/contests/joisc2008/submissions/16466297

折り紙の折り方を表す変数のうち r - p, s - q20 未満という制約があるので、差分をbyte型で保持することにした。

old
readonly struct Paper
{
    public readonly int p;
    public readonly int q;
    public readonly int r;
    public readonly int s;
}

https://atcoder.jp/contests/joisc2008/submissions/16469184

new
readonly struct Paper
{
    public readonly int p;
    public readonly int q;
    public readonly byte rd; // r-p
    public readonly byte sd; // s-q
}

残念ながら改善せず。

Dictionaryのサイズ指定

ほとんどずるに近いが、MLEになるテストケースで必要なDictionary<(int, int), int>Capacityをあらかじめ指定することでMLEを回避できた。

old
Dictionary<(int, int), int> dic = new Dictionary<(int, int), int>();
new
IDictionary<(int, int), int> dic = new Dictionary<(int, int), int>(995263); // IDictionaryな意味は特に無い

https://atcoder.jp/contests/joisc2008/submissions/16470454

.NETのDictionary<(int, int), int>Capacityは足りなくなるとおよそ2倍になるため、メモリがギリギリなケースではCapacityの指定でなんとかなることもある。

GitHubで編集を提案

Discussion