Atcoder茶色の初心者が初心者でもわかるようにA~C問題を解説(しようと)してみた(ABC098)

 こんにちは。
 内定者研修~新人研修で学んだC言語を配属先の業務で一切使わない(どころか使う部署はほぼない)ことが判明しました。
 Javaを勉強中な胡瓜です。

 内定者時代からちょこちょこC言語で取り組んでいたAtcoderですが、C問題まではいつも解ける程度に落ち着いてきました。
 しかし、いつまでたっても、C問題を解き終えるころには時間ギリギリという状況からは抜け出せず、D問題の時間内ACはまだまだ難しそうです。


 そんななか、Atcoderの解説が分かりづらい的な話をtwitterで見まして。
 私自身も「省略し過ぎ……」と思うときもあり、本当に初心者だと全然わからないこともあるのではと(それをググって調べるのも勉強の一部だとは思いますが)。
 ということで、C問題までの自分の思考を整理するついでに解説的なことができればと思いまして、久々に更新します。

 変なところがあればどしどし指摘頂きたいです。

1.筆者の実力

 
 コンテスト参加回数:9回(Ratedのみ)
 レート  :594(2018/05/29現在)
 最高パフォ:1129(ABC097)

レート推移

f:id:activekyuri:20180529192459p:plain

〇A問題

A - Add Sub Mul

 この問題は、2つの整数AとBの足し算、引き算、掛け算を計算して比較すればよいです。
 やり方はいろいろありそうですが、私は何も考えずそのまま比較してしまっています。

#include <stdio.h>

int main()
{
    int A,B,max;
    scanf("%d%d",&A,&B);
    if( A*B >= A+B ){
        if( A*B >= A-B ){
            max = A*B; //(1)
        }else{
            max = A-B; //(2)
        }
    }else{
        if( A+B >= A-B ){
            max = A+B; //(3)
        }else{
            max = A-B; //(4)
        }
    }
  printf("%d\n",max);
}

順に説明していきます。
 まず、最初のif文でA*B と A+B を比較します。
 例えば、 A*B > A+B だったら、次の行のif文で A*B と A-B を比較します。
 そこで A*B > A-B であったら、A*B を int型の maxに入れます。その後、最後のprintf文までとんで、maxを出力します。変数に入れず、そのまま出力してもよいでしょう。

 ポイントは、あくまで最大値さえわかればよいというところでしょうか。
 上の例でいうと、A-B と A+B の大小の比較は必要がありません(3つの数の大小関係自体は6通りあります(※6=3×2×1)が、例えば上の(1)は、A*B > A-B > A+B と A*B > A+B > A-B の2通りを含んでいます。同様に、(3)も2通り含んでいますので、合計6通りで、すべての場合を考慮できていることになります)。

※大小関係が6通り
 3つの数x、y、zを並べ替えるとき、3つのうちひとつを先頭に並べるのは3通り。2番目に並べるものは残りの2つからひとつ選ぶ2通り。3番目は残ったひとつで1通り。

〇B問題

B - Cut and Count

 この問題は、最初に見たとき「B問題にしては実装量多くならん?」と考えてしまい、余計に時間を使ってしまいました。
 解説からは外れますが、B問題までは、愚直にやれば多分問題ありません。余計なことを考えずにいきましょう(と自分に言い聞かせる)。
 
 さて、長さNの文字列Sを切断し、文字列Xと文字列Yにしたとき「XとYのどちらにも含まれている文字」の種類数の最大値を求めよ、という問題です。
 なにかうまい数え方があるのかなーと思ってしまいますが、思い出しましょう、これはB問題です。愚直にやればおーけーです。つまり、前から順に切断して、その都度文字を調べるというやり方です。上記URLにある「入力例1」を例にして考えます。

入力例1

6
aabbca

まず、1番目のaと2番目のaの間で切りましょう。

a | abbca

 このとき、左の文字列にも右の文字列にも含まれている文字は 'a' のみです。したがって、この場合の「XとYのどちらにも含まれている文字」は1種類となります。
 次に、2番目のaと3番目のbの間で切り、もっと細かく考えていきましょう。

aa | bbca

 順番に行きます。
 まず、右側の文字列(Y)の1番目、すなわち 'b' と一致するものが、左側の文字列(X)の中にないかを調べます。
