こんにちは。ようやく茶色帯が見えてきたRockinWoolです。次でようやく参加10回目となってRateも上がりやすくなるはずなので、ここらで本腰を入れて頑張っていきたい所存です。
さて、今回はAtcoder Beginner Contest #333付近の回答と詰まった部分をまとめてみました。直近の正答数は3, 3, 2と来ているので、次は4問クリアできるようにしたいです。
#330-A Three-Threes
NをN個並べるという超単純な問題。過去1簡単だったのでは?と感じました。2分ほどで正答できました。
#include <iostream>
using namespace std;
int main(){
int N;
cin >> N;
for(int i=0;i<N;i++){
cout << N;
}
cout << endl;
return 0;
}
#330-B Pentagon
問題自体は解けないことも無いのですが、B問題にしては難しかった気がします。入力がstring型なので、それを数字に置き換える関数を用意してあげる必要がありました。もしかしたらChar型の扱いに長けた人なら’A’で引いた値をint型で扱えば良いとか気づくのかもしれませんが、エラーが怖かったので力技で変換しました。
#include <iostream>
#include <vector>
#include <algorithm>
#include <unordered_map>
#include <string>
using namespace std;
int return_number(char);
int return_length(int, int);
int return_number(char A){
if(A=='A'){return 0;}
else if(A=='B'){return 1;}
else if(A=='C'){return 2;}
else if(A=='D'){return 3;}
else{return 4;}
};
int return_length(int A, int B){
int length;
if(A>B){
length = A-B;
}else{
length = B-A;
}
if(length>2){
length = 5-length;
}
return length;
};
int main(){
string S_12;int s_1; int s_2;
string T_12;int t_1; int t_2;
cin >> S_12;
cin >> T_12;
s_1 = return_number(S_12[0]); s_2 = return_number(S_12[1]);
t_1 = return_number(T_12[0]); t_2 = return_number(T_12[1]);
int length_s = 0;
int length_tH = 0;
length_s = return_length(s_1,s_2);
length_tH = return_length(t_1,t_2);
if(length_s==length_tH){
cout << "Yes" <<endl;
}else{
cout << "No" <<endl;
}
return 0;
}
B問題にしては行数が多いので、結構難易度が高かった印象です。ちなみに半分以下の行数で済ましている人もいて、その人の回答はこんな感じでした。
#include <bits/stdc++.h>
#define ll long long
using namespace std;
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
ll t;
//cin>>t;
t=1;
while(t--)
{
string s;
string str;
cin>>s>>str;
if(min(5-abs(s[1]-s[0]),abs(s[1]-s[0]))==min(5-abs(str[1]-str[0]),abs(str[1]-str[0])))
cout<<"Yes"<<endl;
else
cout<<"No"<<endl;
}
return 0;
}
ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);の行は単純にパフォーマンス向上のために記載している呪文と思えば良さそう。C標準の標準入出力との同期を解除してcinやcoutを使用する際に呼び出されないようにするそうだけど、ChatGPT曰く保守性の観点から競プロ以外では推奨しないとのこと。whileの必要性はよくわからないけど、ともかく文字列を読み取って2つの文字間の絶対値を取れば長さになるという算段は同じ。かなりスッキリ書けていて羨ましいですね。ちなみに、自分はここで何回かREを連発しました。原因はmain関数のreturn値を1にしていたせいです。気をつけましょう。
#330-C Repunit Trio
時間以内にとけなかったのですが、解答をみたら衝撃の短さだった問題。ともかく1の桁の数字は3になるという法則があるので、1が0~N個、2が0~M個、3が1~L個の出力になっていて、なるべく少ない個数で構成されるようにすれば良いとのこと。いや、気づかないよそんなの。
#include <bits/stdc++.h>
using namespace std;
int main() {
int n;
cin >> n;
for(int d = 1; d <= 12; d++) {
for(int a = d - 1; a >= 0; a--) {
for(int b = d - a - 1; b >= 0; b--) {
int c = d - a - b;
if(--n == 0) {
cout << string(a, '1') + string(b, '2') + string(c, '3') << endl;
return 0;
}
}
}
}
}
dは桁数を表していると予想。d=1の時はaとbのfor文は一度だけ実行、最終的にc=1となってcoutには3が1回出力される。string(c,'3')にそんな機能があったのも初めてしりました。n=2ならばd=1の3はスキップされてd=2に入り、a=1,b=0,c=1で13が出力される。n=3ならばd=2,a=0,b=1,c=1で23, n=4ならばd=2,a=0,b=0,c=2で33が出力される。う、美しい。
おわりに
とりあえず3問正答を目指して精進しようと思っていますが、最後の問題は美しすぎる解き方でしたね。こうやって脳みそを使えればもっと高みを目指せるんだろうなあ。もっと勉強しなければと思いました。それでは、また次回。