久しぶりにABC #025参加しました。
公式解説があるので説明は最小限です。
就職してから、競プロご無沙汰だったので、リハビリのつもりでやっていたのですが、どうやら難易度高めだったらしく後半で詰まってしまいました。
しかも、若干寝不足気味とかでボロボロに…
久しぶりにABCやったけど、ボロボロだった… 競プロ問題解く自体が久しぶりだったせいなのか、眠気のせいなのか、問題の難易度そもそも高めだったっぽいので、もはやよくわからなくなってる
— ik-fib (@ik11235) June 27, 2015
A – 25個の文字列
問題概要
与えられた5つのアルファベットから作成できる2文字の文字列を辞書順に並べた時にn番目にくる文字列を出力する。
解法
5つのアルファベットはソート済みなので、先頭から文字を利用していき、n回目の文字列が答えです。
コード上は、ループで添字を探索していますが、より正確にはループで探索する必要もなく
文字数は固定なので、s[(n-1)/5]s[(n-1)%5]だけで出力できます。
(この辺りの発想がすぐ出なくなってるあたりが、競プロ離れてしまって弱くなった感がしました)
コード
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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; | |
} |
ループなくした方
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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; | |
} |
B – 双子とスイカ割り
問題概要
東西にdiメートル動くクエリが与えられる。全てのクエリーを行った時の立ち位置を出力せよ。
ただし、A <= di <=B でない時、A,Bの近い方に合わせる。
解法
動くのは東西2方向だけなので、一方への移動を負の値とすれば簡単になります。
diの制限も難しいことはなくdiB の時di=Bとしてクエリを処理すれば問題ありません。
コード
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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; | |
} |
C – 双子と○×ゲーム
問題概要
3×3の○×ゲームを行う。各マスの得点は、隣り合うマスと○×が同じ時直大くんに、違う時直子さんに得点が入る。
各マスの得点が与えられて、各々が点数を最大にするようにゲームをした時の、それぞれの点数を出力せよ。
解法
ここから本番中に解けませんでした。
マスの点数は必ずどちらかに入るので、直大くんの点数+直子さんの点数は必ず一定になります。
なので、再帰で直大くんのスコアを元に評価を行い、直大くんの手番は最大の値を、直子さんの時は最小の値を返り値をすれば解けるようです。
D – 25個の整数
問題概要
Cで詰まったので問題読めませんでした。
久しぶりにやってみようと思ったら、ちょうどABCがあったのでちょうどいいタイミングだと思ってやったら、ボロボロでした。難易度高めだったのもありましたが、ARC相当だったとしても前はC行ける時もあったので、C解けなかったのは結構悔しかったです。やっぱり定期的に解かないとすぐ忘れてしまうので、Atcoderの過去問かAOJあたり解こうかなと思います…