InTheDayDream

ABC278に参加してみた!

Published on 2022-11-19
Last Modified 2023-12-01

Table Of Contents

こんにちは。Inです。この度初めて競技プログラミング,もといAtCoderに参加してみたので,その記録もかねてこの記事に残しておきます。注意: 筆者はプログラミング初心者なので競プロ的には特に参考になる点はありません。

競プロって何?

競技プログラミングでは、参加者全員に同一の課題が出題され、より早く与えられた要求を満足するプログラムを正確に記述することを競う。コンピュータサイエンスや数学の知識を必要とする問題が多く、新卒学生の採用活動などに使われることもある[7][8]。多くのコンテストでオンラインジャッジが採用されている。また、競技プログラミングに参加する人を「競技プログラマ」または「競プロer」と呼ぶことがある。近年、プログラミング教育において、競争型学習が注目されている。特に、一定の時間内にプログラミング問題を解く競技系のコンテストは、授業中の演習形式として期待される。しかしこれらは高度であり入門的な授業にコンテストを取り入れるには、初心者向けに視野を広げる適応を考える必要がある。

Wikipedia, 競技プログラミング

だそうです。(適当)まぁ要するに与えられた問題をプログラムで解くんですね。私が参加したのはAtCoderというサイトで行われているものです。正直私はあまり詳しくないです。

初めて参加しての感想

今回あまり下調べせずに適当に参加してみたんですけど,はっきり言ってボロボロでした。。。でも楽しかったです。まず結果から載せます。以下が今回の提出状況でした。

提出結果

A問題で躓きすぎだろ!!!!!

はい。ということで,AとBだけ通すことができまして,得点は3200点中200点取れました。こんなにAがボロボロだったのにも少し訳がありまして,今回私は何の下調べもせずに参加してしまったせいで,標準入力を受け取る方法をずっと模索してたんですよね。前半の何回かのWAはそれにやられました。ちなみに,B問題はコンテスト終了8秒前に提出完了したので,ほんとに奇跡的に通すことができたって感じでした。

自分なりの解法(覚書)

AとBしか通せない雑魚が何をいっちょ前にと思うかもしれませんが,せっかく考えたプログラムですので,どんな感じでやったのかを残しておこうと思います。使用言語はcで,コンパイラはClang10.0.0を使用しました。

まずはA問題です。以下が問題文です。

A問題

この問題は,配列を用意して数列を入れていき,操作の回数番目のところから出力して,0で水増しするような感じで解きました。以下コードです。

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    int input = 0;
    int length = 0;
    int operation_times = 0;
    char sequence[100];

    scanf("%d %d", &length, &operation_times);

    for(int i = 0; length > i; i++){
        scanf("%d", &input);
        sequence[i] = input;
    }

    for(int i = operation_times; length > i; i++){
        printf("%d ", sequence[i]);
    }

    if (operation_times < length){
        for(int i = 0; operation_times > i; i++){
            printf("0 ");
        }
    } else {
        for(int i = 0; length > i; i++){
            printf("0 ");
        }
    }

    return 0;
}

この問題で,最初操作の回数が数列の長さを上回るパターンを見落としていて見事にWAを食らいました。あと,前にも書きましたが標準入力の取り扱いが分からないせいで1時間くらいかかりました。

次B問題です。

B問題

この問題は,きちんと考えるのが大変だったので取り合えず全探索をしようという方針で行きました。「見間違えやすい時刻」を評価するために,〇〇時△△分を十の位,一の位に分解してから初めて「時間として許容できる組み合わせ」に到達したらループを抜けるようにしました。なお,日付をまたいでも(24時以降)いいように,24で割った余りを利用しています。以下コードです。

#include <stdio.h>
#include <stdlib.h>

int main(void){
    int hour = 0;
    int min = 0;
    int hour_tens = 0;
    int hour_ones = 0;
    int min_tens = 0;
    int min_ones = 0;
    int hour_remain = 0;
    int min_remain = 0;
    int flag = 0;
    int breakflag = 0;

    scanf("%d %d", &hour, &min);

    for(int i = hour; 48 > i; i++){
        hour_remain = i % 24;
        hour_tens = hour_remain / 10;
        hour_ones = hour_remain % 10;
        if(flag == 1){
            min = 0;
        }
        for(int j = min; 60 > j; j++){
            min_tens = j / 10;
            min_ones = j % 10;
            if(24 > hour_tens * 10 + min_tens && 60 > hour_ones * 10 + min_ones){
                printf("%d %d", hour_tens * 10 + hour_ones, min_tens * 10 + min_ones);
                breakflag = 1;
                break;
            }
        }
        flag = 1;
        if(breakflag == 1){
            break;
        }
    }
    return 0;
}

絶対こんなに変数いらなかっただろ

ということでこれでAC通りました。もっと数学的に考察したら簡単に解けたかも?(面倒くさいからやらない)

終わりに

初めてのコンテスト参加でしたが,全体的に見て楽しかったです。これからもコンテストは出ていこうかなと思っています。やる気のある時にまたこうやって記事も書いてみたいなと思います。それでは読んでいただき,ありがとうございました。この記事に関して何かございましたら私のTwitterまでどうぞ。