Xの1番目は 'a' 。一致しません。
Xの2番目は 'a' 。これも一致しません。
 Xの文字列は長さが2しかないので、この 'b' との比較は終了です。
 次は、Yの2番目の 'b' とXを比較して……というように考えていきます。

↓    ↓  // 右側の文字列Yの1番目と左側の文字列Xの1番目を比較。
aa | bbca
 ↓   ↓  // 右側の文字列Yの1番目と左側の文字列Xの2番目を比較。
aa | bbca
↓    ↓    // 右側の文字列Yの2番目と左側の文字列Xの1番目を比較。
aa | bbca

 比較が進み、文字列Yの最後、'a' と文字列Xの比較に入ったとしましょう。

↓       ↓    // 右側の文字列Yの4番目と左側の文字列Xの1番目を比較。⇒文字が一致!
aa | bbca

このとき、どちらも 'a' で一致しました。次に、最後の比較に移ります。

↓       ↓    // 右側の文字列Yの4番目と左側の文字列Xの2番目を比較。⇒文字が一致!でもカウントしない
aa | bbca

 こちらも二つの文字が一致しました。しかし、'a' はすでにひとつ前の比較でカウントしています。今回は文字の「種類数」をきかれているので、ここではカウントせず、一致した文字の種類数は1種類のままとなります。
 
 ここまでの手順をまとめましょう。

(1) 文字列を左端で分割
(2) 文字列Y(右側)の先頭文字に着目
(3) 文字列Xの1番目の文字と文字列Yの先頭文字を比較⇒文字列Xの2番目の文字と文字列Yの先頭文字を比較⇒……⇒文字列Xの最後尾の文字と文字列Yの先頭文字を比較
(4) 文字列Yの2番目の文字に着目
(5) 文字列Xの1番目の文字と文字列Yの2番目の文字を比較⇒文字列Xの2番目の文字と文字列Yの2番目の文字を比較⇒……⇒文字列Xの最後尾の文字と文字列Yの2番目の文字を比較
:
:
(6) 文字列Yの最後尾の文字に着目
(7) 文字列Xの1番目の文字と文字列Yの最後尾の文字を比較⇒文字列Xの2番目の文字と文字列Yの最後尾の文字を比較⇒……⇒文字列Xの最後尾の文字と文字列Yの最後尾の文字を比較
(8) 分割位置をひとつ右にずらす。
以下、繰り返し

となります(丁寧に書き過ぎましたかね…)。
 これらをコードで書いたものがこちら。

#include<stdio.h>

int main()
{
    char s[100];
    int N;
    scanf("%d",&N);
    scanf("%s",s);

    int alpha[1000];  //既にカウントしたアルファベットかの判定用(1000は多すぎ)
    int i,j,k,count=0,count_max=0; 

    for(i=1;i<N;i++){ // 分割位置を左端(1番目と2番目の間)から
        count=0;    //    右端(最後尾の手前)まで。      
        for(j=0;j<1000;j++){ // カウントしてないアルファベットは
        alpha[j]=0;     // alpha=0になるように初期化。 
        }
        for(j=i;j<N;j++){       // 文字列Yの先頭から最後尾。
            for(k=0;k<i;k++){   // 文字列Xの先頭から最後尾。
                if(s[j]==s[k] && alpha[s[j]]==0){ // s[j]:Yの文字 s[k]:Xの文字
                    count++;        // alpha[Yで着目中のアルファベット]=0 ⇒未カウント。
                    alpha[s[j]] = 1;      //カウント済み(alpha[]=1)に変更。
                }
            }
        }
        if(count>=count_max){
            count_max=count;
        }
    }

    printf("%d\n",count_max);

    return 0;
}

 for文での処理自体は、上に記した手順と見比べてもらえばわかると思います。
 ここでは、解説pdfで少しだけ触れていたASCIIコードを用いた部分を解説します。
 ASCIIコードというのは、簡単に言えば、’A'⇔65、'a'⇔97 というように、数字と文字・記号を対応させたものです。
 したがって、上のコードの「 if(s[j]==s[k] && alpha[s[j]]==0)」で、s[j]='a' だったとすると、
  s[j]==s[k] && alpha[s[j]]==0
⇔ 'a'==s[k] && alpha['a']==0
⇔ 97==s[k] && alpha[97]==0
となります。つまり、alpha[1000]のうち、各アルファベットに対応した数字を添え字にもつ要素が0か1かで、そのアルファベットが一致したときにカウントするかどうかを判断しているのです。
 このようにASCIIコードを使うと処理が簡単になる問題というのはたびたび見かけるので、理解しておきましょう(アルファベット毎に個数を数える など)。

