はじめに
オムロンプログラミングコンテスト2025(AtCoder Beginner Contest 397) - AtCoderにJavaで出ました。
ほぼ3年ぶりの参加&Javaでの参加は初めてだったため、A,Bは解けましたが、Cまで到達することができませんでした。
備忘録としてまとめておきます。
一部、ChatGPTを用いている箇所があるため、限定公開記事としています。
(きちんと使用箇所には明記しています)
A - Thermometer
私の回答
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// 整数の入力
double x = sc.nextDouble();
// 結果を出力する
if(x>=38.0){
System.out.println("1");
}else if(x<38.0 && x>=37.5){
System.out.println("2");
}else {
System.out.println("3");
}
}
}
解説
公式の解説は解説 - オムロンプログラミングコンテスト2025(AtCoder Beginner Contest 397)です。
この問題は、以下の3つのパターンをただif文を使って、以下のように出力するだけです。
- 38.0℃以上のとき:1を出力
- 37.5℃以上38.0℃未満:2を出力
- 37.5℃未満:3を出力
B - Ticket Gate Log
自分の回答(変な解き方です)
import java.util.*;
public class Main {
public static void main(String[] args) throws Exception {
Scanner sc = new Scanner(System.in);
// 文字列の入力
String inputStr= sc.nextLine();
// 文字列を入れるための配列
String x = inputStr.replaceAll("io", "*");
int count = 0;
for(int i=0;i<x.length();i++){
if(x.charAt(i)=='*'){
count++;
}
}
System.out.println(x.length()-count);
}
}
ioじゃないところだけ変更するということだと考え、以下のように解いたらACでした。
多分変な解き方です。
- ioの部分を
*に置換 - 文字列の長さから、
*の個数を引く
回答(公式C++の回答をJavaにしたもの)
ChatGPTを用いて公式C++の回答をJavaにしています。
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); String S = scanner.next(); int ans = 0; char target = 'i'; for (char c : S.toCharArray()) { if (c == target) { target = (target == 'i') ? 'o' : 'i'; } else { ans++; } } if (target == 'o') { ans++; } System.out.println(ans); scanner.close(); } }
解説
S を前から見て行って,今見ている場所までの文字列が条件を満たすような最小の操作回数を考えます.
次に現れる必要がある文字 t(最初は t=i)を管理しながら,S を前から見ていきます.
S の今見ている文字が,t に一致するならば,すでに条件を満たします.
t を反転させて(iならばoに,oならばiにする),S の次の文字を見ます.S の今見ている文字が,t と異なるならば,t を今見ている文字の前に挿入する必要があります.この操作によって,今見ている文字までの条件が満たされます.このとき,答えに 1 を足し,t を変えずにS の次の文字を見ます.
最後に,S の最後の文字が
iならば,その後ろにoを挿入する必要があるので,答えに 1 を足します.
三項演算子について
1.変数1が「ほげ1」と同じだったら変数2に「ほげ2」を入れてね
2.違ったら変数2に「ほげ3」を入れてねこれを三項演算子を使って書くと
変数2=(変数1=="ほげ1") ? "ほげ2" : "ほげ3"
つまり、target = (target == 'i') ? 'o' : 'i';は、以下となります。
-
targetがiだったらtargetにoを入れてね - 違ったら
targetにiを入れてね
charArrayについて
以下のように書くと、helloを1文字ずつ分割して、cArrayに順番に格納します。
public class Main { public static void main(String[] args) { String str1 = "hello"; char[] cArray; cArray = str1.toCharArray(); for (char c : cArray) { System.out.println(c); } System.out.println(); } }
h
e
l
l
o
ChatGPTによる更にわかりやすい解説
このプログラムの動きを、小学生でもわかるように順序立てて説明します!😊
📝 何をするプログラム?
このプログラムは、文字列の中から 「i → o → i → o → …」 という交互のパターンを作るために、いくつの文字を消せばいいかを数えるものです。
🏃♂️ プログラムの流れ
入力を受け取る
- 例えば、ユーザーが「iiioooii」と入力したとします。
変数を準備する
ans = 0(答えを入れる箱。最初は0)target = 'i'(最初に探す文字は 'i')1文字ずつチェック
- 文字列の最初から順番に見ていく。
- もし target の文字なら、次に探す文字を 'i' ⇄ 'o' に変える
- 違う文字なら、それは不要なので ans を増やす
最後に target が 'o' だったら ans を増やす
- ちゃんと「i → o → i → o …」と続いていれば OK。
- 途中で終わっていたら、最後に 'o' を足して完成させるために ans++ する。
答えを出力する
🔍 実際の動き(例)
例えば「iiioooii」を入力すると、次のように進みます。
文字 target 処理 ans i i OK → 次は o を探す 0 i o ダメ → ans++ 1 i o ダメ → ans++ 2 o o OK → 次は i を探す 2 o i ダメ → ans++ 3 o i ダメ → ans++ 4 i i OK → 次は o を探す 4 i o ダメ → ans++ 5 最後の target は 'o' なので ans++ して 答えは 6!
💡 ポイント
targetの文字が交互に変わる(i → o → i → o)。- その順番にならない文字を消すことで、正しいパターンにする。
- 最後に target が 'o' のままなら ans++ して調整。
🏆 結論
このプログラムは、「i → o → i → o …」の並びにするために、最小限の削除回数を求めるプログラム です!💡
終わりに
会社でJavaを学ぶことになり、その実践として久しぶりにAtCoderに参加したものの、解法が思いつかないことが多々ありました。
そこで、今後はもう少しABCの過去問を解いていこうと思います。
この記事が参考になれば幸いです。
ここまで読んでいただきありがとうございました。