AtCoder ABC 111 A&B&C
A問題
- '9'を'1'に、'1'を'9'に変換する
- Streamでcharを扱ってみたが、毎回Stringに変換する必要があるためすごくパフォーマンスが悪い
- charのstreamがないので使いづらいです。。。
コメントアウトしているのはfor文版
private void solveA() {
Scanner scanner = null;
String line = "";
try {
scanner = new Scanner(System.in);
line = scanner.nextLine();
String res = line.chars()
.mapToObj(c -> {
switch ((char) c) {
case '1':
return String.valueOf('9');
case '9':
return String.valueOf('1');
default:
return String.valueOf(c);
}
}).collect(Collectors.joining());
System.out.println(res);
// char[] wkArray = line.toCharArray();
// StringBuffer buf = new StringBuffer();
// for (int i = 0; i < wkArray.length; i++) {
// switch (wkArray[i]) {
// case '1':
// buf.append(9);
// break;
// case '9':
// buf.append(1);
// break;
// default:
// buf.append(wkArray[i]);
// break;
// }
//
// }
//
// System.out.println(buf.toString());
} finally {
if (scanner != null) {
scanner.close();
}
}
}
B問題
- N以上の数で、同じ数字で構成される3桁の数値を出力
- 実装ではNからスタートして、1つずつ数値をchar[]に変換して比較しているけど、3桁以内限定ならもっと楽な方法もあった
- 考えられる値は {$111,222,333,444,555,666,777,888,999$} しかないのだからそれで直接比較してもよかったな
private void solveB() {
Scanner scanner = null;
String line = "";
try {
scanner = new Scanner(System.in);
line = scanner.nextLine();
int start = Integer.parseInt(line);
for (int outer = start; outer <= 999; outer++) {
char[] wkArray = Integer.toString(outer).toCharArray();
if (wkArray[0] == wkArray[1] && wkArray[1] == wkArray[2]) {
System.out.println(outer);
return;
}
}
} finally {
if (scanner != null) {
scanner.close();
}
}
}
C問題
- 偶数番目と奇数番目を分けて考える
- 主な解説はインラインで書いた
private void solveC() {
int num = 0;
try (Scanner scanner = new Scanner(System.in)) {
num = scanner.nextInt();
int[] wk = IntStream.range(0, num).map(i -> scanner.nextInt()).toArray();
Map<Integer, Integer> wkMapEven = new HashMap<Integer, Integer>();
Map<Integer, Integer> wkMapOdd = new HashMap<Integer, Integer>();
/*
* 奇数番と偶数番でカウントを分ける
*/
for (int i = 0; i < num; i++) {
int val = wk[i];
if (i % 2 == 0) {
wkMapEven.merge(val, 1, (oldV, newV) -> oldV + newV);
} else {
wkMapOdd.merge(val, 1, (oldV, newV) -> oldV + newV);
}
}
int cnt = 0;
/*
* 偶数番を出現数順でソート
*/
long[][] resEven = new long[wkMapEven.size()][2];
for (Entry<Integer, Integer> entry : wkMapEven.entrySet()) {
resEven[cnt][0] = entry.getKey();
resEven[cnt][1] = entry.getValue();
cnt++;
}
Arrays.sort(resEven, (x, y) -> {
if (x[1] < y[1]) {
return -1;
} else if (x[1] > y[1]) {
return 1;
} else {
if (x[0] < y[0]) {
return -1;
} else if (x[0] > y[0]) {
return 1;
} else {
return 0;
}
}
});
cnt = 0;
/*
* 奇数番を出現数順でソート
*/
long[][] resOdd = new long[wkMapOdd.size()][2];
for (Entry<Integer, Integer> entry : wkMapOdd.entrySet()) {
resOdd[cnt][0] = entry.getKey();
resOdd[cnt][1] = entry.getValue();
cnt++;
}
Arrays.sort(resOdd, (x, y) -> {
if (x[1] < y[1]) {
return -1;
} else if (x[1] > y[1]) {
return 1;
} else {
if (x[0] < y[0]) {
return -1;
} else if (x[0] > y[0]) {
return 1;
} else {
return 0;
}
}
});
long sum = 0;
//偶数番の最頻出
long maxEven = resEven[resEven.length - 1][0];
//偶数番の最頻出-1
long maxEvenVal = resEven[resEven.length - 1][1];
//奇数番の最頻出
long maxOdd = resOdd[resOdd.length - 1][0];
//奇数番の最頻出-1
long maxOddVal = resOdd[resOdd.length - 1][1];
//偶数番のトータル
long even = Arrays.stream(resEven).mapToLong(i -> i[1]).sum();
//奇数番のトータル
long odd = Arrays.stream(resOdd).mapToLong(i -> i[1]).sum();
//偶数番と奇数番の最頻出が同じかどうか
if (maxEven != maxOdd) {
//最頻出値が違うので、お互いに最頻出を除いた全てを最頻出値に書き換える
sum = (even - maxEvenVal) + (odd - maxOddVal);
} else {
/*
* 最頻出値が同じなので、最頻出or最頻出-1の値に書き換えた場合の回数を比べ
* 書き換え回数の少ないほうを採用
*/
/*
* 0で初期化するのは、偶数番の値が1つしかないパターンがあるため
* 値が1つの場合は、最頻出と最頻出-1が同じ値となる(最頻出-1は実質存在しない)
*/
long maxEven2Val = 0;
if (resEven.length != 1) {
//値が複数あるので、再頻出-1
maxEven2Val = resEven[resEven.length - 2][1];
}
//偶数番と同じ処理
long maxOdd2Val = 0;
if (resOdd.length != 1) {
maxOdd2Val = resOdd[resOdd.length - 2][1];
}
/*
* 最頻出-1は、値が1つしかない場合は0となる
* 例
* 1 2 1 4 1 4
* 奇数番の最頻出は1で出現回数は3
* 最頻出-1は0
*/
//偶数番の総計-偶数番の最頻出 + 奇数番の総計-奇数番の最頻出
long val1 = (even - maxEvenVal) + (odd - maxOdd2Val);
//偶数番の総計-偶数番の最頻出-1 + 奇数番の総計-奇数番の最頻出
long val2 = (even - maxEven2Val) + (odd - maxOddVal);
sum = Math.min(val1, val2);
}
System.out.println(sum);
}
}