結果

問題 No.518 ローマ数字の和
ユーザー 1ip1ip
提出日時 2018-02-24 01:35:15
言語 Java21
(openjdk 21)
結果
AC  
実行時間 55 ms / 2,000 ms
コード長 4,917 bytes
コンパイル時間 3,942 ms
コンパイル使用メモリ 83,408 KB
実行使用メモリ 37,152 KB
最終ジャッジ日時 2024-04-19 04:11:47
合計ジャッジ時間 5,927 ms
ジャッジサーバーID
(参考情報)
judge3 / judge4
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 52 ms
36,692 KB
testcase_01 AC 53 ms
37,036 KB
testcase_02 AC 54 ms
36,932 KB
testcase_03 AC 53 ms
37,140 KB
testcase_04 AC 53 ms
37,024 KB
testcase_05 AC 53 ms
36,832 KB
testcase_06 AC 54 ms
36,548 KB
testcase_07 AC 54 ms
36,744 KB
testcase_08 AC 51 ms
37,152 KB
testcase_09 AC 53 ms
36,696 KB
testcase_10 AC 54 ms
36,444 KB
testcase_11 AC 53 ms
36,748 KB
testcase_12 AC 53 ms
36,520 KB
testcase_13 AC 53 ms
36,828 KB
testcase_14 AC 52 ms
36,920 KB
testcase_15 AC 51 ms
36,928 KB
testcase_16 AC 55 ms
36,896 KB
testcase_17 AC 53 ms
37,064 KB
testcase_18 AC 53 ms
36,896 KB
testcase_19 AC 53 ms
36,820 KB
testcase_20 AC 54 ms
36,748 KB
testcase_21 AC 54 ms
37,152 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

package yukicoder;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.List;

public class No518 {

	public static void main(String[] args) throws IOException {
		start();
		// roman2num("CDXLIV");
	}

	private static void start() throws IOException {
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		// ローマ数字の個数を取得(使用しない)
		in.readLine();

		// N個のローマ数字文字列を取得
		String romanStr = in.readLine();
		List<String> romans = Arrays.asList(romanStr.split(" "));

		int value = 0;
		// ローマ数字を数値に変換
		for (String roman : romans) {
			int num = roman2num(roman);
			// System.out.println("debug:" + num);
			value += num;
		}
		// System.out.println("debug:value=" + value);
		// 数値をローマ数字に変換
		String output = num2roma(value);
		// 出力
		System.out.println(output);
	}

	/**
	 * ローマ数字から数値に変換します
	 *
	 * @param roman
	 * @return
	 */
	private static int roman2num(String roman) {
		int value = 0;
		// 文字列を走査していく
		for (int index = 0; index < roman.length(); index++) {
			String romanElement = String.valueOf(roman.charAt(index));
			if (index + 1 < roman.length()) {
				// 減算則か判定
				String pair = roman.substring(index, index + 2);
				switch (pair) {
				case "CM":
					value += 900;
					index++;
					break;
				case "CD":
					value += 400;
					index++;
					break;
				case "XC":
					value += 90;
					index++;
					break;
				case "XL":
					value += 40;
					index++;
					break;
				case "IX":
					value += 9;
					index++;
					break;
				case "IV":
					value += 4;
					index++;
					break;
				default:
					value += romanElem2num(romanElement);
					break;
				}
			} else {
				value += romanElem2num(romanElement);
			}
		}
		return value;
	}

	/**
	 * ローマ数字の要素から数値に変換します
	 *
	 * @param romanElement
	 * @return
	 */
	private static int romanElem2num(String romanElement) {
		switch (romanElement) {
		case "I":
			return 1;
		case "V":
			return 5;
		case "X":
			return 10;
		case "L":
			return 50;
		case "C":
			return 100;
		case "D":
			return 500;
		case "M":
			return 1000;
		default:
			throw new IllegalArgumentException("不正な文字:" + romanElement);
		}
	}

	/**
	 * 数値からローマ数字に変換します
	 *
	 * @param value
	 * @return
	 */
	private static String num2roma(int value) {
		if (value > 3999) {
			return "ERROR";
		}
		StringBuilder romanSB = new StringBuilder("MMMCMXCIX".length());
		// M(1000)を取り出す
		int numM = value / 1000;
		for (int m = 0; m < numM; m++) {
			romanSB.append("M");
			value -= 1000;
		}
		if (value == 0) {
			return romanSB.toString();
		}
		// D(500)を取り出す
		int numD = value / 500;
		// Cが4つになるか判定
		if (numD == 1) {
			// 現在値からDを引いたあまり
			int remainderD = value - (numD * 500);
			if (remainderD / 100 == 4) {
				romanSB.append("CM");
				value -= 900;
			} else {
				romanSB.append("D");
				value -= 500;
			}
		}
		if (value == 0) {
			return romanSB.toString();
		}
		// C(100)を取り出す
		int numC = value / 100;
		// Cが4つ重なる場合
		if (numC == 4) {
			romanSB.append("CD");
			value -= 400;
		} else {
			for (int c = 0; c < numC; c++) {
				romanSB.append("C");
				value -= 100;
			}
		}
		if (value == 0) {
			return romanSB.toString();
		}
		// L(50)を取り出す
		int numL = value / 50;
		// X(10)が4つ重なるか判定
		if (numL == 1) {
			// 現在値からLを引いたあまり
			int remainderL = value - (numL * 50);
			if (remainderL / 10 == 4) {
				romanSB.append("XC");
				value -= 90;
			} else {
				romanSB.append("L");
				value -= 50;
			}
		}
		if (value == 0) {
			return romanSB.toString();
		}
		// X(10)を取り出す
		int numX = value / 10;
		if (numX == 4) {
			romanSB.append("XL");
			value -= 40;
		} else {
			for (int x = 0; x < numX; x++) {
				romanSB.append("X");
				value -= 10;
			}
		}
		if (value == 0) {
			return romanSB.toString();
		}
		// V(5)を取り出す
		int numV = value / 5;
		// I(1)が4つ重なるか判定
		if (numV == 1) {
			// 現在値からLを引いたあまり
			int remainderV = value - (numV * 5);
			if (remainderV / 1 == 4) {
				romanSB.append("IX");
				value -= 9;
			} else {
				romanSB.append("V");
				value -= 5;
			}
		}

		if (value == 0) {
			return romanSB.toString();
		}
		// I(1)を取り出す
		int numI = value / 1;
		// 文字が4つ重なる場合
		if (numI == 4) {
			romanSB.append("IV");
			value -= 4;
		} else {
			for (int i = 0; i < numI; i++) {
				romanSB.append("I");
				value -= 1;
			}
		}
		if (value != 0) {
			throw new IllegalStateException("value is not zero:" + value);
		}
		return romanSB.toString();
	}

}
0