はじめに
2か月ぶり人生2回目のABC(Atcoder Beginner Contest)に参加したので、その備忘録を書きます。ABCの3完(52分)でした。
とりあえず茶色を目指します。
参考になる綺麗なコードではありませんが、ABC毎週参加へのモチベーションのために投稿しよう
と思った次第です。
環境
- C++20(gcc 12.2)
- Visual Studio Code
生成AIの使用について
直前でルールが変わったため、github Copilotによるコード補完のみ使用しました。
A - 123233
問題
6桁の整数について、条件を満たしているかを判定しYes/Noで出力
条件 : 各桁に1が1つ、2が2つ、3が3つ含まれているか
解答
- 入力値の各桁に0~9の数値がそれぞれいくつ含まれるかのcount配列を作る
- /10で進み、%10で抽出
int main() {
int N;
vector<int> count(11);
cin >> N;
int t;
for(int i=0;i<6;i++){
t=N%10;
count[t]+=1;
N/=10;
}
if(count[1]==1 && count[2]==2 && count[3]==3){
cout << "Yes" << endl;
}else{
cout << "No" << endl;
}
}
B - Hurdle Parsing
問題
|--|-|---|
の様な入力に対し、各|
の間に-
が何個存在するかを数え、数列で出力する。
解答
一つ目の-
から走査し、|
が見つかったらインクリメントされていた値をans配列に格納する。
int main() {
string S;
cin >> S;
vector<int> ans;
int i=1;
while(i<S.size()){
int n=0;
while(S[i]!='|'){
n++;
i++;
}
ans.push_back(n);
i++;
}
for(int i=0;i<ans.size();i++){
cout << ans[i] << " ";
}
}
C - MoveSegment
問題
0と1で構成された文字列に対して、K番目の1の塊をK-1番目の1の塊にくっつける
解答
i番目の塊は0の塊で、n個あります。というような配列を作る。
➡作った配列から、K番目の1の塊に対応するインデックスを強引に求め、swapで交換。
絶対にもっと単純にできた気がする
int main() {
int N,K;
string S;
cin >> N >> K;
cin >> S;
vector<int> ans_count;
vector<int> ans_bool;
int i=0;
while(i<N){
int n=0;
while(S[i]==S[i+1]){
n++;
i++;
}
ans_count.push_back(n+1);
if(S[i]=='0'){
ans_bool.push_back(0);
}else{
ans_bool.push_back(1);
}
i++;
}
vector<int> temp(2);
swap(ans_count[2*K-2-ans_bool[0]],ans_count[2*K-1-ans_bool[0]]);
swap(ans_bool[2*K-2-ans_bool[0]],ans_bool[2*K-1-ans_bool[0]]);
string ans;
for(int i=0;i<ans_count.size();i++){
for(int j=0;j<ans_count[i];j++){
if(ans_bool[i]==0){
ans.push_back('0');
}else{
ans.push_back('1');
}
}
}
cout << ans << endl;
}
D - Strange Mirroring
問題
与えられた文字列について、大文字小文字を反転させたものを末尾に追加するという操作を繰り返した時のK番目の文字列
解答
K番目の文字の種類を S[K % S.size() - 1]
で特定するところまではいったものの、大文字小文字の判定が出来ずに断念。
((K - 1) / S.size() + 1) % 4
の答えが1 or 4ならそのまま、2 or 3だったら反転という謎の式を導くがAC × 4、WA × 59と惨敗
まとめ
とりあえずの目標はD完を安定させることですね。競プロ鉄則が半分で止まっているので勉強しなおさなきゃなと思いました。