AtCoder Beginner Contest (ABC) #025 参加記


久しぶりにABC #025参加しました。
公式解説があるので説明は最小限です。

就職してから、競プロご無沙汰だったので、リハビリのつもりでやっていたのですが、どうやら難易度高めだったらしく後半で詰まってしまいました。
しかも、若干寝不足気味とかでボロボロに…

A – 25個の文字列

問題概要

与えられた5つのアルファベットから作成できる2文字の文字列を辞書順に並べた時にn番目にくる文字列を出力する。

解法

5つのアルファベットはソート済みなので、先頭から文字を利用していき、n回目の文字列が答えです。
コード上は、ループで添字を探索していますが、より正確にはループで探索する必要もなく
文字数は固定なので、s[(n-1)/5]s[(n-1)%5]だけで出力できます。
(この辺りの発想がすぐ出なくなってるあたりが、競プロ離れてしまって弱くなった感がしました)

コード

#include<algorithm>
#include<iostream>
using namespace std;
int main()
{
string s;
cin>>s;
int n;
cin>>n;
int a=0,b=0;
for(int i=1;i<n;i++)
{
b++;
if(b>=s.size())
{
a++;
b=0;
}
}
cout<<s[a]<<s[b]<<endl;
}

view raw
a.cpp
hosted with ❤ by GitHub

ループなくした方

#include<algorithm>
#include<iostream>
using namespace std;
int main()
{
string s;
cin>>s;
int n;
cin>>n;
n–;
cout<<s[n/5]<<s[n%5]<<endl;
}

view raw
a-2.cpp
hosted with ❤ by GitHub

B – 双子とスイカ割り

問題概要

東西にdiメートル動くクエリが与えられる。全てのクエリーを行った時の立ち位置を出力せよ。
ただし、A <= di <=B でない時、A,Bの近い方に合わせる。

解法

動くのは東西2方向だけなので、一方への移動を負の値とすれば簡単になります。
diの制限も難しいことはなくdiB の時di=Bとしてクエリを処理すれば問題ありません。

コード

#include<algorithm>
#include<iostream>
using namespace std;
int main()
{
int n,a,b;
cin>>n>>a>>b;
int now=0;
for (int i=0; i < n; i++) {
string s;
int d;
cin>>s;
cin>>d;
if(d<a)
d=a;
else if(d>b)
d=b;
if(s=="East")
{
now+=d;
}
else
{
now-=d;
}
}
if(now>0)
cout<<"East "<<now<<endl;
else if(now<0)
cout<<"West "<<-now<<endl;
else
cout<<0<<endl;
}

view raw
b.cpp
hosted with ❤ by GitHub

C – 双子と○×ゲーム

問題概要

3×3の○×ゲームを行う。各マスの得点は、隣り合うマスと○×が同じ時直大くんに、違う時直子さんに得点が入る。
各マスの得点が与えられて、各々が点数を最大にするようにゲームをした時の、それぞれの点数を出力せよ。

解法

ここから本番中に解けませんでした。

マスの点数は必ずどちらかに入るので、直大くんの点数+直子さんの点数は必ず一定になります。
なので、再帰で直大くんのスコアを元に評価を行い、直大くんの手番は最大の値を、直子さんの時は最小の値を返り値をすれば解けるようです。

D – 25個の整数

問題概要

Cで詰まったので問題読めませんでした。

久しぶりにやってみようと思ったら、ちょうどABCがあったのでちょうどいいタイミングだと思ってやったら、ボロボロでした。難易度高めだったのもありましたが、ARC相当だったとしても前はC行ける時もあったので、C解けなかったのは結構悔しかったです。やっぱり定期的に解かないとすぐ忘れてしまうので、Atcoderの過去問かAOJあたり解こうかなと思います…


コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください