ちょっとだけ迷走した。
AtCoder Grand Contest 028のA。
概要
問題URL
A - Two Abbreviations
二つの文字列(長さ), (長さ)が与えられる。
文字列(長さ)について、
- はのどちらでも割り切れる
- の番目だけ抽出してくるとSと同じ
- の番目だけ抽出してくるとTと同じ
となる文字列が存在するならばそのうちで最短のものの長さを、存在しないならば-1を出力せよ。
制約
解説
とを両方ともいい感じに同じ長さに引き伸ばして、場所がかぶったところの文字が全部同じになったらOKという感じです。とか言っていてわかりづらいですが、0-basedで考えるとの整数倍というだけなので簡単です。
入出力例3の様子を画像にしてみました。見づらくてすみません>_<
かぶっているところが赤く塗られていますが、その部分が上の文字列としたの文字列で同じです。このように、場所のかぶったところが同じならその長さは条件を満たします。
まず、はのどちらでも割り切れるので、は一番小さくての最小公倍数で、必ずの倍数です。この時場所がかぶっている文字は、の最大公約数をとすると、
- 文字列SではS[ ], 文字列TではT[ ]
です。
さらに考えると、こうしてできた文字列で場所がかぶっている文字は、この文字列をいくら引きのばしても場所がかぶったままです。よって、でうまくいかない場合は、これを満たす文字列は存在しないということになります。
したがって、について、S[ ] == T[ ] を確かめるだけでよいことになります。
最大公約数についてはユークリッドの互除法が高速で便利です。コピペで使うライブラリを作ったので、リンクを貼っておきます。一応実装したことない人は一度やってみることをお勧めします。GitHubの扱いは不慣れですので何か間違ってたらごめんなさい。
Cpp_ComProLib/gcd at master · hewlae/Cpp_ComProLib · GitHub
最小公倍数は最大公約数ともとの2数N, Mから簡単に求められ、その値はです。
なにか間違っている点や質問などがあったらTwitterやコメントなどで教えてください。
感想
GCDやLCMにはすぐにたどり着きました(そこはいつも得意)が、いくら引きのばしても場所がかぶるやつはかぶるということに気づくまでにちょっとかかり、迷走してしまいました。13分で解けたのはラッキー