〇C問題

C - Attention

 N人のひとがそれぞれ東('E')か西('W')のどちらかを向いて一列に並んでいます。誰かひとりを指名したとき、残りの人は、リーダーの方を向くように向きを変えます。その最小人数を求めよ、という問題です。
 入力例1を例に考えてみます。

↓
WEEWW

 素直に考えてみます。左端(一番西)の人をリーダーとすると、他の4人は全員西('W')を向く必要があります。したがって、向く方向を変える人は、'E'を向いている2人となります。
 次に、西から2番目の人をリーダーにします。このとき、西から1番目の人は東を向く必要があり、東から3番目の人は西を向く必要があります。したがって、向く方向を変える人は2人となります。
 というように、「西から順にリーダーに任命していき、その都度方向を変える人を数えて」いけばよいと考えられます。B問題に似てますね。
 この考えにもとづいたコードがこちら。

#include <stdio.h>

int main()
{
    int N;
    scanf("%d",&N);
    char s[N];
    scanf("%s",s);

    int i,j,count_w,count_e,count_min=4000000;
    for(i=0;i<N;i++){ //「西から順にリーダーに任命していき」
        count_w = 0;
        count_e = 0;
        for(j=0;j<i;j++){ //「方向を変える人を数えて」リーダーより西
            if( s[j] != 'E' ){ 
                count_w++;
            }
        }
        for(j=i+1;j<N;j++){ //「方向を変える人を数えて」リーダーより東
            if( s[j] != 'W' ){
                count_e++;
            }
        }
        if( count_min >= ( count_w + count_e ) ){
            count_min = count_w + count_e;
        }
    }

    printf("%d\n",count_min);

    return 0;
}

 そして提出結果は……
