さかなの思い

競技プログラミングの話が主になるかもしれません

辛くなったときに見るメモ

辛くなったときに見るメモ

  1. このメモを読もうとしている時点で進捗です。えらい
  2. 3分くらいでいいので散歩をしてみたり、筋トレをしてみたり、歯を磨いてみたり、そういう「研究とは無関係だけど自分の人生にプラスになると思えること」をやってみる
  3. 自分の感情を冷静に分析する。具体的には、感情的な自分と理性的な自分を用意して、感情的な自分が愚痴を吐いて、理性的な自分が相談に乗ってあげるという体でRPをする。(このフェーズが一番難しく、一番時間がかかるので、焦らずにゆっくりやる)*1
  4. やるべきことをとりあえずノートに書き出す。可能なら優先順位をつける。(できるだけ細かく分割してリストアップするのが良い)*2
  5. 感情を殺して、ゆっくりとリストの一番上から消化していく。(いかに感情を殺せるかがポイント。好きな音楽でもかけながら、ウオーーーってやると良い)一般的にこういうのは、始めるのが一番大変なので、「2分でいいから頑張ろう!」って思って始めるのがオススメ。どうしてもやる気が出ない時は、作業の準備だけして一旦休憩する、みたいなのもアリ。

参考文献

ICPC国内予選 2020 参加記

結果

全体12位、学内3位で予選通過しました。

前日まで

卒業研究にかなり精神力を費やし、競プロをする時間も気力も確保できない日々が続いていた。

当日、開始前

コミュニケーションを重視していたので、当日は僕の家に集まることになった。
部屋の掃除とかを両親が手伝ってくれました。感謝......

一方その日は13時から研究室の輪講もあったので、発表の緊張+大会の緊張で、1日中ソワソワした気持ちが続く。

そして、合流

駅前で合流し、家に向かう。
2人曰く「この辺は都会という感じがする」らしい。普段住んでいると全くそんなことは感じなかったが(事実、渋谷や新宿と比べると全く都会感はないが)、意外と他の人から見るとそういうものなんだろうか

家につき、環境のセットアップを行う。環境に慣れるために鎖中経路をACした。

開始

問題が見れない。
3人一緒だったこともあって、ほとんど焦る気持ちはなかった。自分たちのチームだけが問題見えなくても後で抗議すればどうせなんとかなるだろうと気楽に考えていた。むしろ、URLを勘違いしていないかとか、そういった「抗議してもどうにもならないミス」の方が気になった。

我々のチームは、ABCに2人、D以降に1人という特殊な配置をしていた。個人的には模擬国内も今回もこの作戦はハマったんじゃないだろうかと思っている。

Aを読み、実装を始める。序盤の問題でペナをつけることが一番やってはいけないことだと自覚していたので(参考:2019国内予選A)、かなり慎重に実装し、AC。

Bはokuraが実装していたので、Cを読む。やることは簡単だが、計算量解析が全くできない。(計算量解析の難しい問題は苦手分野だったので、今思うとこの時点で他人に投げるべきだったのかもしれない。)とりあえず愚直な実装をしてみると、案外100ケースくらいは簡単に通ったのでしばらく待ってみるが、100ケース目以降がやたらと遅いので、どうやらこの方針ではダメそうだろうと思い、考え直す。

いろいろ枝刈りをしていたが全て徒労に終わったので、最終的には、最初に約数列挙して二重ループを回すことにした。それでも遅いが、さっきよりは改善されているっぽいのでそのまま待ち続ける。そしてAC。この頃にはDが通っていた、FAらしい(すごい)。

EやFを読み、問題の考察をする。自分は終始Eを考えていた。(Fがグラフなので。)

全くわからなかったが何チームかは通しているので、どうせ「全探索すれば意外と間に合う系」なんだろうと決め打って、真ん中で分割しながらDFSをすることにする。

今考えると明らかに間に合うはずがない解法なのだが、実装していた当時の僕は、(計算量は重いかもしれないが、実行を待っていればなんとかなるだろう)と気楽に考えて実装を始めてしまう。結果としては、最後まで実装が終わらずにサンプルすら合わないままコンテストが終了し、悔しい思いをした。途中でMisterがFを通してくれたのでなんとか5完でき、Dが早かったのでなんとかペナルティ差で学内3位という成績に滑り込むことができた。

余談だが、僕は終了してからも自分たちのチームが勝ち抜けたことに気づいておらず、完全に落ち込んでいた(例年、東大は10位以内に3チーム以上入賞することが多く、事実上東大チームにとっては勝ち抜け条件が「上位10チームに入賞すること」となっていたため)。終わった数分後に勝ち抜けた事実に気付いたのだが、Misterは終わる前から気付いていたらしい。「なぜ言わなかったの?」と聞いてみたところ「だって言ったらEの実装やめちゃうかもしれないじゃん」とのことだった。草。

終了後

TLを眺めながら感想戦をしたあと、3人で近所のレストランで夕食を食べて帰ってきた。せっかく勝ち抜けたんだからもっと豪華なところに行ってもよかったかもしれないとも思った。

反省

