LoginSignup
31
32

More than 3 years have passed since last update.

初心者がC#でAtCoderデビューするためのVSProjectテンプレート

Last updated at Posted at 2019-12-03

この記事は NSSOL Advent Calendar 2019 の4日目の記事です。

TL;DR

https://github.com/sekikatsu36/AtCoder
↑こちらをfork

概要

この記事では「C#使いの競技プログラミング未経験者が、C#で初AtCoderに挑むハードルを下げる」ことを目的に、ベースとなるVSプロジェクトの共有&紹介を行います。

コンテストを続けるための便利TIPSは他にも山ほどあるので、気になればぜひ調べててみてください。(末尾に参考URLを記載)

背景

AtCoderはいわゆる競技プログラミングコンテストのサービスです。
今更ですが、私も最近AtCoderを始めまして。(まだ茶色レベルの新米です)
初回にC# + Visual Studioで参戦した際、「事前にVSプロジェクトとか準備した方がいいんだろうなぁ」と思ってはいたのですが、それを怠ってぶっつけ本番で突撃して見事なまでに惨敗

何度か再戦し、最近それっぽいプロジェクトが出来上がったので、この場を借りて共有します。
「競プロをC#で!」みたいな記事は世に溢れてますが、VSプロジェクトは転がっていないようだったので、この期に配布。
私のような悔しい思いをする方が一人でも減ればと。

なんでC#?

C#が好きだから

その一言に尽きるんじゃないでしょうか。

一応上げると、以下のようなメリットがあります。

  • LINQが便利(ただしOrderByは使ってはならぬ。遅すぎ)
  • Visual Studioが神IDE
  • ジェネリックが使える

ただ、ぶっちゃけ、AtCoderでワザワザC#を選ぶ必要はないです。
C#には以下のようなデメリットがあるので、PythonやC++が得意ならそっちの方が良いと思います。

  • 競プロで便利なコレクション操作の一部が標準装備されていない(vs Python)
  • 遅い (vs C++)
  • 人口が少ない

できあがったもの

以下にあります。
適宜forkしてください。

使い方

A~Fまで、すべての問題が一プロジェクトに収まってるので、masterからブランチを切れば即コンテストを始められます。
ライブラリを作りたいときは、それ用のクラスを適当に追加すれば良いので、管理は楽だと思います。

コンテスト中にエントリクラスやライブラリに変更を加えた際は、そのファイルだけmasterにmergeすれば次のコンテストですぐ使えます。

git checkout abc146 -- .\AtCoder\Program.cs

問題を切り替えるときはProgram.cs内で呼び出すクラスを書き換える必要があります。
そこはイケてないのですが、良い方法が思いつかず。
まぁ何かしらの方法で切り替える必要はあると思うので、今はこれで妥協してます。
妙案あったらシェアいただけると嬉しいです。

中身の紹介

無限ループで繰り返し実行できる

まぁ言うまでもなく。
これくらいパパっと実装できるとは思いますが、事前に用意してあるとストレスが全然違います。
初心者が一番最初に欲しくなる機能だと思います。

スタートアップオブジェクトを指定して、コピペで提出できるようにする

すべての問題をそのまま一プロジェクトにまとめると、エントリポイントの問題が出てきます。
そのまま各問のクラスにMainメソッドを追加すると「エントリポイントが複数定義されてるぞ」とVisual Studioの怒りを買ってしまいます。
かといって、Main以外の名前にしてしまうと、コードをコピペして提出した時にAtCoderから「エントリポイントが見つからない」と心無いことを言われてしまいます。
プロジェクトを分けるのもコードを共通化しにくい。

image.png

そんな時はプロジェクトのプロパティから[アプリケーション]>[スタートアップオブジェクト]を設定しましょう。
複数のクラスでMainメソッドが定義されていても、これを指定すれば普通に実行できます。

各問の最初によくつかう標準入力処理を書いておく

AtCoderは、テストケースを標準入力から受け取る仕様です。
競プロ勢からすれば標準入出力なんて手慣れたものでしょうが、初心者は一瞬手が止まると思います。(標準入力とか普段使わないし)
出鼻を挫かれるのも何なので、最初から載せておきます。実際の問題に合わせて、追加・削除します。

// 文字列の入力
string s = Console.ReadLine();

// 整数の入力
long n = long.Parse(Console.ReadLine());

// 文字列配列の入力
string[] inputStrArray = Console.ReadLine().Split(' ');

// 整数配列の入力
long[] inputLongArray = Console.ReadLine().Split(' ').Select(i => long.Parse(i)).ToArray();

ちなみに、intを使ってメモリをケチる必要はないです。
これまで10回弱参加しましたが、メモリが問題になったことはほぼなかったので。
予期せぬ桁溢れの方がずっと怖いので、脳みそを止めてlongを使います。(メモリは溢れてから考えるスタイル)

なお、「入力を高速化」みたいなTIPSも世には転がってますが、最初はそこまで神経質になる必要はないかな、と。

各問の最後に標準出力処理を書いておく

AtCoderは、結果を標準出力から返す仕様です。
入力同様、出力処理も記載しておきます。

C#のConsole.WriteLineは遅いので、Mainの開始時にAutoFlushをfalseにセットして、

var sw = new System.IO.StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false };
Console.SetOut(sw);

最後にFlush処理を行います。

Console.Out.Flush();

こうすれば少しだけ高速化できます。(と偉い人が言っていた。自分で速度計測したわけではないです orz)
結果の出力をFlushの前に書くことだけ意識的に。

オーバーフローを例外化する

初心者がやらかすミスの一つがオーバーフロー(桁溢れ)だと思います。
私も何度も痛い目を見ました。

前項の通りintを使わないことである程度回避できますが、それでも食らうときは食らうので、ローカル環境ではオーバーフローが発生したら例外が出るようにしましょう。
プロジェクトのプロパティで、[ビルド]>[詳細設計]>[演算のオーバーフロー及びアンダーフローのチェック]をONにします。

image.png

ライブラリを用意しておく(任意)

ライブラリを持っておくと、解くスピードがぐっと上がる可能性があります。
が、個人的に、

  • 事前に揃えておいても、初心者はどうせ使いどころが分からない
  • 一度自分で実装しようとしてみた方が勉強になる

という理由から、特にはじめは意識しなくてもいいと思います。

とはいえ、C#でAtCoderをやっていれば、今に以下のようなライブラリが欲しくなってくると思うので、「欲しいな」と思ったタイミングでライブラリ化しましょう。

  • 優先度付きキュー。合わせてダイクストラも。
  • UpperBound, LowerBound
  • gcd(最大公約数)
  • 素因数分解
  • nCr

使うときはLibを直接呼び出すのではなく、各問のクラスにコピペするよう注意。

その他TIPS

他にも、以下のようなことをやっておくと、便利かもしれません

  • コードスニペットを覚えておく https://qiita.com/Kosen-amai/items/248e44dff958be901a84
    • for/foreach/cwはよく使います
    • 他にもほしいものがあれば、Visual Studioを使っている利点をフル活用して、事前登録しておくよろし
  • 問題のURLを控えておく
    • コンテスト開始時はアクセスが集中するのでページ表示が遅いです
    • 問題の一覧 → A問題表示、と画面遷移すると若干待たされるので、最初からA問題に飛べるリンクを用意しておくと気が楽です(その数秒を争うレベルなのか?という疑問は捨て置く)
    • e.g. https://atcoder.jp/contests/abc141/tasks/abc141_a

参考リンク

31
32
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
31
32