はじめに
人生3回目のABC(Atcoder Beginner Contest)に参加したので、その備忘録を書きます。なんと2完でした😢。
正直悔しいという気持ちにすらおこがまじさを感じますね。
とりあえず茶色を目指します。
環境
- C++20(gcc 12.2)
- Visual Studio Code
A - 11/22String
- ドはまりして22分使った。
- 文字の種類と状態を先頭から順に走査して、鬼の条件分岐でごり押し。
- お手本のような悪い例ですね
問題
6桁の整数について、条件を満たしているかを判定しYes/Noで出力
条件 : /
の右側に1、左側に2が同じ数だけある文字列を含んでいるか
解答
- 入力値の各桁に0~9の数値がそれぞれいくつ含まれるかのcount配列を作る
- /10で進み、%10で抽出
A
int main() {
int N;
string S;
int countone=0;
int counttwo=0;
bool flag=false;
cin >> N >> S;
for(int i=0;i<N;i++){
if(S[i]=='/'){
flag=true;
continue;
}
if(flag==false){
if(S[i]=='1'){
countone++;
}else{
cout << "No" << endl;
return 0;
}
}
if(flag==true){
if(S[i]=='2'){
counttwo++;
}else{
cout << "No" << endl;
return 0;
}
}
}
if(countone==counttwo){
cout << "Yes" << endl;
}else{
cout << "No" << endl;
}
}
B - 1122 String
問題
偶数文字の文字列について、2文字ずつ分割し、各ペアが同じ数字かつ、ペア間で数字がかぶっていないか否かを判別
解答
「各ペアが同じ文字であること」と「ペア間にダブりがないこと」を順番に見ていく。
B
int main() {
string S;
cin >> S;
vector<int> count(30);
bool ans=false;
if(S.size()%2==1){
cout << "No" << endl;
return 0;
}
for(int i=1;i<S.size();i+=2){
if(S[i-1]!=S[i]){
ans=true;
break;
}
count[S[i]-'a']++;
}
for(int i=0;i<30;i++){
if(!(count[i]==0 || count[i]==1)){
ans=true;
break;
}
}
if(ans){
cout << "No" << endl;
}else{
cout << "Yes" << endl;
}
}
C - 11/22 Substring
Aで使った最悪手、文字列を先頭から愚直に見ていき、鬼の条件分岐で何とかする手法を引き継いだことで、WA × 1
を直せず撃沈
問題
Aにでてきた11/22文字列について、最長の部分文字列の長さを求める
解答
落ち着いてから説きなおしました。
/
の前後の1と2を順にみていきます。死ぬほどきれいになりますね
C
int main() {
int N;
string S;
cin >> N >> S;
int maxnum=0;
for(int i=0;i<N;i++){
if(S[i]=='/'){
for(int j=0;j<=i;j++){
if(S[i-j-1]=='1'&&S[i+j+1]=='2'){
continue;
}else{
maxnum=max(maxnum,j*2+1);
break;
}
}
}
}
cout << maxnum << endl;
}
D - 1122 Substring
問題
入力される数列について、同じ数字のペアが連続し、かつペア間に被りがない部分数列の最大のものの長さを返す。
解答
落ち着いてから問題を見ると尺取り法が使えそうだったので実装してみるが鬼のWA
。今日は眠たいので明日やります。
まとめ
ということで、今日の惨敗ABCでした。自分の無力さを痛感しました。
半分で止まっている鉄則本をもう一度0からやり直そうかな。