上の参加記からも分かる通り、今回は個人としては何も活躍できなかった。Cで苦戦してしまったり、Eの嘘解法にほとんどの時間を費やしてしまったりして、戦犯と言ってもいいくらいの酷いパフォーマンスだった。チームが勝ち抜けたのにこんなに悔しい思いをするとは思わなかった。

ICPC系統の問題の練習が足りていなかったかもしれないので、3月までにはもっと強くなって帰ってきます。

GASを用いてGoogle Form上のクイズの作成を自動化する

オンラインでクイズ大会を開く場合、従来のペーパークイズの代わりにオンラインで解けるクイズ(Google Formなどを用いて)を実施したいと考えることがあります。
しかし、そこには手間が生じます。
なぜなら、問題の管理は多くの場合Excelファイルで行っていることが多く、Wordに直に貼り付けることができるオフラインのペーパークイズとは違い、フォームに1つ1つ問題をコピペしなければなりません。これは非常に面倒くさいです。

よって、この作業をGAS上で自動化しましたので、その方法について備忘録・情報共有的な意味を込めてブログに残しておきます。

使用方法

  1. 以下のコードの各種設定項目に数値を記入する
  2. 問題の並んでいるExcelGoogle ドライブ上でSpread sheetに変換する
  3. [ツール] > [スクリプトエディター] を開いて、コードを貼り付けて実行する

コード

function myFunction() {
 // ペーパーラウンドのGoogle Formをスプレッドシートから作成する
 
 // ********** 各種設定事項 **********
 
 // タイトル
 var Title = '第1R 100問4択ペーパークイズ';
 
 // 問題数
 var Questions = 100;
 
 // ページ数(問題数の約数にしてください)
 var Page = 10;
 
 // 問題が並んでいるシートの名前
 var SheetName = '提出フォーマット';
 
 // ここから、スプレッドシートの内容について
 
 // 問題文が並んでいる列を0-indexで取得(A列 -> 0, B列 -> 1, C列 -> 2, ... )
 var QuestionTextIdx = 3;
 
 // 選択肢が並んでいる列を0-indexで取得
 var ChoiceIdx1 = 5, ChoiceIdx2 = 6, ChoiceIdx3 = 7, ChoiceIdx4 = 8;
 
 // 答え(1, 2, 3, 4のいずれか)が並んでいる列を0-indexで取得
 var AnswerIdx = 9;
 
 // 1問目が記入されている行を0-indexで取得(1行 -> 0, 2行 -> 1, 3行 -> 2, ... )
 var QuestionStartIdx = 3;
 
 // ********** 各種設定事項 終わり **********
  
  var form = FormApp.create(Title);
  
  // スプレッドシートの選択
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const values = ss.getSheetByName(SheetName).getDataRange().getValues();
  
  // テスト形式に設定
  form.setIsQuiz(true);
  form.setProgressBar(true);

  // ********** ここから 問題文の設定 **********
  
  var M = Questions / Page;
  
  for(var i=0;i<Page;i++){
    // このページのタイトル
    var start = i * M + 1, end = (i + 1) * M;
    var PageTitle = 'Q' + String(start) + ' ~ Q' + String(end);
    form.addPageBreakItem().setTitle(PageTitle);
    
    for(var j=0;j<M;j++){
      // 今何問目?
      var Idx = i * 10 + j;
      
      var item = form.addMultipleChoiceItem();
      
      // 問題文
      var QuestionStatement = 'Q' + String(Idx + 1) + '.  ' + values[Idx+QuestionStartIdx][QuestionTextIdx];
      item.setTitle(QuestionStatement);
      
      // 正解
      var answer = values[Idx+QuestionStartIdx][AnswerIdx];
      // 正解選択肢の設定
      var flags = [false, false, false, false];
      flags[answer - 1] = true;
      
      item.setChoices([
        item.createChoice('[A].  ' + values[Idx+QuestionStartIdx][ChoiceIdx1], flags[0]), 
        item.createChoice('[B].  ' + values[Idx+QuestionStartIdx][ChoiceIdx2], flags[1]), 
        item.createChoice('[C].  ' + values[Idx+QuestionStartIdx][ChoiceIdx3], flags[2]), 
        item.createChoice('[D].  ' + values[Idx+QuestionStartIdx][ChoiceIdx4], flags[3])
        ]);
      item.setPoints(1);
    }
  }
  form.addPageBreakItem();
}

制作アプリ一覧

ガチ素因数分解

表示されている合成数を、制限時間内に出来るだけたくさん素因数分解していくアプリです。

f:id:Enjapma:20200329170954p:plainf:id:Enjapma:20200329171016p:plain

ガチ素因数分解

ガチ素因数分解

無料posted withアプリーチ

カラフルロボット工場

ベルトコンベアに乗って流れてくるロボットと、自機の色のRGB値のズレを出来るだけ小さくするアプリです。

f:id:Enjapma:20200408180845p:plainf:id:Enjapma:20200408180932p:plain

カラフルロボット工場

カラフルロボット工場

無料posted withアプリーチ

直進!スライム

まっすぐにしか進めないスライムをゴールへ導く、パズルゲーム です。全45ステージです。

f:id:Enjapma:20200905033438p:plainf:id:Enjapma:20200905033557p:plain


直進!スライム

直進!スライム

無料posted withアプリーチ