1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ABC - 111- A&B&C

Posted at

AtCoder ABC 111 A&B&C

AtCoder - 111

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);
		}
	}
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?