f:id:activekyuri:20180529222024p:plain
TLE
 つまり、時間切れです。
 経験上、C問題は素直にやるだけではTLEになることが多い気がします。
 この場合の修正方針は、N^2 ⇒ N です。簡単に言うと、「二重ループをなくそう」です。計算量の細かい話は省略しておきますが、for文をi=1~Nで回すとすると、二重ループは計算量がN^2となり、Nの増加によって計算量が爆発的に増えてしまいます。
 
 それでは、先ほどの考え方で二重ループを生じさせているところはどこでしょうか。
 まず、「西から順にリーダーに任命していき」です。リーダーを西から順に指名していくので、for(i=0;i

↓   //リーダーは'W'、右隣は'E'
WEEWW
 ↓   //リーダーは'E'(東側から'E'がひとり減少)、西側に'W'がひとり増加。
WEEWW

 
 つまり、リーダーを東にひとり分ずらしたとき、リーダーとそのすぐ東にいる人の向きしか変わりえないことになります。したがって、最初に'W'の人と'E'の人それぞれの人数を求めれば、あとは足し算引き算で計算できます。

#include <stdio.h>

int main()
{
    int N,i;
    scanf("%d",&N);
    char s[N];
    scanf("%s",s);
    int c_w=0,c_e=0;
    for(i=0;i<N;i++){
        if(s[i]=='E'){
            c_e++; //東を向いている人の合計
        }else{
            c_w++; //西を向いている人の合計
        }
    }

    int change_min=4000000;
 //change_w:リーダーの西側で向きを変える人数
    int change_w = 0; //最初は全員リーダーよりも東にいると仮定
 //change_e:リーダーの東側で向きを変える人数
    int change_e = c_e; //
    for(i=0;i<N;i++){
        if(s[i]=='E'){
            change_e--; //リーダーが'E'の場合、東側から'E'が1人減る
        }
        if(change_e+change_w <= change_min){
            change_min = change_e+change_w;
        }
        if(s[i]=='W'){
            change_w++; //リーダーが'W'の場合、西側に'W'が1人増える
        }
    }

    printf("%d\n",change_min);

    return 0;
}

(基本情報・応用情報 学習メモ)ハフマン符号化 一意に識別

 そろそろ応用情報技術者試験に向けて勉強せねば、ということでようやく始めました。

 が、基本情報の知識も曖昧で、なかなか進まず……

 とりあえず、つまづいたところが解決したら記事にしてまとめておこうと思います。かなり基本的なところでもつまづきそうで、ブログでさらすのはなぁ…とも思ったのですが、やらない理由を考えるときりがないので、書いちゃいます。

 

・ハフマン符号化

 ハフマン符号化というのは、伝達する情報を短くする情報源符号化の手法の一つです。

 例えば、4種類の文字A、B、C、Dからなる文字列DBBCAAAAを送るとします。4種類の文字それぞれを一意に表現するには、そのままでは

「00」「01」「10」「11」

のように、1文字あたり2ビットのデータ量が必要となり、上に示した8文字だと、

1101011000000000

となります。その大きさは

2 × 8 = 16 bit

となります。

 上の例では、すべての文字について同じ長さのビット列を与えましたが、これを文字列に出現する確率によって変えようというのがハフマン符号化になります。
 上の文字列における、各文字の出現確率をまとめると、次の表のようになります。

文字 出現確率
A 50%
B 25%
C 12.5%
D 12.5%

 出現確率の大きいものには短いビット列、小さいものには長いビット列を与えると、このようになります。

文字 ビット列
A 0
B 10
C 110
D 111

こうすると文字列は

11110101100000

となり、

14 bit

の大きさとなります。

・「一意に識別」

 上の表で各文字に与えたビット列は、ハフマン木を用いたものです。A~Dの文字を葉、出現確率を木の重みとして作成します。作成方法はここでは割愛。
 ここでの私の疑問は、「なんでそんなの作るの? 『0』『1』『10』『11』じゃだめなの?」でした(当たり前の話なのかもしれませんが、「0と1で伝えるんだ。へ~」くらいの認識しかない私にはすぐにはわからなかった……)。

 検索しても、基本的すぎるせいか、解決しなかったので、実際に文字列を符号化してみることにしました。
 まず、「『0』『1』『10』『11』」。この場合、文字列DBBCAAAAは

1111100000

となります。見ればすぐに気づきますが、どこが文字の切れ目か全くわかりません笑
「BBBBBAAAAA」とか「DDCAAAA」とか、いろんな文字列が考えられますね。
 一方、ハフマン木による方は

11110101100000

(もう一度対応表を)

文字 ビット列
A 0
B 10
C 110
D 111

となります。こちらも、1と0だけでよくわからんとなりそうですが、よく見ると、文字列はひとつに決まります。
 まず、先頭が「1」なので、最初の文字としてあり得るのはB、C、Dのどれか。次の文字も「1」なので、C、Dのどちらか。さらに見ていくと3番目の数字は「1」なので、先頭の文字は「C」に決まります。
 つぎの数字は「10」と続くので、その時点であり得る文字は「B」だけになります。
 こんな感じで、ちゃんと元の文字列に戻せちゃいました。

 なんでだろう?と考えたんですが、ハフマン木での符号化の方法から考えれば当然でした。
 文字を符号化する際には、各節がもつ2つの経路に0と1を割り当てて、それを葉にたどり着くまで続けます。上で「11110101100000」から「DBBCAAAA」に戻した作業は、この符号化を上から順になぞっただけなんですよね。根から葉までの経路は、葉それぞれに一本しかありません。つまり、根から葉まで一本道でたどるようにビット列を与えれば、文字が一意に決まることになります(こんなことにも気づけないなんて……)。

 
 
 以上、「ハフマン符号化」とその符号化における「一意に識別」についてのメモでした。
 「一意に識別」については、ハフマン符号化に限らず、いろんなところで必要な視点な気がしました。というか、情報系に限らない話ですよね、これ。よくこれで基本情報技術者試験に合格したなと笑
先が思いやられるなという感じですが、やれるところまではやろうかと思います……

 ではでは。

プログラミングスクールに通っていたという話

こんにちは。

 少し前に、プログラミングスクールの是非についてtwitterで話題になっていたようなので、私の経験から感じたことを書いていきます。

結論から言いますと、

「作りたいものがあるなら行ってみてもよい。『とりあえずプログラミングを学びたい』なら厳しい。通うなら、メンター・教材を徹底的に自分から使い尽くす気持ち・行動が必要」

だと思います。

 私は、とある有料プログラミングスクールに1か月ほど通っていたのですが、結局、既存サイトの模倣版みたいなのをカリキュラムに沿ってつくるだけで終わりました。得るものもありましたが、値段ほどのものを回収することは(まだ)できていません…

詳しく見ていきます。

1.いわゆる「プログラミングスキル」を鍛えるのはほんの一部

 私の場合、大学の授業で少しだけ触れたプログラミングが楽しかったのと、内定先でプログラミングスキルが必要になりそうだったので、今のうちにプログラミングスキルを高めておきたいと思って、通い始めました。何かを作りたいというのはあまりなくて、やっていくうちに見つかればいいかなという感じでした(そもそもそれが甘すぎた…)。今思うとほんとに適当ですね…

 ガリガリコードを書いていくのかなぁと思ってカリキュラムを進めていったのですが、簡単な文法について学んだあとは、少しだけ練習問題を解いて終わりでした。そのあとは、実際にWebアプリをつくるために必要なフレームワークの説明に入りました。

 明確に作りたいものがある人にとっては「いよいよか!」という感じだと思いますが、私の場合は、もっといろいろ問題を解きたいなと思っていたので、「え、もう?」と感じました(自分でやれよって話になりますが)。今思うと、下調べが足りなすぎますね。

 開発における、いわゆるコーディングというのはあくまで一部分だということだと思います。

 

2.メンターは生徒を放置。質問・相談は全部自分から。

 メンターとして、2~3人の学生アルバイトの方が教室にいましたが、基本は自分の作業をしていて、向こうから生徒に声をかけるということはなさそうでした。

 今でこそ、独学で学んでいますし、わからないことは自分から聞く・調べるというのは当たり前という感覚です。エンジニアとして食べていくなら、身につけなければならない考えです。大学の授業なんかもそうですよね。

 しかし、明確に「メンター」がいるという状況で、あそこまで完全に生徒任せというのは、完全初心者には厳しいのかなと…。全くの実務未経験からエンジニアになろうとしていて、プログラミングスクールに頼ろうという人に最初からそれを求めるのは酷じゃないかなあと感じています。そこでガンガン質問して、自分で調べて進めていける人は、おそらくプログラミングスクールに通わなくてもできちゃうひとではないかと。笑

 少なくとも初期のうちはもう少しフォローがあってもいいと思います。ただ、それも結局、スクール側がどういう人をどのレベルまで育てたいのかによると思うので、単純に良し悪しを判断するのも難しいですね。

 

3.(人によっては)世界が広がる経験ができる

 上の二つで、ネガティブなことを書いてしまったので、ここからはポジティブなことを。

 表題の通りですが、「こういう人たちがいるんだ、こういう世界があるんだ」という気づきがありました。

 twitterを始めてからもそうですが、なにも行動せずになんとなく暮らしているだけだと出会えない世界がありました。大袈裟ですかね……。

 私自身が内気なのもあって、それまでは非常に狭い世界で満足していましたが、そこは「ベンチャーインターン」や「個人でサービスをつくる」みたいなこととは無縁の世界でした。

 しかし、このスクールに通ったのをきっかけにして、独学でプログラミングを学ぶ覚悟ができましたし、いずれは個人で食べていきたいと思うようになりました。twitterをはじめ、こうしてブログなんかも書いています。そういった意味では、得るものはあったのかなと思います。プログラミングスクールがきっかけである必要はないことばかりですが笑

 

 

 というわけで、いろいろ書いてきましたが、結局は、

「自分がなにをしたいのか、なにをつくりたいのか」を明確にして、その手段としてプログラミングスクールを考える

というのが大切だということだと思います。

 なにか作りたいサービスがあるのか、それともただガリガリコードを書いてみたいだけなのか。まずはそれを明確にすること。そしてそのために必要なスキル・環境を得るのに、自分でやるよりもプログラミングスクールを頼った方が効率がよいなら通う価値はあります。

 なにをしたいのか明確にならないという人は、なんでもいいから少しだけ自分で勉強してみるのがいいかと思います。私の場合は(その勉強がプログラミングスクールそのものになってしまったわけですが笑)、自分は(今のところは)なにかを作りたいのではなく、コードを書くこと自体が好きなんだと気づくことができました。

 「1か月でエンジニアに!」「無料で就職までサポート!」なんかの甘い言葉に誘われていくようなら絶対にやめたほうがいいです……

 ではでは。

 

 

C言語の学習状況

こんにちは。

昨日で卒研発表も終了し、少し精神的にも落ち着いてきました。

そこで、昨年11月からちょっとずつ取り組んでいるC言語の学習についてまとめたいと思います。

 

1.進捗状況

・簡単な文法事項は理解

 変数の宣言からはじまり、演算子、制御文、配列とポインタ、関数、構造体あたりまでは、基本的には理解できています。ただし、ポインタとメモリの話は微妙……

 

・メモリを意識した使い方は微妙……

 上でも触れていますが、ポインタとメモリの扱い方についてはまだまだな部分が多いです。わかった!と思ってコードを書いてコンパイル、いざ実行!というところで「動作を停止しました」の一文が……という経験を何度も笑

 ポインタの宣言だけでは実体が生成されておらず、値を入れるなどの操作ができないんだろうなーとはわかるんですが、それだけではエラーが消えないことが多く…。

 とりあえず、ポインタ解説に特化した書籍を購入したので、4月の入社までになんとかせねば…

 

・ただただコードを書いているだけ

 現状、ただひたすらコードを書いているだけです。その他の情報系知識がほとんど身についてません(基本情報技術者とは)。

 検索して出てくる問題をいろいろ解いてみているという段階です。paizaやAtcoderなどの競プロ的なやつから、北ソフト工房さんのコマンドプロンプト上で動く簡単なゲームをつくる問題などなど。

 

・一応、Gitは触れた

 コードを書く以外にやったことは、Gitのアカウントをつくったくらいでしょうか。最初に少しコードをあげただけで、最近は全然触れていません……

 

2.ここまでの感想

 一言で言うと、

「認識が甘すぎた」

でしょうか。 

 独学することの難しさをひしひしと感じています。中高の自分がいかに学習環境に恵まれていたかを通過しています(大学は…)。

 特にC言語に関しては、Web系の言語などに比べるとプログラミングスクールなどは全く活発ではないようですし、自分で書籍を買って進めていくことが必要そうです。twiiterを見ていても、それほど活発には動いていないような……(これは自分の世界がまだ狭すぎるからかもしれません)

 いずれにせよ、エンジニアとして一生勉強をしていくことに対して、軽く考えていたことは深く反省しております……

 

3.これからのこと

 とりあえず、現在読み進めている書籍は

アルゴリズムの入門書

・ソフトウェアエンジニアリングの入門書(新卒研修で使われているやつ)

の2つ。この2つは4月の入社までに終わらせたいところです。

 今後新たに取り組みたいのは、

・ポインタ制覇!みたいなやつ

応用情報技術者試験の対策本

の2つでしょうか。応用情報は、内定先からの指示というのもあります。基本知識が圧倒的に足りていない私には、基本情報の方を復習しつつ進めていくことになると思いますが、これで少しでも知識をつけることができればと考えています。いきなり実践で使えるとは思っていませんが。

 ポインタは、研修中に遅くともなんとかできればと考えています。ポインタ使えないと、Cやってる意味ない気もするので……。

 

 現状はとりあえずこんなところでしょうか。独学で、周りに情報系に強い人もいないので、変な方向に突っ走っているのではないかという不安が常に付きまとっています。環境って大事だなあと笑

 卒業研究は終わりましたが、3月末に学会に出席する予定なので、それまではバリバリ学生です。思いの他両立に苦戦していますが、ここを乗り越えられれば、はたらいてからも仕事+αで学習し続けられるはずだと思って、頑張ろうと思います。

 

基本情報技術者試験 合格体験記

1月11日より、平成30年度春季の情報技術者試験申し込みが開始されました。

ということで、昨年秋に基本情報技術者試験に合格したときの話を書こうと思います。

 

試験の詳細はIPAのHP(IPA 独立行政法人 情報処理推進機構:情報処理技術者試験・情報処理安全確保支援士試験)を参照してください。

 

1.受験の背景・目的

 昨年の春、どうにかこうにか就職先が決定し、内定者懇親会に参加した時のことです。

 小さな会議室に集められた私たちは、2018年4月の入社までに行われる「内定者教育」について説明を受けていました。その中の一つに、「情報処理技術者試験の受験」があったのです。

 社員の方が手にしていたのは、分厚い2冊の参考書。

「特に予定がなければ、基本的には受験しましょうね」

 こうして、10月の試験に向けて勉強することになりました。

 

2.勉強方法・時間

2.1 参考書の読破

 自宅に参考書が届いたのは、受験の3か月ほど前でした。そこから猛勉強を開始……することはなく。当時は、大学の研究の方が楽しくて…ついついそちらに注力してしまいました。

 そんなわけで、勉強を開始したのは受験の1か月ほど前のことでした。

 使用した参考書は、こちら。

 

 

 こちらの過去問と、同シリーズの合格教本でした(正直、合格教本の方は、ところどこと誤りも見られ、参考書としてはどうかなという感じです)。

 具体的な勉強の方法は、予定では、とにかく教本をまずは1周読み、その後は過去問を解きつつ、教本を復習して合格点を目指すというもの。いたって普通です。

 しかし、思いの他読み進めるのに時間がかかりました。出てくる用語のほとんどが、今まで聞いたことのないもの。聞いたことがあるものも、詳しくは知らないものばかり。しかも、読み進めると、その前に出てきていた用語をバンバン使って解説されているので、いちいち前のページに戻って確認しなければなりません。

 結局、1周読み終えたのは試験1週間前。この時点で、ほとんど合格はあきらめていました。

 

2.2 過去問演習

 試験1週間前になってようやく過去問演習へ。すでに合格をあきらめてはいましたが、一応やっとくかと、27年度春期の過去問に取り掛かりました。

 前半は、2時間30分で、80問。ほとんごが知識を問う問題です。目指すは、合格基準の正答率60%。教本を1周読み終えたとはいえ、それだけで暗記するつもりはなく、あくまで読んだだけ。当然、ほとんどの問題で答えに確信をもてず。だめだこりゃといいいつつ、午後の問題へ。

 後半は、同じく2時間30分で、問1~13まで。このうち、問1・8は必答。問2~7は4問選択、問9~13は1問選択です。こちらは、教本を読むのとは別に対策が必要であるという認識だったので、全く解けないだろうと思っていました。ところが、蓋を開けてみれば、なんと暗記が必要な問題はほとんどなく、日本語をしっかり読めば解けるものばかり。これはもらった、と思いながら、2時間30分ぴったりくらいで解き終わりました。

 自己採点の結果は、午後は80%。これは予想通りです。そして問題の午前。なんと正答率68%。これはいったいどういうことだと、なんども解答を確認しましたが、やはり間違いではなさそう。

 復習をして、翌日、27年度秋期の過去問に取り組みましたが、やはりここでも午前70%、午後78%と、見事に合格基準をクリア。

 ということで、なんか合格できそうだぞと自信満々で、試験に臨みました。

 

3.試験結果

 試験結果はこちら。

f:id:activekyuri:20180114210721p:plain

 見事合格! 自己採点結果とのずれもありませんでした。難易度も、過去問とそれほど差は感じず、例年通りかなといった印象です。

 しかし、合格率は毎年25%前後で、私の受験した回は20%程度だったようです。

 

4.感想

 受験してみた感想としては、「合格するだけなら簡単」といったところでしょうか。

 午前の問題は、暗記物がほとんどでしたが、教本を一度読めば、あとはなんとなくで7割近い正答率を出せるようです。普段、全くPC関連に触れない人だと厳しいかもしれませんが、私はごく普通の理系の大学生で、情報系でもなく、レポートを書く時くらいしかパソコンを扱いません。その程度でも、十分合格点は狙えるでしょう。

 午後の問題は、暗記はほとんど必要ありません。問題に書かれている文章をよく読めば、十分に解くことが可能です。ただし、これは向き不向きがあると思いました。私の場合は、大学で少しだけプログラミングに触れてはいましたし、苦労することもありませんでした。プログラムの考え方に抵抗を感じる人は、それなりに演習が必要でしょう。問9~13は完全にプログラム言語の問題ですが、私は表計算を選択して、なんとなくで解いてました笑

 しかし、この試験で学んだ知識を実用レベルまでもっていくのは苦労しそうです。実際に動かしてみるのが難しいものも多く、実務経験と一緒に少しずつ身に着けていくというのが必要かなと思いました。

 

 今回はこんなところで。

 

ブログ開始(3回目)

こんにちは。きゅうりと申します。

 

春からエンジニアとして働く予定の大学生です。

 

自身の「就職活動」についてや、プログラミング学習の状況についてつづっていきます。自分に近いかな…

いずれは、より専門的なことについて書けるようになりたいですね。

 

タイトルの通り、ブログを開始するのは実は3回目。

最初は高校時代で、それは3日ほどで書くことがなくなりストップ。

2回目は半年ほど前で、高校時代に打ち込んだ陸上競技について書こうかと思いましたが、陸上競技にほとんど興味がなくなっていることに気づき、これまた終了。

これで続かなければ、おとなしく諦めますかね……