Quantcast
Channel: C#タグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 8905

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

$
0
0

この記事は 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してください。

https://github.com/sekikatsu36/AtCoder

使い方

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

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

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

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

中身の紹介

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

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

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

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

image.png

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

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

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

// 文字列の入力strings=Console.ReadLine();// 整数の入力longn=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にセットして、

varsw=newSystem.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

参考リンク


Viewing all articles
Browse latest Browse all 8905

Trending Articles